summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/build-manifest/src/main.rs3
-rw-r--r--src/tools/build_helper/src/git.rs38
-rw-r--r--src/tools/cargo/.github/renovate.json527
-rw-r--r--src/tools/cargo/.github/workflows/main.yml11
-rw-r--r--src/tools/cargo/CHANGELOG.md176
-rw-r--r--src/tools/cargo/Cargo.lock819
-rw-r--r--src/tools/cargo/Cargo.toml74
-rw-r--r--src/tools/cargo/benches/benchsuite/Cargo.toml1
-rw-r--r--src/tools/cargo/benches/benchsuite/benches/resolve.rs8
-rw-r--r--src/tools/cargo/benches/capture/Cargo.toml1
-rw-r--r--src/tools/cargo/clippy.toml8
-rw-r--r--src/tools/cargo/crates/cargo-platform/Cargo.toml2
-rw-r--r--src/tools/cargo/crates/cargo-platform/examples/matches.rs4
-rw-r--r--src/tools/cargo/crates/cargo-platform/src/error.rs4
-rw-r--r--src/tools/cargo/crates/cargo-platform/src/lib.rs3
-rw-r--r--src/tools/cargo/crates/cargo-test-macro/Cargo.toml1
-rw-r--r--src/tools/cargo/crates/cargo-test-macro/src/lib.rs2
-rw-r--r--src/tools/cargo/crates/cargo-test-support/Cargo.toml5
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/compare.rs1
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/diff.rs48
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/git.rs21
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/lib.rs77
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/publish.rs7
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/registry.rs44
-rw-r--r--src/tools/cargo/crates/cargo-util/Cargo.toml3
-rw-r--r--src/tools/cargo/crates/cargo-util/src/paths.rs31
-rw-r--r--src/tools/cargo/crates/crates-io/Cargo.toml3
-rw-r--r--src/tools/cargo/crates/crates-io/lib.rs12
-rw-r--r--src/tools/cargo/crates/mdman/Cargo.toml1
-rw-r--r--src/tools/cargo/crates/mdman/src/format/mod.rs (renamed from src/tools/cargo/crates/mdman/src/format.rs)0
-rw-r--r--src/tools/cargo/crates/mdman/src/hbs.rs12
-rw-r--r--src/tools/cargo/crates/mdman/src/lib.rs2
-rw-r--r--src/tools/cargo/crates/mdman/src/main.rs19
-rw-r--r--src/tools/cargo/crates/resolver-tests/Cargo.toml2
-rw-r--r--src/tools/cargo/crates/resolver-tests/src/lib.rs30
-rw-r--r--src/tools/cargo/crates/resolver-tests/tests/resolve.rs33
-rw-r--r--src/tools/cargo/crates/semver-check/Cargo.toml1
-rw-r--r--src/tools/cargo/crates/semver-check/src/main.rs4
-rw-r--r--src/tools/cargo/crates/xtask-build-man/Cargo.toml1
-rw-r--r--src/tools/cargo/crates/xtask-bump-check/Cargo.toml1
-rw-r--r--src/tools/cargo/crates/xtask-bump-check/src/main.rs1
-rw-r--r--src/tools/cargo/crates/xtask-bump-check/src/xtask.rs12
-rw-r--r--src/tools/cargo/crates/xtask-stale-label/Cargo.toml1
-rw-r--r--src/tools/cargo/credential/cargo-credential-1password/Cargo.toml2
-rw-r--r--src/tools/cargo/credential/cargo-credential-1password/README.md17
-rw-r--r--src/tools/cargo/credential/cargo-credential-1password/src/main.rs4
-rw-r--r--src/tools/cargo/credential/cargo-credential-libsecret/Cargo.toml2
-rw-r--r--src/tools/cargo/credential/cargo-credential-libsecret/README.md6
-rw-r--r--src/tools/cargo/credential/cargo-credential-libsecret/src/lib.rs10
-rw-r--r--src/tools/cargo/credential/cargo-credential-macos-keychain/Cargo.toml2
-rw-r--r--src/tools/cargo/credential/cargo-credential-macos-keychain/README.md7
-rw-r--r--src/tools/cargo/credential/cargo-credential-wincred/Cargo.toml2
-rw-r--r--src/tools/cargo/credential/cargo-credential-wincred/README.md6
-rw-r--r--src/tools/cargo/credential/cargo-credential-wincred/src/lib.rs4
-rw-r--r--src/tools/cargo/credential/cargo-credential/Cargo.toml3
-rw-r--r--src/tools/cargo/credential/cargo-credential/README.md4
-rw-r--r--src/tools/cargo/credential/cargo-credential/examples/file-provider.rs4
-rw-r--r--src/tools/cargo/credential/cargo-credential/examples/stdout-redirected.rs4
-rw-r--r--src/tools/cargo/credential/cargo-credential/src/error.rs4
-rw-r--r--src/tools/cargo/credential/cargo-credential/src/lib.rs204
-rw-r--r--src/tools/cargo/deny.toml4
-rwxr-xr-xsrc/tools/cargo/publish.py16
-rw-r--r--src/tools/cargo/src/bin/cargo/cli.rs87
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/add.rs12
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/bench.rs18
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/build.rs7
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/check.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/clean.rs8
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/doc.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/fetch.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/fix.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/generate_lockfile.rs4
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/init.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/install.rs134
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/locate_project.rs4
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/login.rs22
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/logout.rs19
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/metadata.rs4
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/new.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/owner.rs12
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/package.rs8
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/pkgid.rs4
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/publish.rs18
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/read_manifest.rs8
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/remove.rs14
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/report.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/run.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/rustc.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/rustdoc.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/search.rs13
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/test.rs22
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/tree.rs6
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/uninstall.rs4
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/update.rs54
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/vendor.rs54
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/verify_project.rs4
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/version.rs4
-rw-r--r--src/tools/cargo/src/bin/cargo/commands/yank.rs13
-rw-r--r--src/tools/cargo/src/bin/cargo/main.rs17
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/build_config.rs6
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/build_context/mod.rs10
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/build_context/target_info.rs26
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/build_plan.rs5
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/compilation.rs53
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/context/compilation_files.rs2
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/context/mod.rs2
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/custom_build.rs55
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/fingerprint/mod.rs64
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/future_incompat.rs32
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/job_queue/mod.rs5
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/links.rs5
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/mod.rs61
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/standard_lib.rs4
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/timings.rs18
-rw-r--r--src/tools/cargo/src/cargo/core/compiler/unit_dependencies.rs26
-rw-r--r--src/tools/cargo/src/cargo/core/dependency.rs42
-rw-r--r--src/tools/cargo/src/cargo/core/features.rs52
-rw-r--r--src/tools/cargo/src/cargo/core/manifest.rs12
-rw-r--r--src/tools/cargo/src/cargo/core/mod.rs4
-rw-r--r--src/tools/cargo/src/cargo/core/package.rs31
-rw-r--r--src/tools/cargo/src/cargo/core/package_id.rs51
-rw-r--r--src/tools/cargo/src/cargo/core/package_id_spec.rs224
-rw-r--r--src/tools/cargo/src/cargo/core/profiles.rs20
-rw-r--r--src/tools/cargo/src/cargo/core/registry.rs7
-rw-r--r--src/tools/cargo/src/cargo/core/resolver/dep_cache.rs63
-rw-r--r--src/tools/cargo/src/cargo/core/resolver/encode.rs25
-rw-r--r--src/tools/cargo/src/cargo/core/resolver/errors.rs223
-rw-r--r--src/tools/cargo/src/cargo/core/resolver/features.rs150
-rw-r--r--src/tools/cargo/src/cargo/core/resolver/mod.rs28
-rw-r--r--src/tools/cargo/src/cargo/core/resolver/types.rs2
-rw-r--r--src/tools/cargo/src/cargo/core/resolver/version_prefs.rs3
-rw-r--r--src/tools/cargo/src/cargo/core/shell.rs186
-rw-r--r--src/tools/cargo/src/cargo/core/source_id.rs (renamed from src/tools/cargo/src/cargo/core/source/source_id.rs)191
-rw-r--r--src/tools/cargo/src/cargo/core/summary.rs11
-rw-r--r--src/tools/cargo/src/cargo/core/workspace.rs48
-rw-r--r--src/tools/cargo/src/cargo/lib.rs37
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_add/mod.rs108
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_clean.rs389
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_compile/mod.rs23
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_fetch.rs5
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_generate_lockfile.rs57
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_install.rs89
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_new.rs15
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_output_metadata.rs9
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_package.rs17
-rw-r--r--src/tools/cargo/src/cargo/ops/cargo_pkgid.rs5
-rw-r--r--src/tools/cargo/src/cargo/ops/common_for_install_and_uninstall.rs4
-rw-r--r--src/tools/cargo/src/cargo/ops/fix.rs25
-rw-r--r--src/tools/cargo/src/cargo/ops/lockfile.rs4
-rw-r--r--src/tools/cargo/src/cargo/ops/mod.rs1
-rw-r--r--src/tools/cargo/src/cargo/ops/registry/login.rs15
-rw-r--r--src/tools/cargo/src/cargo/ops/registry/logout.rs5
-rw-r--r--src/tools/cargo/src/cargo/ops/registry/mod.rs39
-rw-r--r--src/tools/cargo/src/cargo/ops/registry/owner.rs8
-rw-r--r--src/tools/cargo/src/cargo/ops/registry/publish.rs35
-rw-r--r--src/tools/cargo/src/cargo/ops/registry/search.rs23
-rw-r--r--src/tools/cargo/src/cargo/ops/registry/yank.rs13
-rw-r--r--src/tools/cargo/src/cargo/ops/resolve.rs77
-rw-r--r--src/tools/cargo/src/cargo/ops/tree/graph.rs5
-rw-r--r--src/tools/cargo/src/cargo/ops/tree/mod.rs6
-rw-r--r--src/tools/cargo/src/cargo/sources/config.rs37
-rw-r--r--src/tools/cargo/src/cargo/sources/directory.rs11
-rw-r--r--src/tools/cargo/src/cargo/sources/git/mod.rs2
-rw-r--r--src/tools/cargo/src/cargo/sources/git/oxide.rs2
-rw-r--r--src/tools/cargo/src/cargo/sources/git/source.rs9
-rw-r--r--src/tools/cargo/src/cargo/sources/git/utils.rs27
-rw-r--r--src/tools/cargo/src/cargo/sources/mod.rs14
-rw-r--r--src/tools/cargo/src/cargo/sources/path.rs15
-rw-r--r--src/tools/cargo/src/cargo/sources/registry/download.rs1
-rw-r--r--src/tools/cargo/src/cargo/sources/registry/http_remote.rs51
-rw-r--r--src/tools/cargo/src/cargo/sources/registry/index.rs260
-rw-r--r--src/tools/cargo/src/cargo/sources/registry/local.rs2
-rw-r--r--src/tools/cargo/src/cargo/sources/registry/mod.rs38
-rw-r--r--src/tools/cargo/src/cargo/sources/registry/remote.rs14
-rw-r--r--src/tools/cargo/src/cargo/sources/replaced.rs6
-rw-r--r--src/tools/cargo/src/cargo/sources/source.rs (renamed from src/tools/cargo/src/cargo/core/source/mod.rs)22
-rw-r--r--src/tools/cargo/src/cargo/util/auth/mod.rs215
-rw-r--r--src/tools/cargo/src/cargo/util/command_prelude.rs135
-rw-r--r--src/tools/cargo/src/cargo/util/config/de.rs5
-rw-r--r--src/tools/cargo/src/cargo/util/config/key.rs2
-rw-r--r--src/tools/cargo/src/cargo/util/config/mod.rs154
-rw-r--r--src/tools/cargo/src/cargo/util/config/target.rs1
-rw-r--r--src/tools/cargo/src/cargo/util/config/value.rs19
-rw-r--r--src/tools/cargo/src/cargo/util/credential/paseto.rs13
-rw-r--r--src/tools/cargo/src/cargo/util/credential/process.rs67
-rw-r--r--src/tools/cargo/src/cargo/util/dependency_queue.rs5
-rw-r--r--src/tools/cargo/src/cargo/util/flock.rs11
-rw-r--r--src/tools/cargo/src/cargo/util/graph.rs148
-rw-r--r--src/tools/cargo/src/cargo/util/interning.rs34
-rw-r--r--src/tools/cargo/src/cargo/util/mod.rs14
-rw-r--r--src/tools/cargo/src/cargo/util/network/http.rs14
-rw-r--r--src/tools/cargo/src/cargo/util/network/mod.rs2
-rw-r--r--src/tools/cargo/src/cargo/util/network/retry.rs62
-rw-r--r--src/tools/cargo/src/cargo/util/network/sleep.rs1
-rw-r--r--src/tools/cargo/src/cargo/util/profile.rs5
-rw-r--r--src/tools/cargo/src/cargo/util/progress.rs10
-rw-r--r--src/tools/cargo/src/cargo/util/rustc.rs3
-rw-r--r--src/tools/cargo/src/cargo/util/semver_ext.rs213
-rw-r--r--src/tools/cargo/src/cargo/util/style.rs13
-rw-r--r--src/tools/cargo/src/cargo/util/to_semver.rs5
-rw-r--r--src/tools/cargo/src/cargo/util/toml/embedded.rs193
-rw-r--r--src/tools/cargo/src/cargo/util/toml/mod.rs531
-rw-r--r--src/tools/cargo/src/cargo/util/toml/targets.rs11
-rw-r--r--src/tools/cargo/src/doc/book.toml1
-rw-r--r--src/tools/cargo/src/doc/contrib/src/SUMMARY.md1
-rw-r--r--src/tools/cargo/src/doc/contrib/src/implementation/debugging.md6
-rw-r--r--src/tools/cargo/src/doc/contrib/src/process/security.md136
-rw-r--r--src/tools/cargo/src/doc/man/cargo-add.md6
-rw-r--r--src/tools/cargo/src/doc/man/cargo-bench.md16
-rw-r--r--src/tools/cargo/src/doc/man/cargo-build.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-check.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-clean.md10
-rw-r--r--src/tools/cargo/src/doc/man/cargo-doc.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-fetch.md7
-rw-r--r--src/tools/cargo/src/doc/man/cargo-fix.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-install.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-login.md25
-rw-r--r--src/tools/cargo/src/doc/man/cargo-logout.md12
-rw-r--r--src/tools/cargo/src/doc/man/cargo-metadata.md2
-rw-r--r--src/tools/cargo/src/doc/man/cargo-package.md7
-rw-r--r--src/tools/cargo/src/doc/man/cargo-publish.md12
-rw-r--r--src/tools/cargo/src/doc/man/cargo-remove.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-run.md3
-rw-r--r--src/tools/cargo/src/doc/man/cargo-rustc.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-rustdoc.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-test.md15
-rw-r--r--src/tools/cargo/src/doc/man/cargo-tree.md5
-rw-r--r--src/tools/cargo/src/doc/man/cargo-update.md18
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-bench.txt12
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-build.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-check.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-clean.txt5
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-doc.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-fix.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-install.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-login.txt26
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-logout.txt13
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-metadata.txt2
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-package.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-publish.txt16
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-run.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-rustc.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-rustdoc.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-test.txt8
-rw-r--r--src/tools/cargo/src/doc/man/generated_txt/cargo-update.txt28
-rw-r--r--src/tools/cargo/src/doc/man/includes/options-keep-going.md9
-rw-r--r--src/tools/cargo/src/doc/src/SUMMARY.md2
-rw-r--r--src/tools/cargo/src/doc/src/appendix/glossary.md44
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-add.md3
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-bench.md15
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-build.md10
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-check.md10
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-clean.md7
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-doc.md10
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-fetch.md3
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-fix.md10
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-install.md10
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-login.md25
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-logout.md12
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-metadata.md2
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-package.md11
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-publish.md17
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-remove.md2
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-run.md9
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-rustc.md10
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-rustdoc.md10
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-test.md11
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-tree.md2
-rw-r--r--src/tools/cargo/src/doc/src/commands/cargo-update.md19
-rw-r--r--src/tools/cargo/src/doc/src/faq.md92
-rw-r--r--src/tools/cargo/src/doc/src/getting-started/first-steps.md4
-rw-r--r--src/tools/cargo/src/doc/src/getting-started/index.md2
-rw-r--r--src/tools/cargo/src/doc/src/getting-started/installation.md6
-rw-r--r--src/tools/cargo/src/doc/src/guide/build-cache.md6
-rw-r--r--src/tools/cargo/src/doc/src/guide/cargo-home.md2
-rw-r--r--src/tools/cargo/src/doc/src/guide/cargo-toml-vs-cargo-lock.md19
-rw-r--r--src/tools/cargo/src/doc/src/guide/continuous-integration.md79
-rw-r--r--src/tools/cargo/src/doc/src/guide/creating-a-new-project.md2
-rw-r--r--src/tools/cargo/src/doc/src/guide/dependencies.md4
-rw-r--r--src/tools/cargo/src/doc/src/guide/index.md2
-rw-r--r--src/tools/cargo/src/doc/src/guide/project-layout.md2
-rw-r--r--src/tools/cargo/src/doc/src/guide/tests.md2
-rw-r--r--src/tools/cargo/src/doc/src/guide/why-cargo-exists.md6
-rw-r--r--src/tools/cargo/src/doc/src/guide/working-on-an-existing-project.md2
-rw-r--r--src/tools/cargo/src/doc/src/index.md3
-rw-r--r--src/tools/cargo/src/doc/src/reference/build-script-examples.md12
-rw-r--r--src/tools/cargo/src/doc/src/reference/build-scripts.md50
-rw-r--r--src/tools/cargo/src/doc/src/reference/cargo-targets.md42
-rw-r--r--src/tools/cargo/src/doc/src/reference/config.md272
-rw-r--r--src/tools/cargo/src/doc/src/reference/credential-provider-protocol.md237
-rw-r--r--src/tools/cargo/src/doc/src/reference/environment-variables.md20
-rw-r--r--src/tools/cargo/src/doc/src/reference/external-tools.md16
-rw-r--r--src/tools/cargo/src/doc/src/reference/features-examples.md20
-rw-r--r--src/tools/cargo/src/doc/src/reference/features.md34
-rw-r--r--src/tools/cargo/src/doc/src/reference/future-incompat-report.md2
-rw-r--r--src/tools/cargo/src/doc/src/reference/index.md2
-rw-r--r--src/tools/cargo/src/doc/src/reference/manifest.md97
-rw-r--r--src/tools/cargo/src/doc/src/reference/overriding-dependencies.md20
-rw-r--r--src/tools/cargo/src/doc/src/reference/pkgid-spec.md12
-rw-r--r--src/tools/cargo/src/doc/src/reference/profiles.md52
-rw-r--r--src/tools/cargo/src/doc/src/reference/publishing.md35
-rw-r--r--src/tools/cargo/src/doc/src/reference/registries.md14
-rw-r--r--src/tools/cargo/src/doc/src/reference/registry-authentication.md111
-rw-r--r--src/tools/cargo/src/doc/src/reference/registry-index.md45
-rw-r--r--src/tools/cargo/src/doc/src/reference/registry-web-api.md25
-rw-r--r--src/tools/cargo/src/doc/src/reference/resolver.md6
-rw-r--r--src/tools/cargo/src/doc/src/reference/running-a-registry.md2
-rw-r--r--src/tools/cargo/src/doc/src/reference/semver.md37
-rw-r--r--src/tools/cargo/src/doc/src/reference/source-replacement.md10
-rw-r--r--src/tools/cargo/src/doc/src/reference/specifying-dependencies.md81
-rw-r--r--src/tools/cargo/src/doc/src/reference/timings.md2
-rw-r--r--src/tools/cargo/src/doc/src/reference/unstable.md634
-rw-r--r--src/tools/cargo/src/doc/src/reference/workspaces.md48
-rw-r--r--src/tools/cargo/src/etc/_cargo16
-rw-r--r--src/tools/cargo/src/etc/cargo.bashcomp.sh16
-rw-r--r--src/tools/cargo/src/etc/man/cargo-bench.113
-rw-r--r--src/tools/cargo/src/etc/man/cargo-build.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-check.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-clean.16
-rw-r--r--src/tools/cargo/src/etc/man/cargo-doc.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-fix.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-install.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-login.131
-rw-r--r--src/tools/cargo/src/etc/man/cargo-logout.112
-rw-r--r--src/tools/cargo/src/etc/man/cargo-metadata.12
-rw-r--r--src/tools/cargo/src/etc/man/cargo-package.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-publish.119
-rw-r--r--src/tools/cargo/src/etc/man/cargo-run.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-rustc.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-rustdoc.19
-rw-r--r--src/tools/cargo/src/etc/man/cargo-test.112
-rw-r--r--src/tools/cargo/src/etc/man/cargo-update.119
-rw-r--r--src/tools/cargo/tests/testsuite/alt_registry.rs7
-rw-r--r--src/tools/cargo/tests/testsuite/artifact_dep.rs140
-rw-r--r--src/tools/cargo/tests/testsuite/bad_config.rs152
-rw-r--r--src/tools/cargo/tests/testsuite/bench.rs18
-rw-r--r--src/tools/cargo/tests/testsuite/build.rs37
-rw-r--r--src/tools/cargo/tests/testsuite/build_script.rs37
-rw-r--r--src/tools/cargo/tests/testsuite/cargo/help/stdout.log5
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/in/Cargo.toml5
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/in/src/lib.rs (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/README.md)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/mod.rs38
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/out/Cargo.toml8
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/stderr.log5
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/stdout.log (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/stdout.log)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/Cargo.toml5
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/src/lib.rs0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/mod.rs38
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/out/Cargo.toml8
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stderr.log34
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stdout.log0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/invalid_manifest/stderr.log3
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/mod.rs2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log5
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_alias_config.rs3
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_bench/mod.rs1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/Cargo.toml3
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/src/lib.rs0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/mod.rs19
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stderr.log7
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stdout.log0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log3
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_config/mod.rs22
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_features.rs7
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/clean-glob1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/ignore-glob1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log7
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_init/pijul_autodetect/out/.ignore1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log7
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/inherit_workspace_lints/mod.rs4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/mod.rs2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/Cargo.toml (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/Cargo.toml)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/README.md0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/src/lib.rs (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/src/lib.rs)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/mod.rs (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/mod.rs)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/Cargo.toml (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/Cargo.toml)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/foo/Cargo.toml (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/foo/Cargo.toml)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/foo/src/main.rs (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/foo/src/main.rs)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/src/lib.rs (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/src/lib.rs)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/stderr.log (renamed from src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/stderr.log)0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/stdout.log0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log8
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/mod.rs1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/Cargo.toml13
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/src/lib.rs1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/mod.rs25
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/out/Cargo.toml10
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stderr.log1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stdout.log0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_test/help/stdout.log2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_test/mod.rs1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/Cargo.toml3
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/src/lib.rs0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/mod.rs19
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stderr.log7
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stdout.log0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log12
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_update/mod.rs1
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/Cargo.toml5
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/src/main.rs3
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/mod.rs19
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stderr.log2
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stdout.log0
-rw-r--r--src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log4
-rw-r--r--src/tools/cargo/tests/testsuite/check.rs3
-rw-r--r--src/tools/cargo/tests/testsuite/clean.rs201
-rw-r--r--src/tools/cargo/tests/testsuite/config.rs24
-rw-r--r--src/tools/cargo/tests/testsuite/config_cli.rs10
-rw-r--r--src/tools/cargo/tests/testsuite/credential_process.rs262
-rw-r--r--src/tools/cargo/tests/testsuite/doc.rs4
-rw-r--r--src/tools/cargo/tests/testsuite/features2.rs3
-rw-r--r--src/tools/cargo/tests/testsuite/freshness.rs4
-rw-r--r--src/tools/cargo/tests/testsuite/future_incompat_report.rs2
-rw-r--r--src/tools/cargo/tests/testsuite/git.rs29
-rw-r--r--src/tools/cargo/tests/testsuite/inheritable_workspace_fields.rs8
-rw-r--r--src/tools/cargo/tests/testsuite/install.rs51
-rw-r--r--src/tools/cargo/tests/testsuite/install_upgrade.rs8
-rw-r--r--src/tools/cargo/tests/testsuite/lints.rs197
-rw-r--r--src/tools/cargo/tests/testsuite/list_availables.rs39
-rw-r--r--src/tools/cargo/tests/testsuite/login.rs16
-rw-r--r--src/tools/cargo/tests/testsuite/logout.rs23
-rw-r--r--src/tools/cargo/tests/testsuite/lto.rs6
-rw-r--r--src/tools/cargo/tests/testsuite/metadata.rs21
-rw-r--r--src/tools/cargo/tests/testsuite/new.rs4
-rw-r--r--src/tools/cargo/tests/testsuite/offline.rs4
-rw-r--r--src/tools/cargo/tests/testsuite/owner.rs8
-rw-r--r--src/tools/cargo/tests/testsuite/patch.rs48
-rw-r--r--src/tools/cargo/tests/testsuite/pkgid.rs131
-rw-r--r--src/tools/cargo/tests/testsuite/profile_config.rs4
-rw-r--r--src/tools/cargo/tests/testsuite/profile_custom.rs4
-rw-r--r--src/tools/cargo/tests/testsuite/profile_overrides.rs54
-rw-r--r--src/tools/cargo/tests/testsuite/profiles.rs2
-rw-r--r--src/tools/cargo/tests/testsuite/publish.rs47
-rw-r--r--src/tools/cargo/tests/testsuite/registry.rs67
-rw-r--r--src/tools/cargo/tests/testsuite/registry_auth.rs23
-rw-r--r--src/tools/cargo/tests/testsuite/replace.rs158
-rw-r--r--src/tools/cargo/tests/testsuite/run.rs37
-rw-r--r--src/tools/cargo/tests/testsuite/rust_version.rs253
-rw-r--r--src/tools/cargo/tests/testsuite/rustdocflags.rs8
-rw-r--r--src/tools/cargo/tests/testsuite/script.rs37
-rw-r--r--src/tools/cargo/tests/testsuite/search.rs9
-rw-r--r--src/tools/cargo/tests/testsuite/source_replacement.rs47
-rw-r--r--src/tools/cargo/tests/testsuite/ssh.rs3
-rw-r--r--src/tools/cargo/tests/testsuite/test.rs18
-rw-r--r--src/tools/cargo/tests/testsuite/tool_paths.rs88
-rw-r--r--src/tools/cargo/tests/testsuite/tree.rs2
-rw-r--r--src/tools/cargo/tests/testsuite/update.rs257
-rw-r--r--src/tools/cargo/tests/testsuite/workspaces.rs3
-rw-r--r--src/tools/cargo/tests/testsuite/yank.rs8
-rw-r--r--src/tools/cargo/triagebot.toml8
-rw-r--r--src/tools/cargotest/main.rs2
-rw-r--r--src/tools/clippy/.github/driver.sh2
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml33
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml8
-rw-r--r--src/tools/clippy/CHANGELOG.md117
-rw-r--r--src/tools/clippy/CONTRIBUTING.md2
-rw-r--r--src/tools/clippy/Cargo.toml5
-rw-r--r--src/tools/clippy/book/src/SUMMARY.md5
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md4
-rw-r--r--src/tools/clippy/book/src/development/defining_lints.md205
-rw-r--r--src/tools/clippy/book/src/development/emitting_lints.md217
-rw-r--r--src/tools/clippy/book/src/development/method_checking.md93
-rw-r--r--src/tools/clippy/book/src/development/speedtest.md8
-rw-r--r--src/tools/clippy/book/src/development/trait_checking.md105
-rw-r--r--src/tools/clippy/book/src/development/writing_tests.md218
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md38
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs74
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/default_union_representation.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs404
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_macros.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs190
-rw-r--r--src/tools/clippy/clippy_lints/src/endian_bytes.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_clike.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_variants.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/error_impl_error.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_nesting.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/format_impl.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs318
-rw-r--r--src/tools/clippy/clippy_lints/src/init_numbered_fields.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_futures.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_frames.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs268
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/utils.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_range_patterns.rs129
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/needless_match.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs101
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs106
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs126
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs189
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs176
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs391
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs410
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_else.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs71
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs (renamed from src/tools/clippy/clippy_lints/src/incorrect_impls.rs)63
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs63
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/float_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs46
-rw-r--r--src/tools/clippy/clippy_lints/src/raw_strings.rs96
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs134
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs209
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs93
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs111
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs110
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs10
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs89
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs45
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs35
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs72
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs17
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs13
-rw-r--r--src/tools/clippy/declare_clippy_lint/Cargo.toml2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/compile-test.rs333
-rw-r--r--src/tools/clippy/tests/headers.rs2
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/feature_name/fail/Cargo.stderr2
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_mod/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr1
-rw-r--r--src/tools/clippy/tests/ui-internal/check_formulation.stderr1
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr12
-rw-r--r--src/tools/clippy/tests/ui-internal/if_chain_style.stderr1
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr10
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed2
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr6
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_paths.stderr1
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.fixed2
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.stderr4
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr32
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed1
-rw-r--r--src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr14
-rw-r--r--src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr7
-rw-r--r--src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed6
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_macros/auxiliary/macros.rs15
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_macros/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs5
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr23
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed12
-rw-r--r--src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed12
-rw-r--r--src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr18
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr21
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs3
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_nesting/auxiliary/proc_macros.rs469
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs4
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed10
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr17
-rw-r--r--src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_futures/large_futures.fixed27
-rw-r--r--src/tools/clippy/tests/ui-toml/large_futures/large_futures.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs17
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed7
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.fixed23
-rw-r--r--src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed10
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs14
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed24
-rw-r--r--src/tools/clippy/tests/ui-toml/min_ident_chars/min_ident_chars.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed98
-rw-r--r--src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed16
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/module_inception/module_inception.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed3
-rw-r--r--src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs3
-rw-r--r--src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr17
-rw-r--r--src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs9
-rw-r--r--src/tools/clippy/tests/ui-toml/print_macro/print_macro.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed1
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/both.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr10
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed1
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr3
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed1
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr7
-rw-r--r--src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr3
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs5
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed9
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs9
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs18
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs13
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml3
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr (renamed from src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr)76
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr (renamed from src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr)134
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs46
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed95
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed44
-rw-r--r--src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/vec_box_sized/test.fixed16
-rw-r--r--src/tools/clippy/tests/ui-toml/vec_box_sized/test.stderr1
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed7
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr11
-rw-r--r--src/tools/clippy/tests/ui/absurd-extreme-comparisons.rs19
-rw-r--r--src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr35
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes.fixed10
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes.rs10
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes.stderr5
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes_without_reason.rs2
-rw-r--r--src/tools/clippy/tests/ui/almost_complete_range.fixed3
-rw-r--r--src/tools/clippy/tests/ui/almost_complete_range.rs3
-rw-r--r--src/tools/clippy/tests/ui/almost_complete_range.stderr55
-rw-r--r--src/tools/clippy/tests/ui/approx_const.rs23
-rw-r--r--src/tools/clippy/tests/ui/approx_const.stderr45
-rw-r--r--src/tools/clippy/tests/ui/arc_with_non_send_sync.rs2
-rw-r--r--src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr1
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.rs34
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.stderr15
-rw-r--r--src/tools/clippy/tests/ui/as_conversions.rs2
-rw-r--r--src/tools/clippy/tests/ui/as_conversions.stderr1
-rw-r--r--src/tools/clippy/tests/ui/as_ptr_cast_mut.rs4
-rw-r--r--src/tools/clippy/tests/ui/as_ptr_cast_mut.stderr5
-rw-r--r--src/tools/clippy/tests/ui/as_underscore.fixed2
-rw-r--r--src/tools/clippy/tests/ui/as_underscore.rs2
-rw-r--r--src/tools/clippy/tests/ui/as_underscore.stderr5
-rw-r--r--src/tools/clippy/tests/ui/asm_syntax.rs5
-rw-r--r--src/tools/clippy/tests/ui/asm_syntax.stderr10
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_constants.rs9
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_constants.stderr17
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.fixed1
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.rs1
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.stderr15
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.fixed2
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.rs2
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.stderr23
-rw-r--r--src/tools/clippy/tests/ui/assign_ops2.rs13
-rw-r--r--src/tools/clippy/tests/ui/assign_ops2.stderr22
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.fixed1
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.rs1
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.stderr13
-rw-r--r--src/tools/clippy/tests/ui/attrs.rs5
-rw-r--r--src/tools/clippy/tests/ui/attrs.stderr6
-rw-r--r--src/tools/clippy/tests/ui/await_holding_lock.rs13
-rw-r--r--src/tools/clippy/tests/ui/await_holding_lock.stderr151
-rw-r--r--src/tools/clippy/tests/ui/await_holding_refcell_ref.rs6
-rw-r--r--src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr74
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map.fixed1
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map.rs1
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map.stderr8
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed1
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs1
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr12
-rw-r--r--src/tools/clippy/tests/ui/bit_masks.rs20
-rw-r--r--src/tools/clippy/tests/ui/bit_masks.stderr32
-rw-r--r--src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs3
-rw-r--r--src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr17
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed1
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_if_conditions.rs1
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr8
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs3
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr6
-rw-r--r--src/tools/clippy/tests/ui/bool_assert_comparison.fixed2
-rw-r--r--src/tools/clippy/tests/ui/bool_assert_comparison.rs2
-rw-r--r--src/tools/clippy/tests/ui/bool_assert_comparison.stderr67
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.fixed4
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.rs4
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.stderr45
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.fixed2
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.rs2
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.stderr19
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.fixed1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.rs1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.stderr5
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr5
-rw-r--r--src/tools/clippy/tests/ui/borrow_box.rs11
-rw-r--r--src/tools/clippy/tests/ui/borrow_box.stderr20
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref.fixed3
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref.rs3
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref.stderr7
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.rs3
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr3
-rw-r--r--src/tools/clippy/tests/ui/box_collection.rs9
-rw-r--r--src/tools/clippy/tests/ui/box_collection.stderr17
-rw-r--r--src/tools/clippy/tests/ui/box_default.fixed3
-rw-r--r--src/tools/clippy/tests/ui/box_default.rs3
-rw-r--r--src/tools/clippy/tests/ui/box_default.stderr33
-rw-r--r--src/tools/clippy/tests/ui/boxed_local.rs5
-rw-r--r--src/tools/clippy/tests/ui/boxed_local.stderr7
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs14
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr32
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs9
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr21
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs7
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr23
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs5
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr22
-rw-r--r--src/tools/clippy/tests/ui/builtin_type_shadow.stderr1
-rw-r--r--src/tools/clippy/tests/ui/bytecount.rs29
-rw-r--r--src/tools/clippy/tests/ui/bytecount.stderr14
-rw-r--r--src/tools/clippy/tests/ui/bytes_count_to_len.fixed1
-rw-r--r--src/tools/clippy/tests/ui/bytes_count_to_len.rs1
-rw-r--r--src/tools/clippy/tests/ui/bytes_count_to_len.stderr9
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.fixed2
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.rs2
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.stderr7
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed1
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs1
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr13
-rw-r--r--src/tools/clippy/tests/ui/cast.rs144
-rw-r--r--src/tools/clippy/tests/ui/cast.stderr143
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr37
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.rs5
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.stderr7
-rw-r--r--src/tools/clippy/tests/ui/cast_enum_constructor.rs3
-rw-r--r--src/tools/clippy/tests/ui/cast_enum_constructor.stderr3
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_bool.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_bool.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_bool.stderr29
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_float.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_float.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_float.stderr23
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.fixed13
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.rs13
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.stderr53
-rw-r--r--src/tools/clippy/tests/ui/cast_nan_to_int.rs12
-rw-r--r--src/tools/clippy/tests/ui/cast_nan_to_int.stderr11
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed1
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs1
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr15
-rw-r--r--src/tools/clippy/tests/ui/cast_size.32bit.stderr (renamed from src/tools/clippy/tests/ui/cast_size_32bit.stderr)56
-rw-r--r--src/tools/clippy/tests/ui/cast_size.64bit.stderr (renamed from src/tools/clippy/tests/ui/cast_size.stderr)39
-rw-r--r--src/tools/clippy/tests/ui/cast_size.rs10
-rw-r--r--src/tools/clippy/tests/ui/cast_size_32bit.rs35
-rw-r--r--src/tools/clippy/tests/ui/cast_slice_different_sizes.rs16
-rw-r--r--src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr38
-rw-r--r--src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs2
-rw-r--r--src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr1
-rw-r--r--src/tools/clippy/tests/ui/cfg_features.fixed17
-rw-r--r--src/tools/clippy/tests/ui/cfg_features.rs5
-rw-r--r--src/tools/clippy/tests/ui/cfg_features.stderr7
-rw-r--r--src/tools/clippy/tests/ui/char_lit_as_u8.rs5
-rw-r--r--src/tools/clippy/tests/ui/char_lit_as_u8.stderr5
-rw-r--r--src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed2
-rw-r--r--src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs2
-rw-r--r--src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr21
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.fixed2
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.rs2
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.stderr35
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.rs80
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr86
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.rs10
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr9
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.rs143
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr153
-rw-r--r--src/tools/clippy/tests/ui/clear_with_drain.fixed1
-rw-r--r--src/tools/clippy/tests/ui/clear_with_drain.rs1
-rw-r--r--src/tools/clippy/tests/ui/clear_with_drain.stderr43
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy.fixed2
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy.rs2
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy.stderr19
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy_impl.rs2
-rw-r--r--src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cloned_instead_of_copied.rs2
-rw-r--r--src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr17
-rw-r--r--src/tools/clippy/tests/ui/cmp_null.rs3
-rw-r--r--src/tools/clippy/tests/ui/cmp_null.stderr3
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed1
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs1
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.stderr13
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs2
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/comparison_flip.stderr5
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed2
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs2
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/with_suggestion.stderr13
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs4
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/without_suggestion.stderr5
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity.rs20
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity.stderr39
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity_attr_used.rs1
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr1
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.fixed1
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.rs1
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.stderr17
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.fixed1
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.rs1
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.stderr19
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.rs12
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.stderr65
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match2.rs4
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match2.stderr25
-rw-r--r--src/tools/clippy/tests/ui/collapsible_str_replace.fixed2
-rw-r--r--src/tools/clippy/tests/ui/collapsible_str_replace.rs2
-rw-r--r--src/tools/clippy/tests/ui/collapsible_str_replace.stderr29
-rw-r--r--src/tools/clippy/tests/ui/collection_is_never_read.rs61
-rw-r--r--src/tools/clippy/tests/ui/collection_is_never_read.stderr79
-rw-r--r--src/tools/clippy/tests/ui/comparison_chain.rs7
-rw-r--r--src/tools/clippy/tests/ui/comparison_chain.stderr35
-rw-r--r--src/tools/clippy/tests/ui/comparison_to_empty.fixed2
-rw-r--r--src/tools/clippy/tests/ui/comparison_to_empty.rs2
-rw-r--r--src/tools/clippy/tests/ui/comparison_to_empty.stderr19
-rw-r--r--src/tools/clippy/tests/ui/const_comparisons.rs85
-rw-r--r--src/tools/clippy/tests/ui/const_comparisons.stderr88
-rw-r--r--src/tools/clippy/tests/ui/copy_iterator.rs2
-rw-r--r--src/tools/clippy/tests/ui/copy_iterator.stderr5
-rw-r--r--src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10148.rs4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10148.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10645.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10912.rs4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10912.stderr5
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11337.rs9
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11422.fixed25
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11422.rs25
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11422.stderr16
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2774.fixed29
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2774.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2774.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-360.rs6
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-360.stderr30
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.fixed11
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3741.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3891.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3969.rs6
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3969.stderr9
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5835.fixed11
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5835.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5835.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5872.fixed7
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5872.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5872.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6250.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6251.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6251.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6252.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6252.stderr6
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6254.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6254.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7169.fixed13
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7169.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7169.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7868.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7869.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7869.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8250.fixed8
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8250.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8250.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8821.fixed10
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8821.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8821.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8850.fixed31
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8850.rs4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8850.stderr5
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9041.rs4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9041.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9405.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9445.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9445.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9463.rs4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9463.stderr4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-96721.fixed10
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed21
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed10
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr1
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.fixed1
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.rs1
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.stderr3
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.fixed13
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.rs2
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr3
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.rs1
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr1
-rw-r--r--src/tools/clippy/tests/ui/create_dir.fixed1
-rw-r--r--src/tools/clippy/tests/ui/create_dir.rs1
-rw-r--r--src/tools/clippy/tests/ui/create_dir.stderr5
-rw-r--r--src/tools/clippy/tests/ui/dbg_macro.rs21
-rw-r--r--src/tools/clippy/tests/ui/dbg_macro.stderr37
-rw-r--r--src/tools/clippy/tests/ui/debug_assert_with_mut_call.rs29
-rw-r--r--src/tools/clippy/tests/ui/debug_assert_with_mut_call.stderr55
-rw-r--r--src/tools/clippy/tests/ui/decimal_literal_representation.fixed2
-rw-r--r--src/tools/clippy/tests/ui/decimal_literal_representation.rs2
-rw-r--r--src/tools/clippy/tests/ui/decimal_literal_representation.stderr15
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr1
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr1
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr1
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.rs1
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.stderr1
-rw-r--r--src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed2
-rw-r--r--src/tools/clippy/tests/ui/default_constructed_unit_structs.rs2
-rw-r--r--src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr13
-rw-r--r--src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed1
-rw-r--r--src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs1
-rw-r--r--src/tools/clippy/tests/ui/default_instead_of_iter_empty.stderr7
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed3
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs3
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr49
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed3
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs3
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr53
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.fixed3
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.rs3
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.stderr18
-rw-r--r--src/tools/clippy/tests/ui/default_union_representation.rs4
-rw-r--r--src/tools/clippy/tests/ui/default_union_representation.stderr11
-rw-r--r--src/tools/clippy/tests/ui/deprecated.stderr1
-rw-r--r--src/tools/clippy/tests/ui/deprecated_old.rs4
-rw-r--r--src/tools/clippy/tests/ui/deprecated_old.stderr5
-rw-r--r--src/tools/clippy/tests/ui/deref_addrof.fixed3
-rw-r--r--src/tools/clippy/tests/ui/deref_addrof.rs3
-rw-r--r--src/tools/clippy/tests/ui/deref_addrof.stderr21
-rw-r--r--src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs6
-rw-r--r--src/tools/clippy/tests/ui/deref_addrof_double_trigger.stderr5
-rw-r--r--src/tools/clippy/tests/ui/deref_addrof_macro.rs2
-rw-r--r--src/tools/clippy/tests/ui/deref_by_slicing.fixed2
-rw-r--r--src/tools/clippy/tests/ui/deref_by_slicing.rs2
-rw-r--r--src/tools/clippy/tests/ui/deref_by_slicing.stderr19
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.fixed15
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.rs15
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.stderr17
-rw-r--r--src/tools/clippy/tests/ui/derive.rs11
-rw-r--r--src/tools/clippy/tests/ui/derive.stderr27
-rw-r--r--src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.rs6
-rw-r--r--src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr17
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed2
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs2
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr23
-rw-r--r--src/tools/clippy/tests/ui/derived_hash_with_manual_eq.rs2
-rw-r--r--src/tools/clippy/tests/ui/derived_hash_with_manual_eq.stderr6
-rw-r--r--src/tools/clippy/tests/ui/disallowed_names.rs15
-rw-r--r--src/tools/clippy/tests/ui/disallowed_names.stderr27
-rw-r--r--src/tools/clippy/tests/ui/disallowed_script_idents.rs14
-rw-r--r--src/tools/clippy/tests/ui/disallowed_script_idents.stderr8
-rw-r--r--src/tools/clippy/tests/ui/diverging_sub_expression.rs12
-rw-r--r--src/tools/clippy/tests/ui/diverging_sub_expression.stderr21
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed12
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs12
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.stderr18
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs12
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr29
-rw-r--r--src/tools/clippy/tests/ui/doc_errors.rs39
-rw-r--r--src/tools/clippy/tests/ui/doc_errors.stderr13
-rw-r--r--src/tools/clippy/tests/ui/doc_link_with_quotes.rs2
-rw-r--r--src/tools/clippy/tests/ui/doc_link_with_quotes.stderr1
-rw-r--r--src/tools/clippy/tests/ui/doc_unsafe.rs2
-rw-r--r--src/tools/clippy/tests/ui/doc_unsafe.stderr1
-rw-r--r--src/tools/clippy/tests/ui/double_comparison.fixed1
-rw-r--r--src/tools/clippy/tests/ui/double_comparison.rs1
-rw-r--r--src/tools/clippy/tests/ui/double_comparison.stderr17
-rw-r--r--src/tools/clippy/tests/ui/double_must_use.rs4
-rw-r--r--src/tools/clippy/tests/ui/double_must_use.stderr7
-rw-r--r--src/tools/clippy/tests/ui/double_neg.rs2
-rw-r--r--src/tools/clippy/tests/ui/double_neg.stderr1
-rw-r--r--src/tools/clippy/tests/ui/double_parens.rs7
-rw-r--r--src/tools/clippy/tests/ui/double_parens.stderr11
-rw-r--r--src/tools/clippy/tests/ui/drain_collect.fixed2
-rw-r--r--src/tools/clippy/tests/ui/drain_collect.rs2
-rw-r--r--src/tools/clippy/tests/ui/drain_collect.stderr22
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.rs2
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.stderr5
-rw-r--r--src/tools/clippy/tests/ui/duplicate_underscore_argument.rs2
-rw-r--r--src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr1
-rw-r--r--src/tools/clippy/tests/ui/duration_subsec.fixed1
-rw-r--r--src/tools/clippy/tests/ui/duration_subsec.rs1
-rw-r--r--src/tools/clippy/tests/ui/duration_subsec.stderr11
-rw-r--r--src/tools/clippy/tests/ui/else_if_without_else.stderr1
-rw-r--r--src/tools/clippy/tests/ui/empty_drop.fixed1
-rw-r--r--src/tools/clippy/tests/ui/empty_drop.rs1
-rw-r--r--src/tools/clippy/tests/ui/empty_drop.stderr5
-rw-r--r--src/tools/clippy/tests/ui/empty_enum.rs1
-rw-r--r--src/tools/clippy/tests/ui/empty_enum.stderr1
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs5
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr1
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs5
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr1
-rw-r--r--src/tools/clippy/tests/ui/empty_loop.rs5
-rw-r--r--src/tools/clippy/tests/ui/empty_loop.stderr5
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_no_std.rs2
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_no_std.stderr3
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed1
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.rs1
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr5
-rw-r--r--src/tools/clippy/tests/ui/endian_bytes.stderr3
-rw-r--r--src/tools/clippy/tests/ui/entry.fixed1
-rw-r--r--src/tools/clippy/tests/ui/entry.rs1
-rw-r--r--src/tools/clippy/tests/ui/entry.stderr21
-rw-r--r--src/tools/clippy/tests/ui/entry_btree.fixed2
-rw-r--r--src/tools/clippy/tests/ui/entry_btree.rs2
-rw-r--r--src/tools/clippy/tests/ui/entry_btree.stderr3
-rw-r--r--src/tools/clippy/tests/ui/entry_with_else.fixed2
-rw-r--r--src/tools/clippy/tests/ui/entry_with_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/entry_with_else.stderr15
-rw-r--r--src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs12
-rw-r--r--src/tools/clippy/tests/ui/enum_clike_unportable_variant.stderr17
-rw-r--r--src/tools/clippy/tests/ui/enum_glob_use.fixed2
-rw-r--r--src/tools/clippy/tests/ui/enum_glob_use.rs2
-rw-r--r--src/tools/clippy/tests/ui/enum_glob_use.stderr7
-rw-r--r--src/tools/clippy/tests/ui/enum_variants.rs15
-rw-r--r--src/tools/clippy/tests/ui/enum_variants.stderr45
-rw-r--r--src/tools/clippy/tests/ui/eprint_with_newline.fixed69
-rw-r--r--src/tools/clippy/tests/ui/eprint_with_newline.rs24
-rw-r--r--src/tools/clippy/tests/ui/eprint_with_newline.stderr53
-rw-r--r--src/tools/clippy/tests/ui/eq_op.rs31
-rw-r--r--src/tools/clippy/tests/ui/eq_op.stderr57
-rw-r--r--src/tools/clippy/tests/ui/eq_op_macros.rs8
-rw-r--r--src/tools/clippy/tests/ui/eq_op_macros.stderr15
-rw-r--r--src/tools/clippy/tests/ui/equatable_if_let.fixed3
-rw-r--r--src/tools/clippy/tests/ui/equatable_if_let.rs3
-rw-r--r--src/tools/clippy/tests/ui/equatable_if_let.stderr29
-rw-r--r--src/tools/clippy/tests/ui/erasing_op.rs6
-rw-r--r--src/tools/clippy/tests/ui/erasing_op.stderr9
-rw-r--r--src/tools/clippy/tests/ui/err_expect.fixed2
-rw-r--r--src/tools/clippy/tests/ui/err_expect.rs2
-rw-r--r--src/tools/clippy/tests/ui/err_expect.stderr5
-rw-r--r--src/tools/clippy/tests/ui/error_impl_error.rs4
-rw-r--r--src/tools/clippy/tests/ui/error_impl_error.stderr13
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed4
-rw-r--r--src/tools/clippy/tests/ui/eta.rs4
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr2
-rw-r--r--src/tools/clippy/tests/ui/excessive_precision.fixed1
-rw-r--r--src/tools/clippy/tests/ui/excessive_precision.rs1
-rw-r--r--src/tools/clippy/tests/ui/excessive_precision.stderr31
-rw-r--r--src/tools/clippy/tests/ui/exhaustive_items.fixed2
-rw-r--r--src/tools/clippy/tests/ui/exhaustive_items.rs2
-rw-r--r--src/tools/clippy/tests/ui/exhaustive_items.stderr10
-rw-r--r--src/tools/clippy/tests/ui/exit1.rs2
-rw-r--r--src/tools/clippy/tests/ui/exit1.stderr1
-rw-r--r--src/tools/clippy/tests/ui/exit2.rs2
-rw-r--r--src/tools/clippy/tests/ui/exit2.stderr1
-rw-r--r--src/tools/clippy/tests/ui/expect.rs3
-rw-r--r--src/tools/clippy/tests/ui/expect.stderr5
-rw-r--r--src/tools/clippy/tests/ui/expect_fun_call.fixed1
-rw-r--r--src/tools/clippy/tests/ui/expect_fun_call.rs1
-rw-r--r--src/tools/clippy/tests/ui/expect_fun_call.stderr31
-rw-r--r--src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs7
-rw-r--r--src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr11
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.fixed32
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.rs30
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.stderr89
-rw-r--r--src/tools/clippy/tests/ui/explicit_counter_loop.rs13
-rw-r--r--src/tools/clippy/tests/ui/explicit_counter_loop.stderr17
-rw-r--r--src/tools/clippy/tests/ui/explicit_deref_methods.fixed1
-rw-r--r--src/tools/clippy/tests/ui/explicit_deref_methods.rs1
-rw-r--r--src/tools/clippy/tests/ui/explicit_deref_methods.stderr25
-rw-r--r--src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed1
-rw-r--r--src/tools/clippy/tests/ui/explicit_into_iter_loop.rs1
-rw-r--r--src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr13
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.fixed8
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.rs2
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.stderr30
-rw-r--r--src/tools/clippy/tests/ui/explicit_write.fixed1
-rw-r--r--src/tools/clippy/tests/ui/explicit_write.rs1
-rw-r--r--src/tools/clippy/tests/ui/explicit_write.stderr35
-rw-r--r--src/tools/clippy/tests/ui/extend_with_drain.fixed1
-rw-r--r--src/tools/clippy/tests/ui/extend_with_drain.rs1
-rw-r--r--src/tools/clippy/tests/ui/extend_with_drain.stderr9
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr1
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed18
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters.rs18
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr17
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs3
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/fallible_impl_from.rs4
-rw-r--r--src/tools/clippy/tests/ui/fallible_impl_from.stderr21
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.rs4
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.stderr1
-rw-r--r--src/tools/clippy/tests/ui/filetype_is_file.rs3
-rw-r--r--src/tools/clippy/tests/ui/filetype_is_file.stderr5
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.fixed27
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.rs27
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.stderr39
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.fixed2
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.rs2
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.stderr9
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next.rs2
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next.stderr5
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next_fixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/flat_map_identity.fixed2
-rw-r--r--src/tools/clippy/tests/ui/flat_map_identity.rs2
-rw-r--r--src/tools/clippy/tests/ui/flat_map_identity.stderr7
-rw-r--r--src/tools/clippy/tests/ui/flat_map_option.fixed1
-rw-r--r--src/tools/clippy/tests/ui/flat_map_option.rs1
-rw-r--r--src/tools/clippy/tests/ui/flat_map_option.stderr5
-rw-r--r--src/tools/clippy/tests/ui/float_arithmetic.rs18
-rw-r--r--src/tools/clippy/tests/ui/float_arithmetic.stderr33
-rw-r--r--src/tools/clippy/tests/ui/float_cmp.rs27
-rw-r--r--src/tools/clippy/tests/ui/float_cmp.stderr13
-rw-r--r--src/tools/clippy/tests/ui/float_cmp_const.rs18
-rw-r--r--src/tools/clippy/tests/ui/float_cmp_const.stderr15
-rw-r--r--src/tools/clippy/tests/ui/float_equality_without_abs.rs14
-rw-r--r--src/tools/clippy/tests/ui/float_equality_without_abs.stderr21
-rw-r--r--src/tools/clippy/tests/ui/floating_point_abs.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_abs.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_abs.stderr17
-rw-r--r--src/tools/clippy/tests/ui/floating_point_exp.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_exp.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_exp.stderr11
-rw-r--r--src/tools/clippy/tests/ui/floating_point_hypot.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_hypot.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_hypot.stderr7
-rw-r--r--src/tools/clippy/tests/ui/floating_point_log.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_log.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_log.stderr60
-rw-r--r--src/tools/clippy/tests/ui/floating_point_logbase.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_logbase.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_logbase.stderr11
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.stderr25
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powf.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powf.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powf.stderr64
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powi.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powi.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_powi.stderr29
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.fixed1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.rs1
-rw-r--r--src/tools/clippy/tests/ui/floating_point_rad.stderr17
-rw-r--r--src/tools/clippy/tests/ui/fn_address_comparisons.rs3
-rw-r--r--src/tools/clippy/tests/ui/fn_address_comparisons.stderr3
-rw-r--r--src/tools/clippy/tests/ui/fn_params_excessive_bools.rs7
-rw-r--r--src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr15
-rw-r--r--src/tools/clippy/tests/ui/fn_to_numeric_cast.32bit.stderr (renamed from src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.stderr)62
-rw-r--r--src/tools/clippy/tests/ui/fn_to_numeric_cast.64bit.stderr (renamed from src/tools/clippy/tests/ui/fn_to_numeric_cast.stderr)2
-rw-r--r--src/tools/clippy/tests/ui/fn_to_numeric_cast.rs4
-rw-r--r--src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs55
-rw-r--r--src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs20
-rw-r--r--src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr33
-rw-r--r--src/tools/clippy/tests/ui/for_kv_map.fixed56
-rw-r--r--src/tools/clippy/tests/ui/for_kv_map.rs6
-rw-r--r--src/tools/clippy/tests/ui/for_kv_map.stderr9
-rw-r--r--src/tools/clippy/tests/ui/forget_non_drop.rs2
-rw-r--r--src/tools/clippy/tests/ui/forget_non_drop.stderr5
-rw-r--r--src/tools/clippy/tests/ui/format.fixed1
-rw-r--r--src/tools/clippy/tests/ui/format.rs1
-rw-r--r--src/tools/clippy/tests/ui/format.stderr35
-rw-r--r--src/tools/clippy/tests/ui/format_args.fixed1
-rw-r--r--src/tools/clippy/tests/ui/format_args.rs1
-rw-r--r--src/tools/clippy/tests/ui/format_args.stderr51
-rw-r--r--src/tools/clippy/tests/ui/format_args_unfixable.rs18
-rw-r--r--src/tools/clippy/tests/ui/format_args_unfixable.stderr37
-rw-r--r--src/tools/clippy/tests/ui/format_collect.rs3
-rw-r--r--src/tools/clippy/tests/ui/format_collect.stderr14
-rw-r--r--src/tools/clippy/tests/ui/format_push_string.rs5
-rw-r--r--src/tools/clippy/tests/ui/format_push_string.stderr12
-rw-r--r--src/tools/clippy/tests/ui/formatting.rs12
-rw-r--r--src/tools/clippy/tests/ui/formatting.stderr12
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes.fixed4
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes.rs4
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes.stderr1
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes_first_line.fixed1
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes_first_line.rs1
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr1
-rw-r--r--src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed2
-rw-r--r--src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs2
-rw-r--r--src/tools/clippy/tests/ui/from_iter_instead_of_collect.stderr31
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.fixed2
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.rs2
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr13
-rw-r--r--src/tools/clippy/tests/ui/from_over_into_unfixable.rs4
-rw-r--r--src/tools/clippy/tests/ui/from_over_into_unfixable.stderr7
-rw-r--r--src/tools/clippy/tests/ui/from_raw_with_void_ptr.rs5
-rw-r--r--src/tools/clippy/tests/ui/from_raw_with_void_ptr.stderr17
-rw-r--r--src/tools/clippy/tests/ui/from_str_radix_10.fixed61
-rw-r--r--src/tools/clippy/tests/ui/from_str_radix_10.rs9
-rw-r--r--src/tools/clippy/tests/ui/from_str_radix_10.stderr15
-rw-r--r--src/tools/clippy/tests/ui/functions.rs18
-rw-r--r--src/tools/clippy/tests/ui/functions.stderr34
-rw-r--r--src/tools/clippy/tests/ui/functions_maxlines.rs2
-rw-r--r--src/tools/clippy/tests/ui/functions_maxlines.stderr5
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.rs9
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.stderr64
-rw-r--r--src/tools/clippy/tests/ui/get_first.fixed1
-rw-r--r--src/tools/clippy/tests/ui/get_first.rs1
-rw-r--r--src/tools/clippy/tests/ui/get_first.stderr7
-rw-r--r--src/tools/clippy/tests/ui/get_last_with_len.fixed2
-rw-r--r--src/tools/clippy/tests/ui/get_last_with_len.rs2
-rw-r--r--src/tools/clippy/tests/ui/get_last_with_len.stderr13
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.fixed2
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.rs2
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.stderr63
-rw-r--r--src/tools/clippy/tests/ui/identity_op.fixed1
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs1
-rw-r--r--src/tools/clippy/tests/ui/identity_op.stderr81
-rw-r--r--src/tools/clippy/tests/ui/if_let_mutex.rs3
-rw-r--r--src/tools/clippy/tests/ui/if_let_mutex.stderr8
-rw-r--r--src/tools/clippy/tests/ui/if_not_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_not_else.stderr5
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else.stderr1
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.stderr22
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.rs17
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.stderr12
-rw-r--r--src/tools/clippy/tests/ui/ifs_same_cond.stderr1
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.fixed18
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.rs18
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.stderr17
-rw-r--r--src/tools/clippy/tests/ui/impl.rs4
-rw-r--r--src/tools/clippy/tests/ui/impl.stderr14
-rw-r--r--src/tools/clippy/tests/ui/impl_trait_in_params.rs5
-rw-r--r--src/tools/clippy/tests/ui/impl_trait_in_params.stderr3
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.fixed3
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.rs1
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.stderr31
-rw-r--r--src/tools/clippy/tests/ui/implicit_hasher.rs4
-rw-r--r--src/tools/clippy/tests/ui/implicit_hasher.stderr163
-rw-r--r--src/tools/clippy/tests/ui/implicit_return.fixed1
-rw-r--r--src/tools/clippy/tests/ui/implicit_return.rs1
-rw-r--r--src/tools/clippy/tests/ui/implicit_return.stderr33
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_add.fixed2
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_add.rs2
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_add.stderr49
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.fixed1
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.rs1
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.stderr47
-rw-r--r--src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed125
-rw-r--r--src/tools/clippy/tests/ui/implied_bounds_in_impls.rs125
-rw-r--r--src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr196
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed1
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs1
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_digit_grouping.stderr23
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed3
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs3
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr5
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.fixed177
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs10
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.stderr18
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed29
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs1
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.rs52
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr35
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_slice.rs23
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_slice.stderr44
-rw-r--r--src/tools/clippy/tests/ui/inefficient_to_string.fixed1
-rw-r--r--src/tools/clippy/tests/ui/inefficient_to_string.rs1
-rw-r--r--src/tools/clippy/tests/ui/inefficient_to_string.stderr14
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.fixed1
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.rs1
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.stderr9
-rw-r--r--src/tools/clippy/tests/ui/infinite_iter.rs74
-rw-r--r--src/tools/clippy/tests/ui/infinite_iter.stderr58
-rw-r--r--src/tools/clippy/tests/ui/infinite_loop.rs24
-rw-r--r--src/tools/clippy/tests/ui/infinite_loop.stderr22
-rw-r--r--src/tools/clippy/tests/ui/inherent_to_string.rs2
-rw-r--r--src/tools/clippy/tests/ui/inherent_to_string.stderr5
-rw-r--r--src/tools/clippy/tests/ui/inline_fn_without_body.fixed2
-rw-r--r--src/tools/clippy/tests/ui/inline_fn_without_body.rs2
-rw-r--r--src/tools/clippy/tests/ui/inline_fn_without_body.stderr7
-rw-r--r--src/tools/clippy/tests/ui/inspect_for_each.rs1
-rw-r--r--src/tools/clippy/tests/ui/inspect_for_each.stderr2
-rw-r--r--src/tools/clippy/tests/ui/int_plus_one.fixed2
-rw-r--r--src/tools/clippy/tests/ui/int_plus_one.rs2
-rw-r--r--src/tools/clippy/tests/ui/int_plus_one.stderr9
-rw-r--r--src/tools/clippy/tests/ui/integer_division.rs3
-rw-r--r--src/tools/clippy/tests/ui/integer_division.stderr5
-rw-r--r--src/tools/clippy/tests/ui/into_iter_on_ref.fixed1
-rw-r--r--src/tools/clippy/tests/ui/into_iter_on_ref.rs1
-rw-r--r--src/tools/clippy/tests/ui/into_iter_on_ref.stderr55
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed2
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs2
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr50
-rw-r--r--src/tools/clippy/tests/ui/invalid_upcast_comparisons.rs28
-rw-r--r--src/tools/clippy/tests/ui/invalid_upcast_comparisons.stderr53
-rw-r--r--src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed2
-rw-r--r--src/tools/clippy/tests/ui/is_digit_ascii_radix.rs2
-rw-r--r--src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr7
-rw-r--r--src/tools/clippy/tests/ui/issue-7447.rs3
-rw-r--r--src/tools/clippy/tests/ui/issue-7447.stderr3
-rw-r--r--src/tools/clippy/tests/ui/issue_2356.fixed1
-rw-r--r--src/tools/clippy/tests/ui/issue_2356.rs1
-rw-r--r--src/tools/clippy/tests/ui/issue_2356.stderr4
-rw-r--r--src/tools/clippy/tests/ui/issue_4266.rs4
-rw-r--r--src/tools/clippy/tests/ui/issue_4266.stderr6
-rw-r--r--src/tools/clippy/tests/ui/items_after_statement.rs3
-rw-r--r--src/tools/clippy/tests/ui/items_after_statement.stderr8
-rw-r--r--src/tools/clippy/tests/ui/iter_cloned_collect.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_cloned_collect.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_cloned_collect.stderr11
-rw-r--r--src/tools/clippy/tests/ui/iter_count.fixed1
-rw-r--r--src/tools/clippy/tests/ui/iter_count.rs1
-rw-r--r--src/tools/clippy/tests/ui/iter_count.stderr51
-rw-r--r--src/tools/clippy/tests/ui/iter_kv_map.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_kv_map.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_kv_map.stderr57
-rw-r--r--src/tools/clippy/tests/ui/iter_next_slice.fixed1
-rw-r--r--src/tools/clippy/tests/ui/iter_next_slice.rs1
-rw-r--r--src/tools/clippy/tests/ui/iter_next_slice.stderr9
-rw-r--r--src/tools/clippy/tests/ui/iter_not_returning_iterator.rs4
-rw-r--r--src/tools/clippy/tests/ui/iter_not_returning_iterator.stderr5
-rw-r--r--src/tools/clippy/tests/ui/iter_nth.stderr1
-rw-r--r--src/tools/clippy/tests/ui/iter_nth_zero.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_nth_zero.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_nth_zero.stderr7
-rw-r--r--src/tools/clippy/tests/ui/iter_on_empty_collections.fixed1
-rw-r--r--src/tools/clippy/tests/ui/iter_on_empty_collections.rs1
-rw-r--r--src/tools/clippy/tests/ui/iter_on_empty_collections.stderr13
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.fixed1
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.rs1
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.stderr13
-rw-r--r--src/tools/clippy/tests/ui/iter_out_of_bounds.rs71
-rw-r--r--src/tools/clippy/tests/ui/iter_out_of_bounds.stderr119
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.fixed53
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.rs43
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.stderr114
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next.stderr1
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next_unfixable.rs7
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr9
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_zero.fixed5
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_zero.rs5
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_zero.stderr11
-rw-r--r--src/tools/clippy/tests/ui/iter_with_drain.fixed1
-rw-r--r--src/tools/clippy/tests/ui/iter_with_drain.rs1
-rw-r--r--src/tools/clippy/tests/ui/iter_with_drain.stderr13
-rw-r--r--src/tools/clippy/tests/ui/iterator_step_by_zero.rs8
-rw-r--r--src/tools/clippy/tests/ui/iterator_step_by_zero.stderr13
-rw-r--r--src/tools/clippy/tests/ui/large_const_arrays.fixed2
-rw-r--r--src/tools/clippy/tests/ui/large_const_arrays.rs2
-rw-r--r--src/tools/clippy/tests/ui/large_const_arrays.stderr19
-rw-r--r--src/tools/clippy/tests/ui/large_digit_groups.fixed1
-rw-r--r--src/tools/clippy/tests/ui/large_digit_groups.rs1
-rw-r--r--src/tools/clippy/tests/ui/large_digit_groups.stderr12
-rw-r--r--src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr280
-rw-r--r--src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr (renamed from src/tools/clippy/tests/ui/large_enum_variant.stderr)45
-rw-r--r--src/tools/clippy/tests/ui/large_enum_variant.rs5
-rw-r--r--src/tools/clippy/tests/ui/large_futures.fixed70
-rw-r--r--src/tools/clippy/tests/ui/large_futures.rs8
-rw-r--r--src/tools/clippy/tests/ui/large_futures.stderr17
-rw-r--r--src/tools/clippy/tests/ui/large_stack_arrays.rs7
-rw-r--r--src/tools/clippy/tests/ui/large_stack_arrays.stderr13
-rw-r--r--src/tools/clippy/tests/ui/large_stack_frames.rs6
-rw-r--r--src/tools/clippy/tests/ui/large_stack_frames.stderr13
-rw-r--r--src/tools/clippy/tests/ui/large_types_passed_by_value.rs2
-rw-r--r--src/tools/clippy/tests/ui/large_types_passed_by_value.stderr1
-rw-r--r--src/tools/clippy/tests/ui/len_without_is_empty.rs39
-rw-r--r--src/tools/clippy/tests/ui/len_without_is_empty.stderr50
-rw-r--r--src/tools/clippy/tests/ui/len_zero.fixed2
-rw-r--r--src/tools/clippy/tests/ui/len_zero.rs2
-rw-r--r--src/tools/clippy/tests/ui/len_zero.stderr48
-rw-r--r--src/tools/clippy/tests/ui/len_zero_ranges.fixed2
-rw-r--r--src/tools/clippy/tests/ui/len_zero_ranges.rs2
-rw-r--r--src/tools/clippy/tests/ui/len_zero_ranges.stderr5
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.fixed187
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.rs5
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.stderr7
-rw-r--r--src/tools/clippy/tests/ui/let_if_seq.rs9
-rw-r--r--src/tools/clippy/tests/ui/let_if_seq.stderr18
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_future.rs5
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_future.stderr5
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_lock.rs4
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_lock.stderr7
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_must_use.rs12
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_must_use.stderr23
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_untyped.rs2
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_untyped.stderr1
-rw-r--r--src/tools/clippy/tests/ui/let_unit.fixed4
-rw-r--r--src/tools/clippy/tests/ui/let_unit.rs4
-rw-r--r--src/tools/clippy/tests/ui/let_unit.stderr21
-rw-r--r--src/tools/clippy/tests/ui/let_with_type_underscore.rs2
-rw-r--r--src/tools/clippy/tests/ui/let_with_type_underscore.stderr1
-rw-r--r--src/tools/clippy/tests/ui/lines_filter_map_ok.fixed2
-rw-r--r--src/tools/clippy/tests/ui/lines_filter_map_ok.rs2
-rw-r--r--src/tools/clippy/tests/ui/lines_filter_map_ok.stderr17
-rw-r--r--src/tools/clippy/tests/ui/linkedlist.rs9
-rw-r--r--src/tools/clippy/tests/ui/linkedlist.stderr17
-rw-r--r--src/tools/clippy/tests/ui/literals.rs27
-rw-r--r--src/tools/clippy/tests/ui/literals.stderr46
-rw-r--r--src/tools/clippy/tests/ui/lossy_float_literal.fixed1
-rw-r--r--src/tools/clippy/tests/ui/lossy_float_literal.rs1
-rw-r--r--src/tools/clippy/tests/ui/lossy_float_literal.stderr23
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.fixed4
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.rs4
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.stderr13
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports_expect.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2018.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2018.stderr19
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2021.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2021.stderr19
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.stderr27
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.stderr59
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.fixed296
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.rs70
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.stderr146
-rw-r--r--src/tools/clippy/tests/ui/manual_filter.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_filter.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_filter.stderr31
-rw-r--r--src/tools/clippy/tests/ui/manual_filter_map.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_filter_map.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_filter_map.stderr78
-rw-r--r--src/tools/clippy/tests/ui/manual_find.rs6
-rw-r--r--src/tools/clippy/tests/ui/manual_find.stderr13
-rw-r--r--src/tools/clippy/tests/ui/manual_find_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_find_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_find_fixable.stderr25
-rw-r--r--src/tools/clippy/tests/ui/manual_find_map.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_find_map.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_find_map.stderr79
-rw-r--r--src/tools/clippy/tests/ui/manual_flatten.rs11
-rw-r--r--src/tools/clippy/tests/ui/manual_flatten.stderr46
-rw-r--r--src/tools/clippy/tests/ui/manual_float_methods.rs3
-rw-r--r--src/tools/clippy/tests/ui/manual_float_methods.stderr14
-rw-r--r--src/tools/clippy/tests/ui/manual_instant_elapsed.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_instant_elapsed.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_instant_elapsed.stderr5
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.stderr41
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.rs28
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.stderr76
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.fixed135
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.rs10
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.stderr27
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_question_mark.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_question_mark.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_question_mark.stderr14
-rw-r--r--src/tools/clippy/tests/ui/manual_main_separator_str.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_main_separator_str.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_main_separator_str.stderr9
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.fixed3
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.rs3
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.stderr43
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option_2.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option_2.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option_2.stderr11
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs14
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.stderr33
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs16
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr39
-rw-r--r--src/tools/clippy/tests/ui/manual_next_back.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_next_back.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_next_back.stderr5
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs4
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr9
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs6
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr17
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_or.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_or.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_or.stderr9
-rw-r--r--src/tools/clippy/tests/ui/manual_range_patterns.fixed19
-rw-r--r--src/tools/clippy/tests/ui/manual_range_patterns.rs13
-rw-r--r--src/tools/clippy/tests/ui/manual_range_patterns.stderr83
-rw-r--r--src/tools/clippy/tests/ui/manual_rem_euclid.fixed3
-rw-r--r--src/tools/clippy/tests/ui/manual_rem_euclid.rs3
-rw-r--r--src/tools/clippy/tests/ui/manual_rem_euclid.stderr21
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.fixed40
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.rs40
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.stderr63
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr49
-rw-r--r--src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed3
-rw-r--r--src/tools/clippy/tests/ui/manual_slice_size_calculation.rs3
-rw-r--r--src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr15
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.stderr39
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.stderr25
-rw-r--r--src/tools/clippy/tests/ui/manual_string_new.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_string_new.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_string_new.stderr19
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.rs10
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.stderr33
-rw-r--r--src/tools/clippy/tests/ui/manual_try_fold.rs4
-rw-r--r--src/tools/clippy/tests/ui/manual_try_fold.stderr1
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.stderr29
-rw-r--r--src/tools/clippy/tests/ui/manual_while_let_some.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_while_let_some.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_while_let_some.stderr15
-rw-r--r--src/tools/clippy/tests/ui/many_single_char_names.rs6
-rw-r--r--src/tools/clippy/tests/ui/many_single_char_names.stderr8
-rw-r--r--src/tools/clippy/tests/ui/map_clone.fixed1
-rw-r--r--src/tools/clippy/tests/ui/map_clone.rs1
-rw-r--r--src/tools/clippy/tests/ui/map_clone.stderr13
-rw-r--r--src/tools/clippy/tests/ui/map_collect_result_unit.fixed1
-rw-r--r--src/tools/clippy/tests/ui/map_collect_result_unit.rs1
-rw-r--r--src/tools/clippy/tests/ui/map_collect_result_unit.stderr5
-rw-r--r--src/tools/clippy/tests/ui/map_err.rs1
-rw-r--r--src/tools/clippy/tests/ui/map_err.stderr1
-rw-r--r--src/tools/clippy/tests/ui/map_flatten.rs7
-rw-r--r--src/tools/clippy/tests/ui/map_flatten.stderr22
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.stderr19
-rw-r--r--src/tools/clippy/tests/ui/map_identity.fixed1
-rw-r--r--src/tools/clippy/tests/ui/map_identity.rs1
-rw-r--r--src/tools/clippy/tests/ui/map_identity.stderr13
-rw-r--r--src/tools/clippy/tests/ui/map_unwrap_or.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_unwrap_or.stderr1
-rw-r--r--src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/match_as_ref.fixed2
-rw-r--r--src/tools/clippy/tests/ui/match_as_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_as_ref.stderr7
-rw-r--r--src/tools/clippy/tests/ui/match_bool.rs11
-rw-r--r--src/tools/clippy/tests/ui/match_bool.stderr32
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed2
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr30
-rw-r--r--src/tools/clippy/tests/ui/match_on_vec_items.rs11
-rw-r--r--src/tools/clippy/tests/ui/match_on_vec_items.stderr15
-rw-r--r--src/tools/clippy/tests/ui/match_overlapping_arm.rs8
-rw-r--r--src/tools/clippy/tests/ui/match_overlapping_arm.stderr31
-rw-r--r--src/tools/clippy/tests/ui/match_ref_pats.fixed1
-rw-r--r--src/tools/clippy/tests/ui/match_ref_pats.rs1
-rw-r--r--src/tools/clippy/tests/ui/match_ref_pats.stderr12
-rw-r--r--src/tools/clippy/tests/ui/match_result_ok.fixed1
-rw-r--r--src/tools/clippy/tests/ui/match_result_ok.rs1
-rw-r--r--src/tools/clippy/tests/ui/match_result_ok.stderr7
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms.rs1
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms.stderr33
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms2.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs4
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr7
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.fixed1
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.rs1
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.stderr49
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding2.fixed1
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding2.rs1
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding2.stderr9
-rw-r--r--src/tools/clippy/tests/ui/match_str_case_mismatch.fixed1
-rw-r--r--src/tools/clippy/tests/ui/match_str_case_mismatch.rs1
-rw-r--r--src/tools/clippy/tests/ui/match_str_case_mismatch.stderr15
-rw-r--r--src/tools/clippy/tests/ui/match_wild_err_arm.rs8
-rw-r--r--src/tools/clippy/tests/ui/match_wild_err_arm.stderr7
-rw-r--r--src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed2
-rw-r--r--src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr21
-rw-r--r--src/tools/clippy/tests/ui/mem_forget.rs8
-rw-r--r--src/tools/clippy/tests/ui/mem_forget.stderr7
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.fixed2
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.rs2
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.stderr50
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_macro.rs2
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_macro.stderr1
-rw-r--r--src/tools/clippy/tests/ui/methods.stderr2
-rw-r--r--src/tools/clippy/tests/ui/methods_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/methods_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/methods_fixable.stderr3
-rw-r--r--src/tools/clippy/tests/ui/methods_unfixable.rs3
-rw-r--r--src/tools/clippy/tests/ui/methods_unfixable.stderr1
-rw-r--r--src/tools/clippy/tests/ui/min_ident_chars.rs2
-rw-r--r--src/tools/clippy/tests/ui/min_ident_chars.stderr1
-rw-r--r--src/tools/clippy/tests/ui/min_max.rs14
-rw-r--r--src/tools/clippy/tests/ui/min_max.stderr25
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.rs6
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.stderr10
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs5
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr14
-rw-r--r--src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed2
-rw-r--r--src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs2
-rw-r--r--src/tools/clippy/tests/ui/mismatched_target_os_non_unix.stderr9
-rw-r--r--src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed2
-rw-r--r--src/tools/clippy/tests/ui/mismatched_target_os_unix.rs2
-rw-r--r--src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr35
-rw-r--r--src/tools/clippy/tests/ui/mismatching_type_param_order.rs10
-rw-r--r--src/tools/clippy/tests/ui/mismatching_type_param_order.stderr17
-rw-r--r--src/tools/clippy/tests/ui/misnamed_getters.fixed143
-rw-r--r--src/tools/clippy/tests/ui/misnamed_getters.rs19
-rw-r--r--src/tools/clippy/tests/ui/misnamed_getters.stderr54
-rw-r--r--src/tools/clippy/tests/ui/missing_assert_message.rs16
-rw-r--r--src/tools/clippy/tests/ui/missing_assert_message.stderr31
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed121
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs121
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr253
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs49
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr164
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs12
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr33
-rw-r--r--src/tools/clippy/tests/ui/missing_doc.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_doc.stderr1
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_crate_missing.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr3
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_impl.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_impl.stderr1
-rw-r--r--src/tools/clippy/tests/ui/missing_fields_in_debug.rs3
-rw-r--r--src/tools/clippy/tests/ui/missing_fields_in_debug.stderr21
-rw-r--r--src/tools/clippy/tests/ui/missing_inline.rs25
-rw-r--r--src/tools/clippy/tests/ui/missing_inline.stderr25
-rw-r--r--src/tools/clippy/tests/ui/missing_panics_doc.stderr1
-rw-r--r--src/tools/clippy/tests/ui/missing_spin_loop.fixed1
-rw-r--r--src/tools/clippy/tests/ui/missing_spin_loop.rs1
-rw-r--r--src/tools/clippy/tests/ui/missing_spin_loop.stderr13
-rw-r--r--src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed1
-rw-r--r--src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs1
-rw-r--r--src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr3
-rw-r--r--src/tools/clippy/tests/ui/missing_trait_methods.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_trait_methods.stderr3
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed3
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.rs3
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr32
-rw-r--r--src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs4
-rw-r--r--src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr13
-rw-r--r--src/tools/clippy/tests/ui/module_inception.rs5
-rw-r--r--src/tools/clippy/tests/ui/module_inception.stderr12
-rw-r--r--src/tools/clippy/tests/ui/module_name_repetitions.rs6
-rw-r--r--src/tools/clippy/tests/ui/module_name_repetitions.stderr9
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_float.rs20
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr19
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs34
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr33
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs34
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr33
-rw-r--r--src/tools/clippy/tests/ui/modulo_one.rs26
-rw-r--r--src/tools/clippy/tests/ui/modulo_one.stderr27
-rw-r--r--src/tools/clippy/tests/ui/multi_assignments.rs7
-rw-r--r--src/tools/clippy/tests/ui/multi_assignments.stderr11
-rw-r--r--src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs2
-rw-r--r--src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr1
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.fixed1
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.rs1
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.stderr11
-rw-r--r--src/tools/clippy/tests/ui/must_use_unit.fixed3
-rw-r--r--src/tools/clippy/tests/ui/must_use_unit.rs3
-rw-r--r--src/tools/clippy/tests/ui/must_use_unit.stderr7
-rw-r--r--src/tools/clippy/tests/ui/mut_from_ref.rs6
-rw-r--r--src/tools/clippy/tests/ui/mut_from_ref.stderr21
-rw-r--r--src/tools/clippy/tests/ui/mut_key.rs20
-rw-r--r--src/tools/clippy/tests/ui/mut_key.stderr31
-rw-r--r--src/tools/clippy/tests/ui/mut_mut.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_mut.stderr1
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.fixed1
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.rs1
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.stderr3
-rw-r--r--src/tools/clippy/tests/ui/mut_range_bound.rs30
-rw-r--r--src/tools/clippy/tests/ui/mut_range_bound.stderr19
-rw-r--r--src/tools/clippy/tests/ui/mut_reference.rs6
-rw-r--r--src/tools/clippy/tests/ui/mut_reference.stderr5
-rw-r--r--src/tools/clippy/tests/ui/mutex_atomic.rs9
-rw-r--r--src/tools/clippy/tests/ui/mutex_atomic.stderr14
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type.stderr13
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.fixed46
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr1
-rw-r--r--src/tools/clippy/tests/ui/needless_bitwise_bool.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_bitwise_bool.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_bitwise_bool.stderr3
-rw-r--r--src/tools/clippy/tests/ui/needless_bool/fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_bool/fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_bool/fixable.stderr44
-rw-r--r--src/tools/clippy/tests/ui/needless_bool/simple.stderr1
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.stderr11
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed292
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs292
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr131
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow_pat.fixed163
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow_pat.rs13
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow_pat.stderr27
-rw-r--r--src/tools/clippy/tests/ui/needless_borrowed_ref.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_borrowed_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_borrowed_ref.stderr35
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed287
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs287
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr77
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.stderr39
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.rs19
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.stderr66
-rw-r--r--src/tools/clippy/tests/ui/needless_continue.rs20
-rw-r--r--src/tools/clippy/tests/ui/needless_continue.stderr39
-rw-r--r--src/tools/clippy/tests/ui/needless_doc_main.rs6
-rw-r--r--src/tools/clippy/tests/ui/needless_doc_main.stderr43
-rw-r--r--src/tools/clippy/tests/ui/needless_else.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_else.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_else.stderr3
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.stderr17
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_unfixable.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr11
-rw-r--r--src/tools/clippy/tests/ui/needless_if.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_if.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_if.stderr15
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.stderr33
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.stderr93
-rw-r--r--src/tools/clippy/tests/ui/needless_match.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_match.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_match.stderr27
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.stderr7
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.stderr3
-rw-r--r--src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_parens_on_range_literals.stderr13
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs47
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr69
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.rs25
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.stderr51
-rw-r--r--src/tools/clippy/tests/ui/needless_pub_self.fixed4
-rw-r--r--src/tools/clippy/tests/ui/needless_pub_self.rs4
-rw-r--r--src/tools/clippy/tests/ui/needless_pub_self.stderr1
-rw-r--r--src/tools/clippy/tests/ui/needless_question_mark.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_question_mark.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_question_mark.stderr29
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop.rs17
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop.stderr27
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop2.rs11
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop2.stderr15
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.fixed14
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.rs14
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.stderr53
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed23
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.rs23
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr179
-rw-r--r--src/tools/clippy/tests/ui/needless_return.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_return.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr105
-rw-r--r--src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_return_with_question_mark.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr3
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.stderr27
-rw-r--r--src/tools/clippy/tests/ui/needless_update.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_update.stderr1
-rw-r--r--src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.rs5
-rw-r--r--src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.stderr7
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.fixed1
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.rs1
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.stderr17
-rw-r--r--src/tools/clippy/tests/ui/never_loop.rs71
-rw-r--r--src/tools/clippy/tests/ui/never_loop.stderr83
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self.rs13
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self.stderr34
-rw-r--r--src/tools/clippy/tests/ui/new_without_default.fixed309
-rw-r--r--src/tools/clippy/tests/ui/new_without_default.rs27
-rw-r--r--src/tools/clippy/tests/ui/new_without_default.stderr43
-rw-r--r--src/tools/clippy/tests/ui/no_effect.rs31
-rw-r--r--src/tools/clippy/tests/ui/no_effect.stderr58
-rw-r--r--src/tools/clippy/tests/ui/no_effect_replace.rs9
-rw-r--r--src/tools/clippy/tests/ui/no_effect_replace.stderr15
-rw-r--r--src/tools/clippy/tests/ui/no_effect_return.rs12
-rw-r--r--src/tools/clippy/tests/ui/no_effect_return.stderr23
-rw-r--r--src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs7
-rw-r--r--src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr12
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed (renamed from src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.fixed)1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.rs (renamed from src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.rs)1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr (renamed from src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.stderr)19
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed (renamed from src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.fixed)1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs (renamed from src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.rs)1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr (renamed from src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.stderr)11
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs (renamed from src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type_fully_qual.rs)2
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr (renamed from src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type_fully_qual.stderr)11
-rw-r--r--src/tools/clippy/tests/ui/non_expressive_names.stderr1
-rw-r--r--src/tools/clippy/tests/ui/non_minimal_cfg.fixed2
-rw-r--r--src/tools/clippy/tests/ui/non_minimal_cfg.rs2
-rw-r--r--src/tools/clippy/tests/ui/non_minimal_cfg.stderr9
-rw-r--r--src/tools/clippy/tests/ui/non_minimal_cfg2.rs2
-rw-r--r--src/tools/clippy/tests/ui/non_minimal_cfg2.stderr1
-rw-r--r--src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed2
-rw-r--r--src/tools/clippy/tests/ui/non_octal_unix_permissions.rs2
-rw-r--r--src/tools/clippy/tests/ui/non_octal_unix_permissions.stderr1
-rw-r--r--src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs12
-rw-r--r--src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr49
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.rs15
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.stderr27
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed1
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.rs1
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr27
-rw-r--r--src/tools/clippy/tests/ui/numbered_fields.fixed1
-rw-r--r--src/tools/clippy/tests/ui/numbered_fields.rs1
-rw-r--r--src/tools/clippy/tests/ui/numbered_fields.stderr5
-rw-r--r--src/tools/clippy/tests/ui/obfuscated_if_else.fixed2
-rw-r--r--src/tools/clippy/tests/ui/obfuscated_if_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/obfuscated_if_else.stderr3
-rw-r--r--src/tools/clippy/tests/ui/octal_escapes.rs10
-rw-r--r--src/tools/clippy/tests/ui/octal_escapes.stderr91
-rw-r--r--src/tools/clippy/tests/ui/ok_expect.rs5
-rw-r--r--src/tools/clippy/tests/ui/ok_expect.stderr9
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion.rs18
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion.stderr63
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion2.rs7
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion2.stderr19
-rw-r--r--src/tools/clippy/tests/ui/op_ref.fixed99
-rw-r--r--src/tools/clippy/tests/ui/op_ref.rs5
-rw-r--r--src/tools/clippy/tests/ui/op_ref.stderr7
-rw-r--r--src/tools/clippy/tests/ui/open_options.rs8
-rw-r--r--src/tools/clippy/tests/ui/open_options.stderr13
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_deref.fixed2
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_deref.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_deref.stderr37
-rw-r--r--src/tools/clippy/tests/ui/option_env_unwrap.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_env_unwrap.stderr1
-rw-r--r--src/tools/clippy/tests/ui/option_filter_map.fixed3
-rw-r--r--src/tools/clippy/tests/ui/option_filter_map.rs3
-rw-r--r--src/tools/clippy/tests/ui/option_filter_map.stderr17
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed1
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs1
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.stderr47
-rw-r--r--src/tools/clippy/tests/ui/option_map_or_none.fixed2
-rw-r--r--src/tools/clippy/tests/ui/option_map_or_none.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_map_or_none.stderr12
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr39
-rw-r--r--src/tools/clippy/tests/ui/option_option.rs12
-rw-r--r--src/tools/clippy/tests/ui/option_option.stderr22
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.fixed1
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.rs1
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.stderr64
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.fixed2
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.rs2
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.stderr7
-rw-r--r--src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.rs7
-rw-r--r--src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.stderr7
-rw-r--r--src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.rs7
-rw-r--r--src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.stderr11
-rw-r--r--src/tools/clippy/tests/ui/overflow_check_conditional.rs9
-rw-r--r--src/tools/clippy/tests/ui/overflow_check_conditional.stderr15
-rw-r--r--src/tools/clippy/tests/ui/overly_complex_bool_expr.fixed39
-rw-r--r--src/tools/clippy/tests/ui/overly_complex_bool_expr.rs5
-rw-r--r--src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr17
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn.stderr9
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs3
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr14
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.rs20
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.stderr34
-rw-r--r--src/tools/clippy/tests/ui/partial_pub_fields.rs4
-rw-r--r--src/tools/clippy/tests/ui/partial_pub_fields.stderr7
-rw-r--r--src/tools/clippy/tests/ui/partialeq_ne_impl.rs2
-rw-r--r--src/tools/clippy/tests/ui/partialeq_ne_impl.stderr3
-rw-r--r--src/tools/clippy/tests/ui/partialeq_to_none.fixed1
-rw-r--r--src/tools/clippy/tests/ui/partialeq_to_none.rs1
-rw-r--r--src/tools/clippy/tests/ui/partialeq_to_none.stderr31
-rw-r--r--src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed1
-rw-r--r--src/tools/clippy/tests/ui/path_buf_push_overwrite.rs1
-rw-r--r--src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr5
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.fixed36
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.rs36
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.stderr17
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.rs2
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr3
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.rs3
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr5
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.rs8
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr15
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.rs10
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr19
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs8
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr17
-rw-r--r--src/tools/clippy/tests/ui/patterns.fixed3
-rw-r--r--src/tools/clippy/tests/ui/patterns.rs3
-rw-r--r--src/tools/clippy/tests/ui/patterns.stderr7
-rw-r--r--src/tools/clippy/tests/ui/permissions_set_readonly_false.rs2
-rw-r--r--src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr1
-rw-r--r--src/tools/clippy/tests/ui/precedence.fixed1
-rw-r--r--src/tools/clippy/tests/ui/precedence.rs1
-rw-r--r--src/tools/clippy/tests/ui/precedence.stderr25
-rw-r--r--src/tools/clippy/tests/ui/print.rs10
-rw-r--r--src/tools/clippy/tests/ui/print.stderr16
-rw-r--r--src/tools/clippy/tests/ui/print_in_format_impl.rs10
-rw-r--r--src/tools/clippy/tests/ui/print_in_format_impl.stderr13
-rw-r--r--src/tools/clippy/tests/ui/print_literal.fixed58
-rw-r--r--src/tools/clippy/tests/ui/print_literal.rs13
-rw-r--r--src/tools/clippy/tests/ui/print_literal.stderr23
-rw-r--r--src/tools/clippy/tests/ui/print_stderr.rs3
-rw-r--r--src/tools/clippy/tests/ui/print_stderr.stderr3
-rw-r--r--src/tools/clippy/tests/ui/print_with_newline.fixed28
-rw-r--r--src/tools/clippy/tests/ui/print_with_newline.rs28
-rw-r--r--src/tools/clippy/tests/ui/print_with_newline.stderr55
-rw-r--r--src/tools/clippy/tests/ui/println_empty_string.fixed1
-rw-r--r--src/tools/clippy/tests/ui/println_empty_string.rs1
-rw-r--r--src/tools/clippy/tests/ui/println_empty_string.stderr9
-rw-r--r--src/tools/clippy/tests/ui/proc_macro.rs1
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.rs26
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.stderr52
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.fixed3
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.rs3
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.stderr19
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.fixed3
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.rs3
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.stderr15
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.fixed1
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.rs1
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.stderr5
-rw-r--r--src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed1
-rw-r--r--src/tools/clippy/tests/ui/ptr_offset_with_cast.rs1
-rw-r--r--src/tools/clippy/tests/ui/ptr_offset_with_cast.stderr5
-rw-r--r--src/tools/clippy/tests/ui/pub_use.rs1
-rw-r--r--src/tools/clippy/tests/ui/pub_use.stderr1
-rw-r--r--src/tools/clippy/tests/ui/pub_with_shorthand.fixed4
-rw-r--r--src/tools/clippy/tests/ui/pub_with_shorthand.rs4
-rw-r--r--src/tools/clippy/tests/ui/pub_with_shorthand.stderr1
-rw-r--r--src/tools/clippy/tests/ui/pub_without_shorthand.fixed4
-rw-r--r--src/tools/clippy/tests/ui/pub_without_shorthand.rs4
-rw-r--r--src/tools/clippy/tests/ui/pub_without_shorthand.stderr1
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed1
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs1
-rw-r--r--src/tools/clippy/tests/ui/question_mark.stderr33
-rw-r--r--src/tools/clippy/tests/ui/question_mark_used.rs1
-rw-r--r--src/tools/clippy/tests/ui/question_mark_used.stderr1
-rw-r--r--src/tools/clippy/tests/ui/range.rs2
-rw-r--r--src/tools/clippy/tests/ui/range.stderr1
-rw-r--r--src/tools/clippy/tests/ui/range_contains.fixed2
-rw-r--r--src/tools/clippy/tests/ui/range_contains.rs2
-rw-r--r--src/tools/clippy/tests/ui/range_contains.stderr43
-rw-r--r--src/tools/clippy/tests/ui/range_plus_minus_one.fixed2
-rw-r--r--src/tools/clippy/tests/ui/range_plus_minus_one.rs2
-rw-r--r--src/tools/clippy/tests/ui/range_plus_minus_one.stderr20
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer.fixed1
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer.rs1
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer.stderr17
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer_arc.fixed1
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer_arc.rs1
-rw-r--r--src/tools/clippy/tests/ui/rc_buffer_arc.stderr17
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.rs9
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr17
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.rs9
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr17
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.rs17
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr25
-rw-r--r--src/tools/clippy/tests/ui/rc_mutex.rs4
-rw-r--r--src/tools/clippy/tests/ui/rc_mutex.stderr7
-rw-r--r--src/tools/clippy/tests/ui/read_line_without_trim.fixed2
-rw-r--r--src/tools/clippy/tests/ui/read_line_without_trim.rs2
-rw-r--r--src/tools/clippy/tests/ui/read_line_without_trim.stderr21
-rw-r--r--src/tools/clippy/tests/ui/read_zero_byte_vec.rs13
-rw-r--r--src/tools/clippy/tests/ui/read_zero_byte_vec.stderr19
-rw-r--r--src/tools/clippy/tests/ui/readonly_write_lock.fixed45
-rw-r--r--src/tools/clippy/tests/ui/readonly_write_lock.rs3
-rw-r--r--src/tools/clippy/tests/ui/readonly_write_lock.stderr3
-rw-r--r--src/tools/clippy/tests/ui/recursive_format_impl.rs11
-rw-r--r--src/tools/clippy/tests/ui/recursive_format_impl.stderr19
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.rs45
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.stderr39
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr25
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.fixed24
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.rs24
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.stderr17
-rw-r--r--src/tools/clippy/tests/ui/redundant_async_block.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_async_block.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_async_block.stderr21
-rw-r--r--src/tools/clippy/tests/ui/redundant_at_rest_pattern.fixed3
-rw-r--r--src/tools/clippy/tests/ui/redundant_at_rest_pattern.rs3
-rw-r--r--src/tools/clippy/tests/ui/redundant_at_rest_pattern.stderr13
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.fixed1
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.rs1
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.stderr61
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_early.rs3
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_early.stderr3
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr29
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_late.rs4
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_late.stderr5
-rw-r--r--src/tools/clippy/tests/ui/redundant_else.rs7
-rw-r--r--src/tools/clippy/tests/ui/redundant_else.stderr20
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.fixed13
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.rs13
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.stderr17
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.fixed53
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.rs53
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.stderr127
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.stderr1
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr45
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed1
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs1
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.stderr37
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr61
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_poll.stderr37
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed1
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs1
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr57
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.fixed1
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.rs1
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.stderr33
-rw-r--r--src/tools/clippy/tests/ui/redundant_slicing.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_slicing.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_slicing.stderr7
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr37
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.rs12
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.stderr21
-rw-r--r--src/tools/clippy/tests/ui/redundant_type_annotations.rs18
-rw-r--r--src/tools/clippy/tests/ui/redundant_type_annotations.stderr33
-rw-r--r--src/tools/clippy/tests/ui/ref_binding_to_reference.rs10
-rw-r--r--src/tools/clippy/tests/ui/ref_binding_to_reference.stderr18
-rw-r--r--src/tools/clippy/tests/ui/ref_option_ref.rs14
-rw-r--r--src/tools/clippy/tests/ui/ref_option_ref.stderr21
-rw-r--r--src/tools/clippy/tests/ui/ref_patterns.rs3
-rw-r--r--src/tools/clippy/tests/ui/ref_patterns.stderr5
-rw-r--r--src/tools/clippy/tests/ui/regex.rs22
-rw-r--r--src/tools/clippy/tests/ui/regex.stderr60
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed10
-rw-r--r--src/tools/clippy/tests/ui/rename.rs10
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr107
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.fixed2
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.rs2
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.stderr2
-rw-r--r--src/tools/clippy/tests/ui/repeat_once.fixed1
-rw-r--r--src/tools/clippy/tests/ui/repeat_once.rs1
-rw-r--r--src/tools/clippy/tests/ui/repeat_once.stderr13
-rw-r--r--src/tools/clippy/tests/ui/repl_uninit.rs7
-rw-r--r--src/tools/clippy/tests/ui/repl_uninit.stderr7
-rw-r--r--src/tools/clippy/tests/ui/reserve_after_initialization.fixed48
-rw-r--r--src/tools/clippy/tests/ui/reserve_after_initialization.rs51
-rw-r--r--src/tools/clippy/tests/ui/reserve_after_initialization.stderr26
-rw-r--r--src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs5
-rw-r--r--src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr7
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.rs14
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.stderr25
-rw-r--r--src/tools/clippy/tests/ui/result_map_or_into_option.fixed2
-rw-r--r--src/tools/clippy/tests/ui/result_map_or_into_option.rs2
-rw-r--r--src/tools/clippy/tests/ui/result_map_or_into_option.stderr3
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr37
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs11
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr12
-rw-r--r--src/tools/clippy/tests/ui/result_unit_error.rs5
-rw-r--r--src/tools/clippy/tests/ui/result_unit_error.stderr9
-rw-r--r--src/tools/clippy/tests/ui/return_self_not_must_use.rs3
-rw-r--r--src/tools/clippy/tests/ui/return_self_not_must_use.stderr7
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr9
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr13
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.rs3
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.stderr3
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.rs4
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.rs5
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.stderr9
-rw-r--r--src/tools/clippy/tests/ui/same_name_method.rs5
-rw-r--r--src/tools/clippy/tests/ui/same_name_method.stderr19
-rw-r--r--src/tools/clippy/tests/ui/search_is_some.rs2
-rw-r--r--src/tools/clippy/tests/ui/search_is_some.stderr1
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed1
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_none.rs1
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr87
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed1
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_some.rs1
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr95
-rw-r--r--src/tools/clippy/tests/ui/seek_from_current.fixed1
-rw-r--r--src/tools/clippy/tests/ui/seek_from_current.rs1
-rw-r--r--src/tools/clippy/tests/ui/seek_from_current.stderr3
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed1
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs1
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr7
-rw-r--r--src/tools/clippy/tests/ui/self_assignment.rs12
-rw-r--r--src/tools/clippy/tests/ui/self_assignment.stderr21
-rw-r--r--src/tools/clippy/tests/ui/self_named_constructors.rs2
-rw-r--r--src/tools/clippy/tests/ui/self_named_constructors.stderr3
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed1
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs1
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr11
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block.fixed1
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block.rs1
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block.stderr9
-rw-r--r--src/tools/clippy/tests/ui/semicolon_outside_block.fixed1
-rw-r--r--src/tools/clippy/tests/ui/semicolon_outside_block.rs1
-rw-r--r--src/tools/clippy/tests/ui/semicolon_outside_block.stderr9
-rw-r--r--src/tools/clippy/tests/ui/serde.rs2
-rw-r--r--src/tools/clippy/tests/ui/serde.stderr6
-rw-r--r--src/tools/clippy/tests/ui/shadow.rs2
-rw-r--r--src/tools/clippy/tests/ui/shadow.stderr3
-rw-r--r--src/tools/clippy/tests/ui/short_circuit_statement.fixed2
-rw-r--r--src/tools/clippy/tests/ui/short_circuit_statement.rs2
-rw-r--r--src/tools/clippy/tests/ui/short_circuit_statement.stderr7
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_1.rs15
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr44
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs17
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr44
-rw-r--r--src/tools/clippy/tests/ui/should_panic_without_expect.rs21
-rw-r--r--src/tools/clippy/tests/ui/should_panic_without_expect.stderr14
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.fixed627
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs54
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr86
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_tightening.fixed2
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_tightening.rs2
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_tightening.stderr9
-rw-r--r--src/tools/clippy/tests/ui/similar_names.rs8
-rw-r--r--src/tools/clippy/tests/ui/similar_names.stderr29
-rw-r--r--src/tools/clippy/tests/ui/single_call_fn.rs3
-rw-r--r--src/tools/clippy/tests/ui/single_call_fn.stderr17
-rw-r--r--src/tools/clippy/tests/ui/single_char_add_str.fixed1
-rw-r--r--src/tools/clippy/tests/ui/single_char_add_str.rs1
-rw-r--r--src/tools/clippy/tests/ui/single_char_add_str.stderr53
-rw-r--r--src/tools/clippy/tests/ui/single_char_lifetime_names.rs5
-rw-r--r--src/tools/clippy/tests/ui/single_char_lifetime_names.stderr7
-rw-r--r--src/tools/clippy/tests/ui/single_char_pattern.fixed2
-rw-r--r--src/tools/clippy/tests/ui/single_char_pattern.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_char_pattern.stderr103
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports.fixed1
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports.rs1
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports.stderr5
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports_nested_first.rs6
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr5
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.fixed1
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.rs1
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.stderr15
-rw-r--r--src/tools/clippy/tests/ui/single_match.fixed1
-rw-r--r--src/tools/clippy/tests/ui/single_match.rs1
-rw-r--r--src/tools/clippy/tests/ui/single_match.stderr37
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.fixed3
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.rs3
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr19
-rw-r--r--src/tools/clippy/tests/ui/single_range_in_vec_init.rs3
-rw-r--r--src/tools/clippy/tests/ui/single_range_in_vec_init.stderr21
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs4
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr7
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs21
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr41
-rw-r--r--src/tools/clippy/tests/ui/size_of_ref.rs3
-rw-r--r--src/tools/clippy/tests/ui/size_of_ref.stderr5
-rw-r--r--src/tools/clippy/tests/ui/skip_while_next.stderr1
-rw-r--r--src/tools/clippy/tests/ui/slow_vector_initialization.rs29
-rw-r--r--src/tools/clippy/tests/ui/slow_vector_initialization.stderr33
-rw-r--r--src/tools/clippy/tests/ui/stable_sort_primitive.fixed1
-rw-r--r--src/tools/clippy/tests/ui/stable_sort_primitive.rs1
-rw-r--r--src/tools/clippy/tests/ui/stable_sort_primitive.stderr15
-rw-r--r--src/tools/clippy/tests/ui/starts_ends_with.fixed1
-rw-r--r--src/tools/clippy/tests/ui/starts_ends_with.rs1
-rw-r--r--src/tools/clippy/tests/ui/starts_ends_with.stderr54
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.fixed62
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.rs11
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.stderr74
-rw-r--r--src/tools/clippy/tests/ui/str_to_string.rs2
-rw-r--r--src/tools/clippy/tests/ui/str_to_string.stderr3
-rw-r--r--src/tools/clippy/tests/ui/string_add.rs4
-rw-r--r--src/tools/clippy/tests/ui/string_add.stderr2
-rw-r--r--src/tools/clippy/tests/ui/string_add_assign.fixed2
-rw-r--r--src/tools/clippy/tests/ui/string_add_assign.rs2
-rw-r--r--src/tools/clippy/tests/ui/string_add_assign.stderr8
-rw-r--r--src/tools/clippy/tests/ui/string_extend.fixed2
-rw-r--r--src/tools/clippy/tests/ui/string_extend.rs2
-rw-r--r--src/tools/clippy/tests/ui/string_extend.stderr9
-rw-r--r--src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed1
-rw-r--r--src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs1
-rw-r--r--src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr3
-rw-r--r--src/tools/clippy/tests/ui/string_lit_as_bytes.fixed1
-rw-r--r--src/tools/clippy/tests/ui/string_lit_as_bytes.rs1
-rw-r--r--src/tools/clippy/tests/ui/string_lit_as_bytes.stderr19
-rw-r--r--src/tools/clippy/tests/ui/string_lit_chars_any.fixed3
-rw-r--r--src/tools/clippy/tests/ui/string_lit_chars_any.rs3
-rw-r--r--src/tools/clippy/tests/ui/string_lit_chars_any.stderr31
-rw-r--r--src/tools/clippy/tests/ui/string_slice.rs4
-rw-r--r--src/tools/clippy/tests/ui/string_slice.stderr5
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.rs1
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.stderr1
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.fixed2
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.rs2
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.stderr15
-rw-r--r--src/tools/clippy/tests/ui/struct_excessive_bools.rs2
-rw-r--r--src/tools/clippy/tests/ui/struct_excessive_bools.stderr5
-rw-r--r--src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs11
-rw-r--r--src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr18
-rw-r--r--src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed13
-rw-r--r--src/tools/clippy/tests/ui/suspicious_command_arg_space.rs3
-rw-r--r--src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr3
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.fixed1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.rs1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.stderr19
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr9
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.rs2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.stderr1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_map.rs2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_map.stderr3
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.rs1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr53
-rw-r--r--src/tools/clippy/tests/ui/suspicious_splitn.rs18
-rw-r--r--src/tools/clippy/tests/ui/suspicious_splitn.stderr17
-rw-r--r--src/tools/clippy/tests/ui/suspicious_to_owned.rs9
-rw-r--r--src/tools/clippy/tests/ui/suspicious_to_owned.stderr14
-rw-r--r--src/tools/clippy/tests/ui/suspicious_unary_op_formatting.rs4
-rw-r--r--src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr7
-rw-r--r--src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.rs9
-rw-r--r--src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr11
-rw-r--r--src/tools/clippy/tests/ui/swap.fixed1
-rw-r--r--src/tools/clippy/tests/ui/swap.rs1
-rw-r--r--src/tools/clippy/tests/ui/swap.stderr36
-rw-r--r--src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed2
-rw-r--r--src/tools/clippy/tests/ui/swap_ptr_to_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/swap_ptr_to_ref.stderr9
-rw-r--r--src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.rs4
-rw-r--r--src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed2
-rw-r--r--src/tools/clippy/tests/ui/tabs_in_doc_comments.rs2
-rw-r--r--src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr17
-rw-r--r--src/tools/clippy/tests/ui/temporary_assignment.rs5
-rw-r--r--src/tools/clippy/tests/ui/temporary_assignment.stderr8
-rw-r--r--src/tools/clippy/tests/ui/tests_outside_test_module.rs2
-rw-r--r--src/tools/clippy/tests/ui/tests_outside_test_module.stderr1
-rw-r--r--src/tools/clippy/tests/ui/to_digit_is_some.fixed2
-rw-r--r--src/tools/clippy/tests/ui/to_digit_is_some.rs2
-rw-r--r--src/tools/clippy/tests/ui/to_digit_is_some.stderr5
-rw-r--r--src/tools/clippy/tests/ui/to_string_in_format_args_incremental.fixed1
-rw-r--r--src/tools/clippy/tests/ui/toplevel_ref_arg.fixed3
-rw-r--r--src/tools/clippy/tests/ui/toplevel_ref_arg.rs3
-rw-r--r--src/tools/clippy/tests/ui/toplevel_ref_arg.stderr13
-rw-r--r--src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs2
-rw-r--r--src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr1
-rw-r--r--src/tools/clippy/tests/ui/trailing_empty_array.rs11
-rw-r--r--src/tools/clippy/tests/ui/trailing_empty_array.stderr31
-rw-r--r--src/tools/clippy/tests/ui/trailing_zeros.fixed13
-rw-r--r--src/tools/clippy/tests/ui/trailing_zeros.rs7
-rw-r--r--src/tools/clippy/tests/ui/trailing_zeros.stderr7
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed1
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs1
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr20
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs8
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr12
-rw-r--r--src/tools/clippy/tests/ui/transmute.rs47
-rw-r--r--src/tools/clippy/tests/ui/transmute.stderr81
-rw-r--r--src/tools/clippy/tests/ui/transmute_32bit.stderr30
-rw-r--r--src/tools/clippy/tests/ui/transmute_64bit.rs3
-rw-r--r--src/tools/clippy/tests/ui/transmute_64bit.stderr3
-rw-r--r--src/tools/clippy/tests/ui/transmute_collection.rs19
-rw-r--r--src/tools/clippy/tests/ui/transmute_collection.stderr35
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.fixed32
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.rs7
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.stderr11
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed52
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs11
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr19
-rw-r--r--src/tools/clippy/tests/ui/transmute_null_to_fn.rs14
-rw-r--r--src/tools/clippy/tests/ui/transmute_null_to_fn.stderr31
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed70
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs7
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr11
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr45
-rw-r--r--src/tools/clippy/tests/ui/transmute_undefined_repr.rs305
-rw-r--r--src/tools/clippy/tests/ui/transmute_undefined_repr.stderr49
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed1
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs1
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr23
-rw-r--r--src/tools/clippy/tests/ui/transmuting_null.rs4
-rw-r--r--src/tools/clippy/tests/ui/transmuting_null.stderr5
-rw-r--r--src/tools/clippy/tests/ui/trim_split_whitespace.fixed1
-rw-r--r--src/tools/clippy/tests/ui/trim_split_whitespace.rs1
-rw-r--r--src/tools/clippy/tests/ui/trim_split_whitespace.stderr17
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs21
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr66
-rw-r--r--src/tools/clippy/tests/ui/try_err.fixed3
-rw-r--r--src/tools/clippy/tests/ui/try_err.rs3
-rw-r--r--src/tools/clippy/tests/ui/try_err.stderr24
-rw-r--r--src/tools/clippy/tests/ui/tuple_array_conversions.rs7
-rw-r--r--src/tools/clippy/tests/ui/tuple_array_conversions.stderr5
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.rs16
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.stderr29
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box.fixed2
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box.rs2
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box.stderr7
-rw-r--r--src/tools/clippy/tests/ui/type_repetition_in_bounds.rs5
-rw-r--r--src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr8
-rw-r--r--src/tools/clippy/tests/ui/types.fixed2
-rw-r--r--src/tools/clippy/tests/ui/types.rs2
-rw-r--r--src/tools/clippy/tests/ui/types.stderr3
-rw-r--r--src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs1
-rw-r--r--src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr9
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs534
-rw-r--r--src/tools/clippy/tests/ui/unicode.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unicode.rs1
-rw-r--r--src/tools/clippy/tests/ui/unicode.stderr36
-rw-r--r--src/tools/clippy/tests/ui/uninit.rs4
-rw-r--r--src/tools/clippy/tests/ui/uninit.stderr4
-rw-r--r--src/tools/clippy/tests/ui/uninit_vec.rs11
-rw-r--r--src/tools/clippy/tests/ui/uninit_vec.stderr39
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.fixed4
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.rs4
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.stderr9
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed1
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr3
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed1
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.stderr13
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args_panic.rs1
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.rs3
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.stderr21
-rw-r--r--src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs1
-rw-r--r--src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr9
-rw-r--r--src/tools/clippy/tests/ui/unit_cmp.rs7
-rw-r--r--src/tools/clippy/tests/ui/unit_cmp.stderr22
-rw-r--r--src/tools/clippy/tests/ui/unit_hash.fixed34
-rw-r--r--src/tools/clippy/tests/ui/unit_hash.rs6
-rw-r--r--src/tools/clippy/tests/ui/unit_hash.stderr5
-rw-r--r--src/tools/clippy/tests/ui/unit_return_expecting_ord.rs4
-rw-r--r--src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr11
-rw-r--r--src/tools/clippy/tests/ui/unknown_attribute.rs1
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.rs2
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.stderr17
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_box_returns.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_box_returns.stderr7
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.rs1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.stderr81
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_unfixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_unfixable.stderr3
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_clone.rs13
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_clone.stderr18
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_filter_map.rs5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_filter_map.stderr11
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_find_map.rs5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_find_map.stderr11
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_fold.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_fold.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_fold.stderr31
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_join.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_join.rs1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_join.stderr5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed3
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs3
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr77
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr107
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs54
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr199
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed56
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs56
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr53
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.stderr39
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_safety_comment.rs8
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr33
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_self_imports.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_self_imports.rs1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_self_imports.stderr5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_sort_by.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_sort_by.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_sort_by.stderr25
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr13
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr170
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_wraps.rs9
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_wraps.stderr27
-rw-r--r--src/tools/clippy/tests/ui/unneeded_field_pattern.rs2
-rw-r--r--src/tools/clippy/tests/ui/unneeded_field_pattern.stderr1
-rw-r--r--src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed3
-rw-r--r--src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs3
-rw-r--r--src/tools/clippy/tests/ui/unneeded_wildcard_pattern.stderr30
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.stderr35
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns2.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns2.rs2
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns2.stderr17
-rw-r--r--src/tools/clippy/tests/ui/unreadable_literal.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unreadable_literal.rs2
-rw-r--r--src/tools/clippy/tests/ui/unreadable_literal.stderr21
-rw-r--r--src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs4
-rw-r--r--src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr7
-rw-r--r--src/tools/clippy/tests/ui/unsafe_removed_from_name.rs6
-rw-r--r--src/tools/clippy/tests/ui/unsafe_removed_from_name.stderr9
-rw-r--r--src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed3
-rw-r--r--src/tools/clippy/tests/ui/unseparated_prefix_literals.rs3
-rw-r--r--src/tools/clippy/tests/ui/unseparated_prefix_literals.stderr19
-rw-r--r--src/tools/clippy/tests/ui/unused_async.rs4
-rw-r--r--src/tools/clippy/tests/ui/unused_async.stderr12
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs7
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr7
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.rs20
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.stderr40
-rw-r--r--src/tools/clippy/tests/ui/unused_peekable.rs8
-rw-r--r--src/tools/clippy/tests/ui/unused_peekable.stderr15
-rw-r--r--src/tools/clippy/tests/ui/unused_rounding.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unused_rounding.rs1
-rw-r--r--src/tools/clippy/tests/ui/unused_rounding.stderr11
-rw-r--r--src/tools/clippy/tests/ui/unused_self.rs9
-rw-r--r--src/tools/clippy/tests/ui/unused_self.stderr17
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.rs2
-rw-r--r--src/tools/clippy/tests/ui/unwrap.rs3
-rw-r--r--src/tools/clippy/tests/ui/unwrap.stderr5
-rw-r--r--src/tools/clippy/tests/ui/unwrap_expect_used.rs6
-rw-r--r--src/tools/clippy/tests/ui/unwrap_expect_used.stderr12
-rw-r--r--src/tools/clippy/tests/ui/unwrap_in_result.rs2
-rw-r--r--src/tools/clippy/tests/ui/unwrap_in_result.stderr13
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or.fixed13
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or.rs3
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or.stderr3
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or_else_default.fixed32
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or_else_default.rs32
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or_else_default.stderr33
-rw-r--r--src/tools/clippy/tests/ui/upper_case_acronyms.fixed62
-rw-r--r--src/tools/clippy/tests/ui/upper_case_acronyms.rs12
-rw-r--r--src/tools/clippy/tests/ui/upper_case_acronyms.stderr21
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed3
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs3
-rw-r--r--src/tools/clippy/tests/ui/use_self.stderr85
-rw-r--r--src/tools/clippy/tests/ui/use_self_trait.fixed2
-rw-r--r--src/tools/clippy/tests/ui/use_self_trait.rs2
-rw-r--r--src/tools/clippy/tests/ui/use_self_trait.stderr33
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.rs30
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.stderr48
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.fixed1
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.rs1
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.stderr24
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.fixed3
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.rs3
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.stderr7
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.fixed93
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.rs93
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.stderr90
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion_try.rs9
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion_try.stderr16
-rw-r--r--src/tools/clippy/tests/ui/vec.fixed2
-rw-r--r--src/tools/clippy/tests/ui/vec.rs2
-rw-r--r--src/tools/clippy/tests/ui/vec.stderr29
-rw-r--r--src/tools/clippy/tests/ui/vec_box_sized.fixed7
-rw-r--r--src/tools/clippy/tests/ui/vec_box_sized.rs7
-rw-r--r--src/tools/clippy/tests/ui/vec_box_sized.stderr13
-rw-r--r--src/tools/clippy/tests/ui/vec_init_then_push.rs11
-rw-r--r--src/tools/clippy/tests/ui/vec_init_then_push.stderr26
-rw-r--r--src/tools/clippy/tests/ui/vec_resize_to_zero.fixed20
-rw-r--r--src/tools/clippy/tests/ui/vec_resize_to_zero.rs1
-rw-r--r--src/tools/clippy/tests/ui/vec_resize_to_zero.stderr1
-rw-r--r--src/tools/clippy/tests/ui/verbose_file_reads.rs2
-rw-r--r--src/tools/clippy/tests/ui/verbose_file_reads.stderr3
-rw-r--r--src/tools/clippy/tests/ui/vtable_address_comparisons.rs8
-rw-r--r--src/tools/clippy/tests/ui/vtable_address_comparisons.stderr15
-rw-r--r--src/tools/clippy/tests/ui/while_let_loop.rs8
-rw-r--r--src/tools/clippy/tests/ui/while_let_loop.stderr22
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.fixed1
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.rs1
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.stderr53
-rw-r--r--src/tools/clippy/tests/ui/wild_in_or_pats.rs4
-rw-r--r--src/tools/clippy/tests/ui/wild_in_or_pats.stderr7
-rw-r--r--src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed1
-rw-r--r--src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs1
-rw-r--r--src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr14
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.fixed2
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.rs2
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.stderr1
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed2
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr1
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed2
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr1
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.rs2
-rw-r--r--src/tools/clippy/tests/ui/write_literal.fixed58
-rw-r--r--src/tools/clippy/tests/ui/write_literal.rs13
-rw-r--r--src/tools/clippy/tests/ui/write_literal.stderr23
-rw-r--r--src/tools/clippy/tests/ui/write_literal_2.rs29
-rw-r--r--src/tools/clippy/tests/ui/write_literal_2.stderr115
-rw-r--r--src/tools/clippy/tests/ui/write_with_newline.fixed27
-rw-r--r--src/tools/clippy/tests/ui/write_with_newline.rs25
-rw-r--r--src/tools/clippy/tests/ui/write_with_newline.stderr55
-rw-r--r--src/tools/clippy/tests/ui/writeln_empty_string.fixed2
-rw-r--r--src/tools/clippy/tests/ui/writeln_empty_string.rs2
-rw-r--r--src/tools/clippy/tests/ui/writeln_empty_string.stderr5
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention.rs24
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention.stderr47
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention2.rs2
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention2.stderr3
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_conventions_mut.rs2
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr3
-rw-r--r--src/tools/clippy/tests/ui/zero_div_zero.rs4
-rw-r--r--src/tools/clippy/tests/ui/zero_div_zero.stderr7
-rw-r--r--src/tools/clippy/tests/ui/zero_offset.rs9
-rw-r--r--src/tools/clippy/tests/ui/zero_offset.stderr14
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.fixed1
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.rs1
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.stderr11
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr_no_std.fixed2
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr_no_std.rs2
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr_no_std.stderr8
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs14
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr25
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs14
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr25
-rw-r--r--src/tools/compiletest/Cargo.toml1
-rw-r--r--src/tools/compiletest/src/common.rs32
-rw-r--r--src/tools/compiletest/src/header/needs.rs33
-rw-r--r--src/tools/compiletest/src/header/tests.rs234
-rw-r--r--src/tools/compiletest/src/lib.rs2
-rw-r--r--src/tools/compiletest/src/read2.rs63
-rw-r--r--src/tools/compiletest/src/read2/tests.rs50
-rw-r--r--src/tools/compiletest/src/runtest.rs179
-rw-r--r--src/tools/compiletest/src/util.rs97
-rw-r--r--src/tools/coverage-dump/Cargo.toml14
-rw-r--r--src/tools/coverage-dump/README.md8
-rw-r--r--src/tools/coverage-dump/src/covfun.rs296
-rw-r--r--src/tools/coverage-dump/src/main.rs17
-rw-r--r--src/tools/coverage-dump/src/parser.rs80
-rw-r--r--src/tools/coverage-dump/src/parser/tests.rs38
-rw-r--r--src/tools/coverage-dump/src/prf_names.rs87
-rw-r--r--src/tools/generate-windows-sys/Cargo.toml2
-rw-r--r--src/tools/generate-windows-sys/src/main.rs31
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs12
-rw-r--r--src/tools/jsondoclint/src/validator.rs10
-rw-r--r--src/tools/opt-dist/Cargo.toml2
-rw-r--r--src/tools/opt-dist/src/environment.rs108
-rw-r--r--src/tools/opt-dist/src/environment/linux.rs58
-rw-r--r--src/tools/opt-dist/src/environment/mod.rs77
-rw-r--r--src/tools/opt-dist/src/environment/windows.rs82
-rw-r--r--src/tools/opt-dist/src/exec.rs4
-rw-r--r--src/tools/opt-dist/src/main.rs227
-rw-r--r--src/tools/opt-dist/src/tests.rs16
-rw-r--r--src/tools/opt-dist/src/training.rs22
-rw-r--r--src/tools/opt-dist/src/utils/io.rs8
-rw-r--r--src/tools/opt-dist/src/utils/mod.rs23
-rw-r--r--src/tools/rust-analyzer/.cargo/config.toml2
-rw-r--r--src/tools/rust-analyzer/Cargo.lock118
-rw-r--r--src/tools/rust-analyzer/Cargo.toml9
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/fixture.rs14
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs6
-rw-r--r--src/tools/rust-analyzer/crates/cfg/src/lib.rs26
-rw-r--r--src/tools/rust-analyzer/crates/flycheck/src/lib.rs67
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/Cargo.toml6
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr.rs187
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs476
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs53
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs89
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs20
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/db.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/find_path.rs184
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/generics.rs85
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs502
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs11
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/import_map.rs78
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs477
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs53
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs91
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs13
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs44
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lower.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs78
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs61
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres.rs74
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs438
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs85
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs80
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs52
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs32
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/path.rs31
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs82
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/pretty.rs72
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs230
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/src.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs170
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/name.rs25
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/builder.rs13
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs53
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs36
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs67
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs42
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs15
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs101
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs132
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs27
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs48
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs13
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs121
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir.rs145
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs98
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs116
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs246
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs42
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs219
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs60
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs104
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs28
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/attrs.rs260
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs11
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs68
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs133
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs477
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/symbols.rs40
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs105
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs190
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs159
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs93
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs166
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs37
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs205
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs43
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs64
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs57
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs71
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs87
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs53
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs145
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/item.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs38
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs54
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs294
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/defs.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/documentation.rs281
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/helpers.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs44
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/rename.rs17
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/rust_doc.rs169
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt203
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs108
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs25
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs101
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/undeclared_label.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/annotations.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs63
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs47
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/extend_selection.rs29
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs54
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs17
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs23
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs127
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs33
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs32
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs38
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/navigation_target.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs29
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/signature_help.rs61
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/status.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html58
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs23
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/typing.rs248
-rw-r--r--src/tools/rust-analyzer/crates/intern/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/lib.rs6
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs88
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/lexed_str.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/shortcuts.rs13
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs19
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast6
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rast90
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rs5
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast15
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast17
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast9
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast105
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs5
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-test/build.rs4
-rw-r--r--src/tools/rust-analyzer/crates/profile/src/stop_watch.rs20
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs91
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/sysroot.rs11
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs100
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt8
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt8
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt8
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt44
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs12
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs20
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs37
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs42
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs11
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/dispatch.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs61
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs23
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs155
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs30
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs29
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs (renamed from src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs)4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs (renamed from src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs)4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs (renamed from src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs)0
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs (renamed from src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs)146
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs (renamed from src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs)4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs173
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/markdown.rs165
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs5
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs8
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram24
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs171
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs7
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs8
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs19
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs19
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs20
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/fixture.rs2
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/minicore.rs103
-rw-r--r--src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/vfs/src/lib.rs5
-rw-r--r--src/tools/rust-analyzer/docs/dev/architecture.md2
-rw-r--r--src/tools/rust-analyzer/docs/dev/lsp-extensions.md6
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc15
-rw-r--r--src/tools/rust-analyzer/lib/lsp-server/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs5
-rw-r--r--src/tools/rust-analyzer/xtask/src/flags.rs20
-rw-r--r--src/tools/rust-analyzer/xtask/src/metrics.rs65
-rw-r--r--src/tools/rustdoc-js/tester.js4
-rw-r--r--src/tools/rustdoc-themes/main.rs45
-rw-r--r--src/tools/rustfmt/src/expr.rs2
-rw-r--r--src/tools/rustfmt/src/parse/session.rs16
-rw-r--r--src/tools/rustfmt/src/types.rs2
-rw-r--r--src/tools/rustfmt/tests/target/anonymous-types.rs19
-rw-r--r--src/tools/tidy/src/deps.rs10
-rw-r--r--src/tools/tidy/src/error_codes.rs7
-rw-r--r--src/tools/tidy/src/lib.rs2
-rw-r--r--src/tools/tidy/src/main.rs2
-rw-r--r--src/tools/tidy/src/pal.rs1
-rw-r--r--src/tools/tidy/src/primitive_docs.rs17
-rw-r--r--src/tools/tidy/src/rustdoc_css_themes.rs99
-rw-r--r--src/tools/tidy/src/ui_tests.rs4
3013 files changed, 45694 insertions, 23007 deletions
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 778609da0..5153dd26f 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -69,7 +69,6 @@ static TARGETS: &[&str] = &[
"arm-unknown-linux-musleabihf",
"armv5te-unknown-linux-gnueabi",
"armv5te-unknown-linux-musleabi",
- "armv7-apple-ios",
"armv7-linux-androideabi",
"thumbv7neon-linux-androideabi",
"armv7-unknown-linux-gnueabi",
@@ -99,6 +98,8 @@ static TARGETS: &[&str] = &[
"i686-unknown-linux-musl",
"i686-unknown-uefi",
"loongarch64-unknown-linux-gnu",
+ "loongarch64-unknown-none",
+ "loongarch64-unknown-none-softfloat",
"m68k-unknown-linux-gnu",
"csky-unknown-linux-gnuabiv2",
"mips-unknown-linux-gnu",
diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs
index 66876e02c..f20b7a2b4 100644
--- a/src/tools/build_helper/src/git.rs
+++ b/src/tools/build_helper/src/git.rs
@@ -78,13 +78,22 @@ pub fn rev_exists(rev: &str, git_dir: Option<&Path>) -> Result<bool, String> {
/// We will then fall back to origin/master in the hope that at least this exists.
pub fn updated_master_branch(git_dir: Option<&Path>) -> Result<String, String> {
let upstream_remote = get_rust_lang_rust_remote(git_dir)?;
- let upstream_master = format!("{upstream_remote}/master");
- if rev_exists(&upstream_master, git_dir)? {
- return Ok(upstream_master);
+ for upstream_master in [format!("{upstream_remote}/master"), format!("origin/master")] {
+ if rev_exists(&upstream_master, git_dir)? {
+ return Ok(upstream_master);
+ }
}
- // We could implement smarter logic here in the future.
- Ok("origin/master".into())
+ Err(format!("Cannot find any suitable upstream master branch"))
+}
+
+pub fn get_git_merge_base(git_dir: Option<&Path>) -> Result<String, String> {
+ let updated_master = updated_master_branch(git_dir)?;
+ let mut git = Command::new("git");
+ if let Some(git_dir) = git_dir {
+ git.current_dir(git_dir);
+ }
+ Ok(output_result(git.arg("merge-base").arg(&updated_master).arg("HEAD"))?.trim().to_owned())
}
/// Returns the files that have been modified in the current branch compared to the master branch.
@@ -94,20 +103,13 @@ pub fn get_git_modified_files(
git_dir: Option<&Path>,
extensions: &Vec<&str>,
) -> Result<Option<Vec<String>>, String> {
- let Ok(updated_master) = updated_master_branch(git_dir) else {
- return Ok(None);
- };
-
- let git = || {
- let mut git = Command::new("git");
- if let Some(git_dir) = git_dir {
- git.current_dir(git_dir);
- }
- git
- };
+ let merge_base = get_git_merge_base(git_dir)?;
- let merge_base = output_result(git().arg("merge-base").arg(&updated_master).arg("HEAD"))?;
- let files = output_result(git().arg("diff-index").arg("--name-only").arg(merge_base.trim()))?
+ let mut git = Command::new("git");
+ if let Some(git_dir) = git_dir {
+ git.current_dir(git_dir);
+ }
+ let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))?
.lines()
.map(|s| s.trim().to_owned())
.filter(|f| {
diff --git a/src/tools/cargo/.github/renovate.json5 b/src/tools/cargo/.github/renovate.json5
index 8ad9952d2..b633fc245 100644
--- a/src/tools/cargo/.github/renovate.json5
+++ b/src/tools/cargo/.github/renovate.json5
@@ -8,7 +8,34 @@
ignorePaths: [
"**/tests/**",
],
+ customManagers: [
+ {
+ customType: 'regex',
+ fileMatch: [
+ '^Cargo.toml$',
+ ],
+ matchStrings: [
+ 'rust-version.*?(?<currentValue>\\d+\\.\\d+(\\.\\d+)?)',
+ ],
+ depNameTemplate: 'latest-msrv',
+ packageNameTemplate: 'rust-lang/rust',
+ datasourceTemplate: 'github-releases',
+ },
+ ],
packageRules: [
+ {
+ commitMessageTopic: 'Latest MSRV',
+ matchManagers: [
+ 'regex',
+ ],
+ matchPackageNames: [
+ 'latest-msrv',
+ ],
+ "extractVersion": "^(?<version>\\d+\\.\\d+)", // Drop the patch version
+ schedule: [
+ '* * * * *',
+ ],
+ },
// Goals:
// - Rollup safe upgrades to reduce CI runner load
// - Have lockfile and manifest in-sync (implicit rules)
diff --git a/src/tools/cargo/.github/workflows/main.yml b/src/tools/cargo/.github/workflows/main.yml
index 2e71f14b8..44dd76e13 100644
--- a/src/tools/cargo/.github/workflows/main.yml
+++ b/src/tools/cargo/.github/workflows/main.yml
@@ -20,6 +20,7 @@ jobs:
needs:
- build_std
- clippy
+ - credential_msrv
- docs
- lockfile
- resolver
@@ -37,6 +38,7 @@ jobs:
needs:
- build_std
- clippy
+ - credential_msrv
- docs
- lockfile
- resolver
@@ -176,7 +178,7 @@ jobs:
run: 'cargo test -p cargo --test testsuite -- fix::'
env:
__CARGO_TEST_FORCE_ARGFILE: 1
- - run: cargo test --workspace --exclude cargo --exclude benchsuite
+ - run: cargo test --workspace --exclude cargo --exclude benchsuite --exclude resolver-tests
- name: Check benchmarks
run: |
# This only tests one benchmark since it can take over 10 minutes to
@@ -246,3 +248,10 @@ jobs:
cd target
curl -sSLO https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh
sh linkcheck.sh --all --path ../src/doc cargo
+
+ credential_msrv:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - run: rustup update 1.70 && rustup default 1.70
+ - run: cargo test -p cargo-credential
diff --git a/src/tools/cargo/CHANGELOG.md b/src/tools/cargo/CHANGELOG.md
index 0141302c8..f2c9bd0eb 100644
--- a/src/tools/cargo/CHANGELOG.md
+++ b/src/tools/cargo/CHANGELOG.md
@@ -1,23 +1,110 @@
# Changelog
+## Cargo 1.74 (2023-11-16)
+[80eca0e5...HEAD](https://github.com/rust-lang/cargo/compare/80eca0e5...HEAD)
+
+### Added
+
+### Changed
+
+### Fixed
+
+### Nightly only
+
+### Documentation
+
+- ❗ Policy change: Checking `Cargo.lock` into version control is now the default choice,
+ even for libraries. Lockfile and CI integration documentations are also expanded.
+ [Policy docs](https://doc.rust-lang.org/nightly/cargo/faq.html#why-have-cargolock-in-version-control),
+ [Lockfile docs](https://doc.rust-lang.org/nightly/cargo/guide/cargo-toml-vs-cargo-lock.html),
+ [CI docs](https://doc.rust-lang.org/nightly/cargo/guide/continuous-integration.html),
+ [#12382](https://github.com/rust-lang/cargo/pull/12382)
+
## Cargo 1.73 (2023-10-05)
-[45782b6b...HEAD](https://github.com/rust-lang/cargo/compare/45782b6b...HEAD)
+[45782b6b...rust-1.73.0](https://github.com/rust-lang/cargo/compare/45782b6b...rust-1.73.0)
### Added
+- Print environment variables for `cargo run/bench/test` in extra verbose mode `-vv`.
+ [#12498](https://github.com/rust-lang/cargo/pull/12498)
+- Display package versions on Cargo timings graph.
+ [#12420](https://github.com/rust-lang/cargo/pull/12420)
+
### Changed
+- Cargo now bails out when using `cargo::` in custom build scripts. This is
+ a preparation for an upcoming change in build script invocations.
+ [#12332](https://github.com/rust-lang/cargo/pull/12332)
+- Make Cargo `--help` easier to browse.
+ [#11905](https://github.com/rust-lang/cargo/pull/11905)
+- Prompt the use of `--nocapture` flag if `cargo test` process is terminated via a signal.
+ [#12463](https://github.com/rust-lang/cargo/pull/12463)
+- Preserve jobserver file descriptors on the rustc invocation for getting target information.
+ [#12447](https://github.com/rust-lang/cargo/pull/12447)
+- Clarify in `--help` that `cargo test --all-targets` excludes doctests.
+ [#12422](https://github.com/rust-lang/cargo/pull/12422)
+- Normalize `cargo.toml` to `Cargo.toml` on publish, and warn on other cases of `Cargo.toml`.
+ [#12399](https://github.com/rust-lang/cargo/pull/12399)
+
### Fixed
+- Only skip mtime check on `~/.cargo/{git,registry}`.
+ [#12369](https://github.com/rust-lang/cargo/pull/12369)
+- Fixed `cargo doc --open` crash on WSL2.
+ [#12373](https://github.com/rust-lang/cargo/pull/12373)
+- Fixed panic when enabling `http.debug` for certain strings.
+ [#12468](https://github.com/rust-lang/cargo/pull/12468)
+- Fixed `cargo remove` incorrectly removing used patches.
+ [#12454](https://github.com/rust-lang/cargo/pull/12454)
+- Fixed crate checksum lookup query should match on semver build metadata.
+ [#11447](https://github.com/rust-lang/cargo/pull/11447)
+- Fixed printing multiple warning messages for unused fields in `[registries]` table.
+ [#12439](https://github.com/rust-lang/cargo/pull/12439)
+
### Nightly only
+- 🔥 The `-Zcredential-process` has been reimplemented with a clearer way to
+ communicate with different credential providers. Several built-in providers
+ are also added to Cargo.
+ [docs](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process)
+ [#12334](https://github.com/rust-lang/cargo/pull/12334)
+ [#12396](https://github.com/rust-lang/cargo/pull/12396)
+ [#12424](https://github.com/rust-lang/cargo/pull/12424)
+ [#12440](https://github.com/rust-lang/cargo/pull/12440)
+ [#12461](https://github.com/rust-lang/cargo/pull/12461)
+ [#12469](https://github.com/rust-lang/cargo/pull/12469)
+ [#12483](https://github.com/rust-lang/cargo/pull/12483)
+ [#12499](https://github.com/rust-lang/cargo/pull/12499)
+ [#12507](https://github.com/rust-lang/cargo/pull/12507)
+ [#12512](https://github.com/rust-lang/cargo/pull/12512)
+ [#12518](https://github.com/rust-lang/cargo/pull/12518)
+ [#12521](https://github.com/rust-lang/cargo/pull/12521)
+ [#12526](https://github.com/rust-lang/cargo/pull/12526)
+ Some notable changes:
+ - Renamed `credential-process` to `credential-provider` in Cargo configurations.
+ - New JSON protocol for communicating with external credential providers via stdin/stdout.
+ - The GNOME Secert provider now dynamically loads `libsecert`.
+ - The 1password provider is no longer built-in.
+ - Changed the unstable key for asymmetric tokens from `registry-auth` to `credential-process`.
+- ❗️ Removed `--keep-going` flag support from `cargo test` and `cargo bench`.
+ [#12478](https://github.com/rust-lang/cargo/pull/12478)
+ [#12492](https://github.com/rust-lang/cargo/pull/12492)
- Fixed invalid package names generated by `-Zscript`.
[#12349](https://github.com/rust-lang/cargo/pull/12349)
- `-Zscript` now errors out on unsupported commands — `publish` and `package`.
[#12350](https://github.com/rust-lang/cargo/pull/12350)
+- Encode URL params correctly for source ID in Cargo.lock.
+ [#12280](https://github.com/rust-lang/cargo/pull/12280)
+- Replaced invalid `panic_unwind` std feature with `panic-unwind`.
+ [#12364](https://github.com/rust-lang/cargo/pull/12364)
+- `-Zlints`: doctest extraction should respect `[lints]`.
+ [#12501](https://github.com/rust-lang/cargo/pull/12501)
### Documentation
+- SemVer: Adding a section for changing the alignment, layout, or size of a
+ well-defined type.
+ [#12169](https://github.com/rust-lang/cargo/pull/12169)
- Use heading attributes to control the fragment.
[#12339](https://github.com/rust-lang/cargo/pull/12339)
- Use "number" instead of "digit" when explaining Cargo's use of semver.
@@ -26,19 +113,66 @@
[#12344](https://github.com/rust-lang/cargo/pull/12344)
- Clarify "Package ID" and "Source ID" in `cargo metadata` are opaque strings.
[#12313](https://github.com/rust-lang/cargo/pull/12313)
-- Added `profile.strip` to configuration docs.
- [#12337](https://github.com/rust-lang/cargo/pull/12337)
-- Multiple versions that differ only in the metadata tag are disallowed on crates.io.
+- Clarify that `rerun-if-env-changed` doesn't monitor the environment variables
+ it set for crates and build script.
+ [#12482](https://github.com/rust-lang/cargo/pull/12482)
+- Clarify that multiple versions that differ only in the metadata tag are
+ disallowed on crates.io.
[#12335](https://github.com/rust-lang/cargo/pull/12335)
+- Clarify `lto` setting passing `-Clinker-plugin-lto`.
+ [#12407](https://github.com/rust-lang/cargo/pull/12407)
+- Added `profile.strip` to configuration and environment variable docs.
+ [#12337](https://github.com/rust-lang/cargo/pull/12337)
+ [#12408](https://github.com/rust-lang/cargo/pull/12408)
+- Added docs for artifact JSON debuginfo levels.
+ [#12376](https://github.com/rust-lang/cargo/pull/12376)
+- Added a notice for the backward compatible `.cargo/credential` file existence.
+ [#12479](https://github.com/rust-lang/cargo/pull/12479)
+- Raised the awareness of `resolver = 2` used inside workspaces.
+ [#12388](https://github.com/rust-lang/cargo/pull/12388)
+- Replaced `master` branch by default branch in documentation.
+ [#12435](https://github.com/rust-lang/cargo/pull/12435)
### Internal
- Updated to `criterion` 0.5.1.
[#12338](https://github.com/rust-lang/cargo/pull/12338)
+- Updated to `curl-sys` 0.4.65, which corresponds to curl 8.2.1.
+ [#12406](https://github.com/rust-lang/cargo/pull/12406)
+- Updated to `indexmap` v2.
+ [#12368](https://github.com/rust-lang/cargo/pull/12368)
+- Updated to `miow` 0.6.0, which drops old versions of `windows-sys`.
+ [#12453](https://github.com/rust-lang/cargo/pull/12453)
- ci: automatically test new packages by using `--workspace`.
[#12342](https://github.com/rust-lang/cargo/pull/12342)
- ci: automatically update dependencies monthly with Renovate.
[#12341](https://github.com/rust-lang/cargo/pull/12341)
+ [#12466](https://github.com/rust-lang/cargo/pull/12466)
+- ci: rewrote `xtask-bump-check` for respecting semver by adopting `cargo-semver-checks`.
+ [#12395](https://github.com/rust-lang/cargo/pull/12395)
+ [#12513](https://github.com/rust-lang/cargo/pull/12513)
+ [#12508](https://github.com/rust-lang/cargo/pull/12508)
+- Rearranged and renamed test directories
+ [#12397](https://github.com/rust-lang/cargo/pull/12397)
+ [#12398](https://github.com/rust-lang/cargo/pull/12398)
+- Migrated from `log` to `tracing`.
+ [#12458](https://github.com/rust-lang/cargo/pull/12458)
+ [#12488](https://github.com/rust-lang/cargo/pull/12488)
+- Track `--help` output in tests.
+ [#11912](https://github.com/rust-lang/cargo/pull/11912)
+- Cleaned up and shared package metadata within workspace.
+ [#12352](https://github.com/rust-lang/cargo/pull/12352)
+- `crates-io`: expose HTTP headers and `Error` type.
+ [#12310](https://github.com/rust-lang/cargo/pull/12310)
+- For `cargo update`, caught CLI flags conflict between `--aggressive` and `--precise` in clap.
+ [#12428](https://github.com/rust-lang/cargo/pull/12428)
+- Several fixes for either making Cargo testsuite pass on nightly or in `rust-lang/rust`.
+ [#12413](https://github.com/rust-lang/cargo/pull/12413)
+ [#12416](https://github.com/rust-lang/cargo/pull/12416)
+ [#12429](https://github.com/rust-lang/cargo/pull/12429)
+ [#12450](https://github.com/rust-lang/cargo/pull/12450)
+ [#12491](https://github.com/rust-lang/cargo/pull/12491)
+ [#12500](https://github.com/rust-lang/cargo/pull/12500)
## Cargo 1.72 (2023-08-24)
[64fb38c9...rust-1.72.0](https://github.com/rust-lang/cargo/compare/64fb38c9...rust-1.72.0)
@@ -57,10 +191,11 @@
### Changed
-- ❗ Turned feature name validation check to a hard error. The warning was
- added in Rust 1.49. These extended characters aren't allowed on crates.io, so
- this should only impact users of other registries, or people who don't publish
- to a registry.
+- 🚨 [CVE-2023-40030](https://github.com/rust-lang/cargo/security/advisories/GHSA-wrrj-h57r-vx9p):
+ Malicious dependencies can inject arbitrary JavaScript into cargo-generated timing reports.
+ To mitigate this, feature name validation check is now turned into a hard error.
+ The warning was added in Rust 1.49. These extended characters aren't allowed on crates.io,
+ so this should only impact users of other registries, or people who don't publish to a registry.
[#12291](https://github.com/rust-lang/cargo/pull/12291)
- Cargo now warns when an edition 2021 package is in a virtual workspace and
`workspace.resolver` is not set. It is recommended to set the resolver
@@ -75,6 +210,9 @@
[#12231](https://github.com/rust-lang/cargo/pull/12231)
- Added a message when `rustup` override shorthand is put in a wrong position.
[#12226](https://github.com/rust-lang/cargo/pull/12226)
+- Respect scp-like URL as much as possible when fetching nested submodules.
+ [#12359](https://github.com/rust-lang/cargo/pull/12359)
+ [#12411](https://github.com/rust-lang/cargo/pull/12411)
### Fixed
@@ -184,6 +322,14 @@
- Show a better error when container tests fail.
[#12264](https://github.com/rust-lang/cargo/pull/12264)
+## Cargo 1.71.1 (2023-08-03)
+
+### Fixed
+
+- 🚨 [CVE-2023-38497](https://github.com/rust-lang/cargo/security/advisories/GHSA-j3xp-wfr4-hx87):
+ Cargo 1.71.1 or later respects umask when extracting crate archives. It also
+ purges the caches it tries to access if they were generated by older Cargo versions.
+
## Cargo 1.71 (2023-07-13)
[84b7041f...rust-1.71.0](https://github.com/rust-lang/cargo/compare/84b7041f...rust-1.71.0)
@@ -283,7 +429,7 @@
[#10877](https://github.com/rust-lang/cargo/pull/10877)
- SemVer: It is not a breaking change to make an unsafe function safe.
[#12116](https://github.com/rust-lang/cargo/pull/12116)
-- SemVer: changeing MSRV is generally a minor change.
+- SemVer: changing MSRV is generally a minor change.
[#12122](https://github.com/rust-lang/cargo/pull/12122)
- Clarify when and how to `cargo yank`.
[#11862](https://github.com/rust-lang/cargo/pull/11862)
@@ -582,9 +728,9 @@
- Clarified the difference between `CARGO_CRATE_NAME` and `CARGO_PKG_NAME`.
[#11576](https://github.com/rust-lang/cargo/pull/11576)
-- Added links to the Target section of the glossary for occurences of target triple.
+- Added links to the Target section of the glossary for occurrences of target triple.
[#11603](https://github.com/rust-lang/cargo/pull/11603)
-- Described how the current resolver sometimes duplicates depenencies.
+- Described how the current resolver sometimes duplicates dependencies.
[#11604](https://github.com/rust-lang/cargo/pull/11604)
- Added a note about verifying your email address on crates.io.
[#11620](https://github.com/rust-lang/cargo/pull/11620)
@@ -743,7 +889,7 @@
### Nightly only
-- Implemented a inital support of asymmetric token authentication for registries.
+- Implemented a initial support of asymmetric token authentication for registries.
([RFC 3231](https://github.com/rust-lang/rfcs/blob/master/text/3231-cargo-asymmetric-tokens.md))
([docs](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#registry-auth))
[#10771](https://github.com/rust-lang/cargo/pull/10771)
@@ -859,7 +1005,7 @@
## Cargo 1.66.1 (2023-01-10)
### Fixed
-- [CVE-2022-46176](https://github.com/rust-lang/cargo/security/advisories/GHSA-r5w3-xm58-jv6j):
+- 🚨 [CVE-2022-46176](https://github.com/rust-lang/cargo/security/advisories/GHSA-r5w3-xm58-jv6j):
Added validation of SSH host keys for git URLs.
See [the docs](https://doc.rust-lang.org/cargo/appendix/git-authentication.html#ssh-known-hosts) for more information on how to configure the known host keys.
@@ -1085,11 +1231,11 @@
### Fixed
-- [CVE-2022-36113](https://github.com/rust-lang/cargo/security/advisories/GHSA-rfj2-q3h3-hm5j):
+- 🚨 [CVE-2022-36113](https://github.com/rust-lang/cargo/security/advisories/GHSA-rfj2-q3h3-hm5j):
Extracting malicious crates can corrupt arbitrary files.
[#11089](https://github.com/rust-lang/cargo/pull/11089)
[#11088](https://github.com/rust-lang/cargo/pull/11088)
-- [CVE-2022-36114](https://github.com/rust-lang/cargo/security/advisories/GHSA-2hvr-h6gw-qrxp):
+- 🚨 [CVE-2022-36114](https://github.com/rust-lang/cargo/security/advisories/GHSA-2hvr-h6gw-qrxp):
Extracting malicious crates can fill the file system.
[#11089](https://github.com/rust-lang/cargo/pull/11089)
[#11088](https://github.com/rust-lang/cargo/pull/11088)
diff --git a/src/tools/cargo/Cargo.lock b/src/tools/cargo/Cargo.lock
index 371504138..cc0cb9a88 100644
--- a/src/tools/cargo/Cargo.lock
+++ b/src/tools/cargo/Cargo.lock
@@ -9,27 +9,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
-name = "ahash"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
-dependencies = [
- "cfg-if",
- "getrandom",
- "once_cell",
- "version_check",
-]
-
-[[package]]
-name = "aho-corasick"
-version = "0.7.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
-dependencies = [
- "memchr",
-]
-
-[[package]]
name = "aho-corasick"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -46,24 +25,23 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstream"
-version = "0.3.2"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
+checksum = "83d7b3983a025adeb201ef26a5564ebd1641ea9851f6282aee4940f745a3c07c"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
- "is-terminal",
"utf8parse",
]
[[package]]
name = "anstyle"
-version = "1.0.0"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d"
+checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
[[package]]
name = "anstyle-parse"
@@ -85,9 +63,9 @@ dependencies = [
[[package]]
name = "anstyle-wincon"
-version = "1.0.1"
+version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
+checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
dependencies = [
"anstyle",
"windows-sys",
@@ -95,9 +73,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.72"
+version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
+checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "arc-swap"
@@ -106,12 +84,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
[[package]]
-name = "arrayvec"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
-
-[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -125,9 +97,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]]
name = "base64"
-version = "0.21.2"
+version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
+checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
[[package]]
name = "base64ct"
@@ -193,13 +165,12 @@ dependencies = [
[[package]]
name = "bstr"
-version = "1.5.0"
+version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5"
+checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a"
dependencies = [
"memchr",
- "once_cell",
- "regex-automata",
+ "regex-automata 0.3.8",
"serde",
]
@@ -232,9 +203,15 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "bytesize"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38fcc2979eff34a4b84e1cf9a1e3da42a7d44b3b690a40cdcb23e3d556cfb2e5"
+checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc"
+
+[[package]]
+name = "byteyarn"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7534301c0ea17abb4db06d75efc7b4b0fa360fce8e175a4330d721c71c942ff"
[[package]]
name = "camino"
@@ -257,8 +234,10 @@ dependencies = [
[[package]]
name = "cargo"
-version = "0.74.0"
+version = "0.75.0"
dependencies = [
+ "anstream",
+ "anstyle",
"anyhow",
"base64",
"bytesize",
@@ -266,17 +245,17 @@ dependencies = [
"cargo-credential-libsecret",
"cargo-credential-macos-keychain",
"cargo-credential-wincred",
- "cargo-platform 0.1.4",
+ "cargo-platform 0.1.5",
"cargo-test-macro",
"cargo-test-support",
"cargo-util",
"clap",
+ "color-print",
"crates-io",
"curl",
"curl-sys",
"filetime",
"flate2",
- "fwdansi",
"git2",
"git2-curl",
"gix",
@@ -307,17 +286,16 @@ dependencies = [
"same-file",
"semver",
"serde",
+ "serde-untagged",
"serde-value",
"serde_ignored",
"serde_json",
"sha1",
"shell-escape",
"snapbox",
- "strip-ansi-escapes",
- "syn 2.0.28",
+ "syn 2.0.29",
"tar",
"tempfile",
- "termcolor",
"time",
"toml",
"toml_edit",
@@ -333,7 +311,7 @@ dependencies = [
[[package]]
name = "cargo-credential"
-version = "0.3.0"
+version = "0.4.0"
dependencies = [
"anyhow",
"libc",
@@ -347,7 +325,7 @@ dependencies = [
[[package]]
name = "cargo-credential-1password"
-version = "0.3.0"
+version = "0.4.0"
dependencies = [
"cargo-credential",
"serde",
@@ -356,7 +334,7 @@ dependencies = [
[[package]]
name = "cargo-credential-libsecret"
-version = "0.3.1"
+version = "0.3.2"
dependencies = [
"anyhow",
"cargo-credential",
@@ -365,7 +343,7 @@ dependencies = [
[[package]]
name = "cargo-credential-macos-keychain"
-version = "0.3.0"
+version = "0.3.1"
dependencies = [
"cargo-credential",
"security-framework",
@@ -373,7 +351,7 @@ dependencies = [
[[package]]
name = "cargo-credential-wincred"
-version = "0.3.0"
+version = "0.3.1"
dependencies = [
"cargo-credential",
"windows-sys",
@@ -390,7 +368,7 @@ dependencies = [
[[package]]
name = "cargo-platform"
-version = "0.1.4"
+version = "0.1.5"
dependencies = [
"serde",
]
@@ -403,6 +381,8 @@ version = "0.1.0"
name = "cargo-test-support"
version = "0.1.0"
dependencies = [
+ "anstream",
+ "anstyle",
"anyhow",
"cargo-test-macro",
"cargo-util",
@@ -412,13 +392,11 @@ dependencies = [
"git2",
"glob",
"itertools",
- "lazy_static",
"pasetors",
"serde",
"serde_json",
"snapbox",
"tar",
- "termcolor",
"time",
"toml",
"url",
@@ -427,7 +405,7 @@ dependencies = [
[[package]]
name = "cargo-util"
-version = "0.2.6"
+version = "0.2.7"
dependencies = [
"anyhow",
"core-foundation",
@@ -447,15 +425,16 @@ dependencies = [
[[package]]
name = "cargo_metadata"
-version = "0.14.2"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
+checksum = "e7daec1a2a2129eeba1644b220b4647ec537b0b5d4bfd6876fcc5a540056b592"
dependencies = [
"camino",
"cargo-platform 0.1.2",
"semver",
"serde",
"serde_json",
+ "thiserror",
]
[[package]]
@@ -508,18 +487,18 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.3.19"
+version = "4.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d"
+checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
-version = "4.3.19"
+version = "4.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
+checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
dependencies = [
"anstream",
"anstyle",
@@ -541,6 +520,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807"
[[package]]
+name = "color-print"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2a5e6504ed8648554968650feecea00557a3476bc040d0ffc33080e66b646d0"
+dependencies = [
+ "color-print-proc-macro",
+]
+
+[[package]]
+name = "color-print-proc-macro"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d51beaa537d73d2d1ff34ee70bc095f170420ab2ec5d687ecd3ec2b0d092514b"
+dependencies = [
+ "nom",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -588,7 +588,7 @@ dependencies = [
[[package]]
name = "crates-io"
-version = "0.38.0"
+version = "0.39.0"
dependencies = [
"curl",
"percent-encoding",
@@ -731,9 +731,9 @@ dependencies = [
[[package]]
name = "curl-sys"
-version = "0.4.65+curl-8.2.1"
+version = "0.4.68+curl-8.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986"
+checksum = "b4a0d18d88360e374b16b2273c832b5e57258ffc1d4aa4f96b108e0738d5752f"
dependencies = [
"cc",
"libc",
@@ -742,7 +742,7 @@ dependencies = [
"openssl-sys",
"pkg-config",
"vcpkg",
- "winapi",
+ "windows-sys",
]
[[package]]
@@ -757,6 +757,15 @@ dependencies = [
]
[[package]]
+name = "deranged"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
+dependencies = [
+ "serde",
+]
+
+[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -831,12 +840,30 @@ dependencies = [
]
[[package]]
+name = "encoding_rs"
+version = "0.8.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
+name = "erased-serde"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c"
+dependencies = [
+ "serde",
+]
+
+[[package]]
name = "errno"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -870,12 +897,12 @@ dependencies = [
]
[[package]]
-name = "fastrand"
-version = "1.9.0"
+name = "faster-hex"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+checksum = "239f7bfb930f820ab16a9cd95afc26f88264cf6905c960b340a615384aa3338a"
dependencies = [
- "instant",
+ "serde",
]
[[package]]
@@ -902,21 +929,21 @@ checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77"
[[package]]
name = "filetime"
-version = "0.2.21"
+version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
+checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.2.16",
+ "redox_syscall",
"windows-sys",
]
[[package]]
name = "flate2"
-version = "1.0.26"
+version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
+checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
dependencies = [
"crc32fast",
"libz-sys",
@@ -954,16 +981,6 @@ dependencies = [
]
[[package]]
-name = "fwdansi"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c1f5787fe85505d1f7777268db5103d80a7a374d2316a7ce262e57baf8f208"
-dependencies = [
- "memchr",
- "termcolor",
-]
-
-[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -989,11 +1006,11 @@ dependencies = [
[[package]]
name = "git2"
-version = "0.17.2"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044"
+checksum = "12ef350ba88a33b4d524b1d1c79096c9ade5ef8c59395df0e60d1e1889414c0e"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.3.3",
"libc",
"libgit2-sys",
"log",
@@ -1004,9 +1021,9 @@ dependencies = [
[[package]]
name = "git2-curl"
-version = "0.18.0"
+version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8f8b7432b72928cff76f69e59ed5327f94a52763731e71274960dee72fe5f8c"
+checksum = "78e26b61608c573ffd26fc79061a823aa5147449a1afe1f61679a21e2031f7c3"
dependencies = [
"curl",
"git2",
@@ -1016,9 +1033,9 @@ dependencies = [
[[package]]
name = "gix"
-version = "0.45.1"
+version = "0.54.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf2a03ec66ee24d1b2bae3ab718f8d14f141613810cb7ff6756f7db667f1cd82"
+checksum = "ad6d32e74454459690d57d18ea4ebec1629936e6b130b51d12cb4a81630ac953"
dependencies = [
"gix-actor",
"gix-attributes",
@@ -1029,6 +1046,7 @@ dependencies = [
"gix-diff",
"gix-discover",
"gix-features",
+ "gix-filter",
"gix-fs",
"gix-glob",
"gix-hash",
@@ -1036,29 +1054,32 @@ dependencies = [
"gix-ignore",
"gix-index",
"gix-lock",
- "gix-mailmap",
+ "gix-macros",
"gix-negotiate",
"gix-object",
"gix-odb",
"gix-pack",
"gix-path",
+ "gix-pathspec",
"gix-prompt",
"gix-protocol",
"gix-ref",
"gix-refspec",
"gix-revision",
+ "gix-revwalk",
"gix-sec",
+ "gix-submodule",
"gix-tempfile",
+ "gix-trace",
"gix-transport",
"gix-traverse",
"gix-url",
"gix-utils",
"gix-validate",
"gix-worktree",
- "log",
"once_cell",
+ "parking_lot",
"prodash",
- "signal-hook",
"smallvec",
"thiserror",
"unicode-normalization",
@@ -1066,30 +1087,30 @@ dependencies = [
[[package]]
name = "gix-actor"
-version = "0.21.0"
+version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fe73f9f6be1afbf1bd5be919a9636fa560e2f14d42262a934423ed6760cd838"
+checksum = "08c60e982c5290897122d4e2622447f014a2dadd5a18cb73d50bb91b31645e27"
dependencies = [
"bstr",
"btoi",
"gix-date",
"itoa 1.0.6",
- "nom",
"thiserror",
+ "winnow",
]
[[package]]
name = "gix-attributes"
-version = "0.13.1"
+version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b79590ac382f80d87e06416f5fcac6fee5d83dcb152a00ed0bdbaa988acc31"
+checksum = "2451665e70709ba4753b623ef97511ee98c4a73816b2c5b5df25678d607ed820"
dependencies = [
"bstr",
+ "byteyarn",
"gix-glob",
"gix-path",
"gix-quote",
- "kstring",
- "log",
+ "gix-trace",
"smallvec",
"thiserror",
"unicode-bom",
@@ -1097,36 +1118,36 @@ dependencies = [
[[package]]
name = "gix-bitmap"
-version = "0.2.4"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc02feb20ad313d52a450852f2005c2205d24f851e74d82b7807cbe12c371667"
+checksum = "0ccab4bc576844ddb51b78d81b4a42d73e6229660fa614dfc3d3999c874d1959"
dependencies = [
"thiserror",
]
[[package]]
name = "gix-chunk"
-version = "0.4.2"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7acf3bc6c4b91e8fb260086daf5e105ea3a6d913f5fd3318137f7e309d6e540"
+checksum = "5b42ea64420f7994000130328f3c7a2038f639120518870436d31b8bde704493"
dependencies = [
"thiserror",
]
[[package]]
name = "gix-command"
-version = "0.2.5"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f6141b70cfb21255223e42f3379855037cbbe8673b58dd8318d2f09b516fad1"
+checksum = "0f28f654184b5f725c5737c7e4f466cbd8f0102ac352d5257eeab19647ee4256"
dependencies = [
"bstr",
]
[[package]]
name = "gix-commitgraph"
-version = "0.16.0"
+version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8490ae1b3d55c47e6a71d247c082304a2f79f8d0332c1a2f5693d42a2021a09"
+checksum = "e75a975ee22cf0a002bfe9b5d5cb3d2a88e263a8a178cd7509133cff10f4df8a"
dependencies = [
"bstr",
"gix-chunk",
@@ -1138,9 +1159,9 @@ dependencies = [
[[package]]
name = "gix-config"
-version = "0.23.0"
+version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51f310120ae1ba8f0ca52fb22876ce9bad5b15c8ffb3eb7302e4b64a3b9f681c"
+checksum = "c171514b40487d3f677ae37efc0f45ac980e3169f23c27eb30a70b47fdf88ab5"
dependencies = [
"bstr",
"gix-config-value",
@@ -1149,20 +1170,19 @@ dependencies = [
"gix-path",
"gix-ref",
"gix-sec",
- "log",
"memchr",
- "nom",
"once_cell",
"smallvec",
"thiserror",
"unicode-bom",
+ "winnow",
]
[[package]]
name = "gix-config-value"
-version = "0.12.1"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f216df1c33e6e1555923eff0096858a879e8aaadd35b5d788641e4e8064c892"
+checksum = "ea7505b97f4d8e7933e29735a568ba2f86d8de466669d9f0e8321384f9972f47"
dependencies = [
"bitflags 2.3.3",
"bstr",
@@ -1173,9 +1193,9 @@ dependencies = [
[[package]]
name = "gix-credentials"
-version = "0.15.0"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6f89fea8acd28f5ef8fa5042146f1637afd4d834bc8f13439d8fd1e5aca0d65"
+checksum = "46900b884cc5af6a6c141ee741607c0c651a4e1d33614b8d888a1ba81cc0bc8a"
dependencies = [
"bstr",
"gix-command",
@@ -1189,9 +1209,9 @@ dependencies = [
[[package]]
name = "gix-date"
-version = "0.5.1"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc164145670e9130a60a21670d9b6f0f4f8de04e5dd256c51fa5a0340c625902"
+checksum = "fc7df669639582dc7c02737642f76890b03b5544e141caba68a7d6b4eb551e0d"
dependencies = [
"bstr",
"itoa 1.0.6",
@@ -1201,21 +1221,20 @@ dependencies = [
[[package]]
name = "gix-diff"
-version = "0.30.1"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9029ad0083cc286a4bd2f5b3bf66bb66398abc26f2731a2824cd5edfc41a0e33"
+checksum = "788ddb152c388206e81f36bcbb574e7ed7827c27d8fa62227b34edc333d8928c"
dependencies = [
"gix-hash",
"gix-object",
- "imara-diff",
"thiserror",
]
[[package]]
name = "gix-discover"
-version = "0.19.0"
+version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aba9c6c0d1f2b2efe65581de73de4305004612d49c83773e783202a7ef204f46"
+checksum = "69507643d75a0ea9a402fcf73ced517d2b95cc95385904ac09d03e0b952fde33"
dependencies = [
"bstr",
"dunce",
@@ -1228,15 +1247,16 @@ dependencies = [
[[package]]
name = "gix-features"
-version = "0.30.0"
+version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a8c493409bf6060d408eec9bbdd1b12ea351266b50012e2a522f75dfc7b8314"
+checksum = "9b9ff423ae4983f762659040d13dd7a5defbd54b6a04ac3cc7347741cec828cd"
dependencies = [
"bytes",
"crc32fast",
"crossbeam-channel",
"flate2",
"gix-hash",
+ "gix-trace",
"libc",
"once_cell",
"parking_lot",
@@ -1247,19 +1267,39 @@ dependencies = [
]
[[package]]
+name = "gix-filter"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1be40d28cd41445bb6cd52c4d847d915900e5466f7433eaee6a9e0a3d1d88b08"
+dependencies = [
+ "bstr",
+ "encoding_rs",
+ "gix-attributes",
+ "gix-command",
+ "gix-hash",
+ "gix-object",
+ "gix-packetline-blocking",
+ "gix-path",
+ "gix-quote",
+ "gix-trace",
+ "smallvec",
+ "thiserror",
+]
+
+[[package]]
name = "gix-fs"
-version = "0.2.0"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30da8997008adb87f94e15beb7ee229f8a48e97af585a584bfee4a5a1880aab5"
+checksum = "09815faba62fe9b32d918b75a554686c98e43f7d48c43a80df58eb718e5c6635"
dependencies = [
"gix-features",
]
[[package]]
name = "gix-glob"
-version = "0.8.0"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd0ade1e80ab1f079703d1824e1daf73009096386aa7fd2f0477f6e4ac0a558e"
+checksum = "a9d76e85f11251dcf751d2c5e918a14f562db5be6f727fd24775245653e9b19d"
dependencies = [
"bitflags 2.3.3",
"bstr",
@@ -1269,30 +1309,30 @@ dependencies = [
[[package]]
name = "gix-hash"
-version = "0.11.3"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0dd58cdbe7ffa4032fc111864c80d5f8cecd9a2c9736c97ae7e5be834188272"
+checksum = "2ccf425543779cddaa4a7c62aba3fa9d90ea135b160be0a72dd93c063121ad4a"
dependencies = [
- "hex",
+ "faster-hex",
"thiserror",
]
[[package]]
name = "gix-hashtable"
-version = "0.2.3"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e133bc56d938eaec1c675af7c681a51de9662b0ada779f45607b967a10da77a"
+checksum = "409268480841ad008e81c17ca5a293393fbf9f2b6c2f85b8ab9de1f0c5176a16"
dependencies = [
"gix-hash",
- "hashbrown 0.14.0",
+ "hashbrown",
"parking_lot",
]
[[package]]
name = "gix-ignore"
-version = "0.3.0"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc6f7f101a0ccce808dbf7008ba131dede94e20257e7bde7a44cbb2f8c775625"
+checksum = "b048f443a1f6b02da4205c34d2e287e3fd45d75e8e2f06cfb216630ea9bff5e3"
dependencies = [
"bstr",
"gix-glob",
@@ -1302,9 +1342,9 @@ dependencies = [
[[package]]
name = "gix-index"
-version = "0.17.0"
+version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "616ba958fabfb11263fa042c35690d48a6c7be4e9277e2c7e24ff263b3fe7b82"
+checksum = "f54d63a9d13c13088f41f5a3accbec284e492ac8f4f707fcc307c139622e17b7"
dependencies = [
"bitflags 2.3.3",
"bstr",
@@ -1312,6 +1352,7 @@ dependencies = [
"filetime",
"gix-bitmap",
"gix-features",
+ "gix-fs",
"gix-hash",
"gix-lock",
"gix-object",
@@ -1324,9 +1365,9 @@ dependencies = [
[[package]]
name = "gix-lock"
-version = "6.0.0"
+version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ec5d5e6f07316d3553aa7425e3ecd935ec29882556021fe1696297a448af8d2"
+checksum = "47fc96fa8b6b6d33555021907c81eb3b27635daecf6e630630bdad44f8feaa95"
dependencies = [
"gix-tempfile",
"gix-utils",
@@ -1334,57 +1375,59 @@ dependencies = [
]
[[package]]
-name = "gix-mailmap"
-version = "0.13.0"
+name = "gix-macros"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4653701922c920e009f1bc4309feaff14882ade017770788f9a150928da3fa6a"
+checksum = "9d8acb5ee668d55f0f2d19a320a3f9ef67a6999ad483e11135abcc2464ed18b6"
dependencies = [
- "bstr",
- "gix-actor",
- "thiserror",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.29",
]
[[package]]
name = "gix-negotiate"
-version = "0.2.1"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "945c3ef1e912e44a5f405fc9e924edf42000566a1b257ed52cb1293300f6f08c"
+checksum = "6f1697bf9911c6d1b8d709b9e6ef718cb5ea5821a1b7991520125a8134448004"
dependencies = [
"bitflags 2.3.3",
"gix-commitgraph",
+ "gix-date",
"gix-hash",
"gix-object",
- "gix-revision",
+ "gix-revwalk",
"smallvec",
"thiserror",
]
[[package]]
name = "gix-object"
-version = "0.30.0"
+version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8926c8f51c44dec3e709cb5dbc93deb9e8d4064c43c9efc54c158dcdfe8446c7"
+checksum = "1e7e19616c67967374137bae83e950e9b518a9ea8a605069bd6716ada357fd6f"
dependencies = [
"bstr",
"btoi",
"gix-actor",
+ "gix-date",
"gix-features",
"gix-hash",
"gix-validate",
- "hex",
"itoa 1.0.6",
- "nom",
"smallvec",
"thiserror",
+ "winnow",
]
[[package]]
name = "gix-odb"
-version = "0.46.0"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b234d806278eeac2f907c8b5a105c4ba537230c1a9d9236d822bf0db291f8f3"
+checksum = "8d6a392c6ba3a2f133cdc63120e9bc7aec81eef763db372c817de31febfe64bf"
dependencies = [
"arc-swap",
+ "gix-date",
"gix-features",
"gix-hash",
"gix-object",
@@ -1398,20 +1441,18 @@ dependencies = [
[[package]]
name = "gix-pack"
-version = "0.36.0"
+version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d2a14cb3156037eedb17d6cb7209b7180522b8949b21fd0fe3184c0a1d0af88"
+checksum = "7536203a45b31e1bc5694bbf90ba8da1b736c77040dd6a520db369f371eb1ab3"
dependencies = [
"clru",
"gix-chunk",
- "gix-diff",
"gix-features",
"gix-hash",
"gix-hashtable",
"gix-object",
"gix-path",
"gix-tempfile",
- "gix-traverse",
"memmap2",
"parking_lot",
"smallvec",
@@ -1420,62 +1461,90 @@ dependencies = [
[[package]]
name = "gix-packetline"
-version = "0.16.2"
+version = "0.16.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74414f89a6b72fa1a530ce8e646faf1a05499c3f4a5c15441d17ae8c978578eb"
+checksum = "d6df0b75361353e7c0a6d72d49617a37379a7a22cba4569ae33a7720a4c8755a"
dependencies = [
"bstr",
- "hex",
+ "faster-hex",
+ "thiserror",
+]
+
+[[package]]
+name = "gix-packetline-blocking"
+version = "0.16.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d8395f7501c84d6a1fe902035fdfd8cd86d89e2dd6be0200ec1a72fd3c92d39"
+dependencies = [
+ "bstr",
+ "faster-hex",
"thiserror",
]
[[package]]
name = "gix-path"
-version = "0.8.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1226f2e50adeb4d76c754c1856c06f13a24cad1624801653fbf09b869e5b808"
+checksum = "6a1d370115171e3ae03c5c6d4f7d096f2981a40ddccb98dfd704c773530ba73b"
dependencies = [
"bstr",
+ "gix-trace",
"home 0.5.5",
"once_cell",
"thiserror",
]
[[package]]
+name = "gix-pathspec"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3e26c9b47c51be73f98d38c84494bd5fb99334c5d6fda14ef5d036d50a9e5fd"
+dependencies = [
+ "bitflags 2.3.3",
+ "bstr",
+ "gix-attributes",
+ "gix-config-value",
+ "gix-glob",
+ "gix-path",
+ "thiserror",
+]
+
+[[package]]
name = "gix-prompt"
-version = "0.5.1"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e15fe57fa48572b7d3bf465d6a2a0351cd3c55cba74fd5f0b9c23689f9c1a31e"
+checksum = "5c9a913769516f5e9d937afac206fb76428e3d7238e538845842887fda584678"
dependencies = [
"gix-command",
"gix-config-value",
"parking_lot",
- "rustix 0.37.20",
+ "rustix",
"thiserror",
]
[[package]]
name = "gix-protocol"
-version = "0.33.2"
+version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92a17058b45c461f0847528c5fb6ee6e76115e026979eb2d2202f98ee94f6c24"
+checksum = "cc7b700dc20cc9be8a5130a1fd7e10c34117ffa7068431c8c24d963f0a2e0c9b"
dependencies = [
"bstr",
"btoi",
"gix-credentials",
+ "gix-date",
"gix-features",
"gix-hash",
"gix-transport",
"maybe-async",
- "nom",
"thiserror",
+ "winnow",
]
[[package]]
name = "gix-quote"
-version = "0.4.4"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29d59489bff95b06dcdabe763b7266d3dc0a628cac1ac1caf65a7ca0a43eeae0"
+checksum = "475c86a97dd0127ba4465fbb239abac9ea10e68301470c9791a6dd5351cdc905"
dependencies = [
"bstr",
"btoi",
@@ -1484,11 +1553,12 @@ dependencies = [
[[package]]
name = "gix-ref"
-version = "0.30.0"
+version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebdd999256f4ce8a5eefa89999879c159c263f3493a951d62aa5ce42c0397e1c"
+checksum = "22e6b749660b613641769edc1954132eb8071a13c32224891686091bef078de4"
dependencies = [
"gix-actor",
+ "gix-date",
"gix-features",
"gix-fs",
"gix-hash",
@@ -1498,15 +1568,15 @@ dependencies = [
"gix-tempfile",
"gix-validate",
"memmap2",
- "nom",
"thiserror",
+ "winnow",
]
[[package]]
name = "gix-refspec"
-version = "0.11.0"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72bfd622abc86dd8ad1ec51b9eb77b4f1a766b94e3a1b87cf4a022c5b5570cf4"
+checksum = "0895cb7b1e70f3c3bd4550c329e9f5caf2975f97fcd4238e05754e72208ef61e"
dependencies = [
"bstr",
"gix-hash",
@@ -1518,9 +1588,9 @@ dependencies = [
[[package]]
name = "gix-revision"
-version = "0.15.2"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5044f56cd7a487ce9b034cbe0252ae0b6b47ff56ca3dabd79bc30214d0932cd7"
+checksum = "c8c4b15cf2ab7a35f5bcb3ef146187c8d36df0177e171ca061913cbaaa890e89"
dependencies = [
"bstr",
"gix-date",
@@ -1528,16 +1598,18 @@ dependencies = [
"gix-hashtable",
"gix-object",
"gix-revwalk",
+ "gix-trace",
"thiserror",
]
[[package]]
name = "gix-revwalk"
-version = "0.1.0"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc2623ba8747914f151f5e12b65adac576ab459dbed5f50a36c7a3e9cbf2d3ca"
+checksum = "e9870c6b1032f2084567710c3b2106ac603377f8d25766b8a6b7c33e6e3ca279"
dependencies = [
"gix-commitgraph",
+ "gix-date",
"gix-hash",
"gix-hashtable",
"gix-object",
@@ -1547,9 +1619,9 @@ dependencies = [
[[package]]
name = "gix-sec"
-version = "0.8.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2b7b38b766eb95dcc5350a9c450030b69892c0902fa35f4a6d0809273bd9dae"
+checksum = "92b9542ac025a8c02ed5d17b3fc031a111a384e859d0be3532ec4d58c40a0f28"
dependencies = [
"bitflags 2.3.3",
"gix-path",
@@ -1558,25 +1630,44 @@ dependencies = [
]
[[package]]
+name = "gix-submodule"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0150e82e9282d3f2ab2dd57a22f9f6c3447b9d9856e5321ac92d38e3e0e2b7"
+dependencies = [
+ "bstr",
+ "gix-config",
+ "gix-path",
+ "gix-pathspec",
+ "gix-refspec",
+ "gix-url",
+ "thiserror",
+]
+
+[[package]]
name = "gix-tempfile"
-version = "6.0.0"
+version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3785cb010e9dc5c446dfbf02bc1119fc17d3a48a27c029efcb3a3c32953eb10"
+checksum = "5ae0978f3e11dc57290ee75ac2477c815bca1ce2fa7ed5dc5f16db067410ac4d"
dependencies = [
"gix-fs",
"libc",
"once_cell",
"parking_lot",
- "signal-hook",
- "signal-hook-registry",
"tempfile",
]
[[package]]
+name = "gix-trace"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836"
+
+[[package]]
name = "gix-transport"
-version = "0.32.0"
+version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64a39ffed9a9078ed700605e064b15d7c6ae50aa65e7faa36ca6919e8081df15"
+checksum = "b9ec726e6a245e68ace59a34126a1d679de60360676612985e70b0d3b102fb4e"
dependencies = [
"base64",
"bstr",
@@ -1593,21 +1684,25 @@ dependencies = [
[[package]]
name = "gix-traverse"
-version = "0.26.0"
+version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0842e984cb4bf26339dc559f3a1b8bf8cdb83547799b2b096822a59f87f33d9"
+checksum = "22ef04ab3643acba289b5cedd25d6f53c0430770b1d689d1d654511e6fb81ba0"
dependencies = [
+ "gix-commitgraph",
+ "gix-date",
"gix-hash",
"gix-hashtable",
"gix-object",
+ "gix-revwalk",
+ "smallvec",
"thiserror",
]
[[package]]
name = "gix-url"
-version = "0.19.0"
+version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1663df25ac42047a2547618d2a6979a26f478073f6306997429235d2cd4c863"
+checksum = "6125ecf46e8c68bf7202da6cad239831daebf0247ffbab30210d72f3856e420f"
dependencies = [
"bstr",
"gix-features",
@@ -1619,18 +1714,18 @@ dependencies = [
[[package]]
name = "gix-utils"
-version = "0.1.2"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbcfcb150c7ef553d76988467d223254045bdcad0dc6724890f32fbe96415da5"
+checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f"
dependencies = [
- "fastrand 1.9.0",
+ "fastrand",
]
[[package]]
name = "gix-validate"
-version = "0.7.5"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57ea5845b506c7728b9d89f4227cc369a5fc5a1d5b26c3add0f0d323413a3a60"
+checksum = "e05cab2b03a45b866156e052aa38619f4ece4adcb2f79978bfc249bc3b21b8c5"
dependencies = [
"bstr",
"thiserror",
@@ -1638,12 +1733,11 @@ dependencies = [
[[package]]
name = "gix-worktree"
-version = "0.18.0"
+version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d388ad962e8854402734a7387af8790f6bdbc8d05349052dab16ca4a0def50f6"
+checksum = "9f5e32972801bd82d56609e6fc84efc358fa1f11f25c5e83b7807ee2280f14fe"
dependencies = [
"bstr",
- "filetime",
"gix-attributes",
"gix-features",
"gix-fs",
@@ -1653,8 +1747,6 @@ dependencies = [
"gix-index",
"gix-object",
"gix-path",
- "io-close",
- "thiserror",
]
[[package]]
@@ -1665,11 +1757,11 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "globset"
-version = "0.4.10"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
+checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d"
dependencies = [
- "aho-corasick 0.7.20",
+ "aho-corasick",
"bstr",
"fnv",
"log",
@@ -1710,12 +1802,6 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
@@ -1832,64 +1918,23 @@ dependencies = [
]
[[package]]
-name = "imara-diff"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8"
-dependencies = [
- "ahash",
- "hashbrown 0.12.3",
-]
-
-[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
- "hashbrown 0.14.0",
-]
-
-[[package]]
-name = "instant"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "io-close"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "io-lifetimes"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
-dependencies = [
- "hermit-abi 0.3.2",
- "libc",
- "windows-sys",
+ "hashbrown",
]
[[package]]
name = "is-terminal"
-version = "0.4.7"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi 0.3.2",
- "io-lifetimes",
- "rustix 0.37.20",
+ "rustix",
"windows-sys",
]
@@ -1933,15 +1978,6 @@ dependencies = [
]
[[package]]
-name = "kstring"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747"
-dependencies = [
- "static_assertions",
-]
-
-[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1961,15 +1997,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
[[package]]
name = "libc"
-version = "0.2.147"
+version = "0.2.148"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
[[package]]
name = "libgit2-sys"
-version = "0.15.2+1.6.4"
+version = "0.16.1+1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a80df2e11fb4a61f4ba2ab42dbe7f74468da143f1a75c74e11dee7c813f694fa"
+checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c"
dependencies = [
"cc",
"libc",
@@ -2033,12 +2069,6 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
-
-[[package]]
-name = "linux-raw-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
@@ -2065,7 +2095,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
- "regex-automata",
+ "regex-automata 0.1.10",
]
[[package]]
@@ -2094,15 +2124,15 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.5.0"
+version = "2.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e"
[[package]]
name = "memmap2"
-version = "0.5.10"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
+checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6"
dependencies = [
"libc",
]
@@ -2229,11 +2259,11 @@ dependencies = [
[[package]]
name = "openssl"
-version = "0.10.55"
+version = "0.10.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
+checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.3.3",
"cfg-if",
"foreign-types",
"libc",
@@ -2250,7 +2280,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn 2.0.29",
]
[[package]]
@@ -2270,9 +2300,9 @@ dependencies = [
[[package]]
name = "openssl-sys"
-version = "0.9.90"
+version = "0.9.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
+checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b"
dependencies = [
"cc",
"libc",
@@ -2348,7 +2378,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.3.5",
+ "redox_syscall",
"smallvec",
"windows-targets",
]
@@ -2445,7 +2475,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn 2.0.29",
]
[[package]]
@@ -2545,9 +2575,9 @@ dependencies = [
[[package]]
name = "prodash"
-version = "25.0.0"
+version = "26.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3236ce1618b6da4c7b618e0143c4d5b5dc190f75f81c49f248221382f7e9e9ae"
+checksum = "794b5bf8e2d19b53dcdcec3e4bba628e20f5b6062503ba89281fa7037dd7bbcf"
dependencies = [
"parking_lot",
]
@@ -2676,15 +2706,6 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
-dependencies = [
- "bitflags 1.3.2",
-]
-
-[[package]]
-name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
@@ -2698,7 +2719,7 @@ version = "1.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
dependencies = [
- "aho-corasick 1.0.2",
+ "aho-corasick",
"memchr",
"regex-syntax 0.7.2",
]
@@ -2713,6 +2734,12 @@ dependencies = [
]
[[package]]
+name = "regex-automata"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
+
+[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2730,7 +2757,6 @@ version = "0.0.0"
dependencies = [
"cargo",
"cargo-util",
- "lazy_static",
"proptest",
"varisat",
]
@@ -2765,20 +2791,6 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.37.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
-dependencies = [
- "bitflags 1.3.2",
- "errno",
- "io-lifetimes",
- "libc",
- "linux-raw-sys 0.3.8",
- "windows-sys",
-]
-
-[[package]]
-name = "rustix"
version = "0.38.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f"
@@ -2786,7 +2798,7 @@ dependencies = [
"bitflags 2.3.3",
"errno",
"libc",
- "linux-raw-sys 0.4.5",
+ "linux-raw-sys",
"windows-sys",
]
@@ -2887,14 +2899,24 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.171"
+version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
+checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
+name = "serde-untagged"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ba3ac59c62f51b75a6bfad8840b2ede4a81ff5cc23c200221ef479ae75a4aa3"
+dependencies = [
+ "erased-serde",
+ "serde",
+]
+
+[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2906,13 +2928,13 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.171"
+version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
+checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn 2.0.29",
]
[[package]]
@@ -2926,9 +2948,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.104"
+version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
+checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
dependencies = [
"itoa 1.0.6",
"ryu",
@@ -2988,25 +3010,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
[[package]]
-name = "signal-hook"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
-dependencies = [
- "libc",
- "signal-hook-registry",
-]
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
-dependencies = [
- "libc",
-]
-
-[[package]]
name = "signature"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3040,9 +3043,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "snapbox"
-version = "0.4.11"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6bccd62078347f89a914e3004d94582e13824d4e3d8a816317862884c423835"
+checksum = "7b439536a42c43be148b610c7f7f968fb79a457254910a9cb20900da73cd3271"
dependencies = [
"anstream",
"anstyle",
@@ -3059,9 +3062,9 @@ dependencies = [
[[package]]
name = "snapbox-macros"
-version = "0.3.4"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eaaf09df9f0eeae82be96290918520214530e738a7fe5a351b0f24cf77c0ca31"
+checksum = "ed1559baff8a696add3322b9be3e940d433e7bb4e38d79017205fd37ff28b28e"
dependencies = [
"anstream",
]
@@ -3087,21 +3090,6 @@ dependencies = [
]
[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
-[[package]]
-name = "strip-ansi-escapes"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8"
-dependencies = [
- "vte",
-]
-
-[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3126,9 +3114,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.28"
+version = "2.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
+checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
dependencies = [
"proc-macro2",
"quote",
@@ -3149,9 +3137,9 @@ dependencies = [
[[package]]
name = "tar"
-version = "0.4.39"
+version = "0.4.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec96d2ffad078296368d46ff1cb309be1c23c513b4ab0e22a45de0185275ac96"
+checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb"
dependencies = [
"filetime",
"libc",
@@ -3159,54 +3147,45 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.7.0"
+version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998"
+checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
dependencies = [
"cfg-if",
- "fastrand 2.0.0",
- "redox_syscall 0.3.5",
- "rustix 0.38.6",
+ "fastrand",
+ "redox_syscall",
+ "rustix",
"windows-sys",
]
[[package]]
-name = "termcolor"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
name = "terminal_size"
-version = "0.2.6"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
+checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
dependencies = [
- "rustix 0.37.20",
+ "rustix",
"windows-sys",
]
[[package]]
name = "thiserror"
-version = "1.0.44"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
+checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.44"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
+checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn 2.0.29",
]
[[package]]
@@ -3221,10 +3200,11 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.22"
+version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
+checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe"
dependencies = [
+ "deranged",
"itoa 1.0.6",
"libc",
"num_threads",
@@ -3235,15 +3215,15 @@ dependencies = [
[[package]]
name = "time-core"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
-version = "0.2.9"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
+checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
dependencies = [
"time-core",
]
@@ -3327,7 +3307,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn 2.0.29",
]
[[package]]
@@ -3389,9 +3369,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unicase"
-version = "2.6.0"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
@@ -3437,9 +3417,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "url"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
+checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
dependencies = [
"form_urlencoded",
"idna",
@@ -3558,27 +3538,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
-name = "vte"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983"
-dependencies = [
- "arrayvec",
- "utf8parse",
- "vte_generate_state_changes",
-]
-
-[[package]]
-name = "vte_generate_state_changes"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff"
-dependencies = [
- "proc-macro2",
- "quote",
-]
-
-[[package]]
name = "wait-timeout"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3624,7 +3583,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn 2.0.29",
"wasm-bindgen-shared",
]
@@ -3646,7 +3605,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn 2.0.29",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -3775,9 +3734,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "winnow"
-version = "0.5.0"
+version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
+checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
dependencies = [
"memchr",
]
diff --git a/src/tools/cargo/Cargo.toml b/src/tools/cargo/Cargo.toml
index 0e189a6d4..440304416 100644
--- a/src/tools/cargo/Cargo.toml
+++ b/src/tools/cargo/Cargo.toml
@@ -11,15 +11,18 @@ exclude = [
]
[workspace.package]
+rust-version = "1.72.0"
edition = "2021"
license = "MIT OR Apache-2.0"
[workspace.dependencies]
-anyhow = "1.0.72"
-base64 = "0.21.2"
-bytesize = "1.2"
+anstream = "0.6.3"
+anstyle = "1.0.4"
+anyhow = "1.0.75"
+base64 = "0.21.3"
+bytesize = "1.3"
cargo = { path = "" }
-cargo-credential = { version = "0.3.0", path = "credential/cargo-credential" }
+cargo-credential = { version = "0.4.0", path = "credential/cargo-credential" }
cargo-credential-libsecret = { version = "0.3.1", path = "credential/cargo-credential-libsecret" }
cargo-credential-wincred = { version = "0.3.0", path = "credential/cargo-credential-wincred" }
cargo-credential-macos-keychain = { version = "0.3.0", path = "credential/cargo-credential-macos-keychain" }
@@ -27,20 +30,20 @@ cargo-platform = { path = "crates/cargo-platform", version = "0.1.4" }
cargo-test-macro = { path = "crates/cargo-test-macro" }
cargo-test-support = { path = "crates/cargo-test-support" }
cargo-util = { version = "0.2.6", path = "crates/cargo-util" }
-cargo_metadata = "0.14.0"
-clap = "4.3.19"
+cargo_metadata = "0.17.0"
+clap = "4.4.6"
+color-print = "0.3.4"
core-foundation = { version = "0.9.3", features = ["mac_os_10_7_support"] }
-crates-io = { version = "0.38.0", path = "crates/crates-io" }
+crates-io = { version = "0.39.0", path = "crates/crates-io" }
criterion = { version = "0.5.1", features = ["html_reports"] }
curl = "0.4.44"
-curl-sys = "0.4.65"
-filetime = "0.2.21"
-flate2 = { version = "1.0.26", default-features = false, features = ["zlib"] }
-fwdansi = "1.1.0"
-git2 = "0.17.2"
-git2-curl = "0.18.0"
-gix = { version = "0.45.1", default-features = false, features = ["blocking-http-transport-curl", "progress-tree"] }
-gix-features-for-configuration-only = { version = "0.30.0", package = "gix-features", features = [ "parallel" ] }
+curl-sys = "0.4.68"
+filetime = "0.2.22"
+flate2 = { version = "1.0.27", default-features = false, features = ["zlib"] }
+git2 = "0.18.0"
+git2-curl = "0.19.0"
+gix = { version = "0.54.1", default-features = false, features = ["blocking-http-transport-curl", "progress-tree", "revision"] }
+gix-features-for-configuration-only = { version = "0.35.0", package = "gix-features", features = [ "parallel" ] }
glob = "0.3.1"
handlebars = { version = "3.5.5", features = ["dir_source"] }
hex = "0.4.3"
@@ -53,15 +56,14 @@ im-rc = "15.1.0"
indexmap = "2"
itertools = "0.10.0"
jobserver = "0.1.26"
-lazy_static = "1.4.0"
lazycell = "1.3.0"
-libc = "0.2.147"
-libgit2-sys = "0.15.2"
+libc = "0.2.148"
+libgit2-sys = "0.16.1"
libloading = "0.8.0"
-memchr = "2.5.0"
+memchr = "2.6.2"
miow = "0.6.0"
opener = "0.6.1"
-openssl ="0.10.55"
+openssl ="0.10.57"
os_info = "3.7.0"
pasetors = { version = "0.6.7", features = ["v3", "paserk", "std", "serde"] }
pathdiff = "0.2"
@@ -75,36 +77,35 @@ rustfix = "0.6.1"
same-file = "1.0.6"
security-framework = "2.9.2"
semver = { version = "1.0.18", features = ["serde"] }
-serde = "1.0.171"
+serde = "1.0.188"
+serde-untagged = "0.1.1"
serde-value = "0.7.0"
serde_ignored = "0.1.9"
-serde_json = "1.0.104"
+serde_json = "1.0.105"
sha1 = "0.10.5"
sha2 = "0.10.7"
shell-escape = "0.1.5"
-snapbox = { version = "0.4.11", features = ["diff", "path"] }
-strip-ansi-escapes = "0.1.1"
-syn = { version = "2.0.28", features = ["extra-traits", "full"] }
-tar = { version = "0.4.39", default-features = false }
-tempfile = "3.7.0"
-termcolor = "1.2.0"
-thiserror = "1.0.44"
+snapbox = { version = "0.4.13", features = ["diff", "path"] }
+syn = { version = "2.0.29", features = ["extra-traits", "full"] }
+tar = { version = "0.4.40", default-features = false }
+tempfile = "3.8.0"
+thiserror = "1.0.47"
time = { version = "0.3", features = ["parsing", "formatting", "serde"] }
toml = "0.7.6"
toml_edit = "0.19.14"
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
-unicase = "2.6.0"
+unicase = "2.7.0"
unicode-width = "0.1.10"
unicode-xid = "0.2.4"
-url = "2.4.0"
+url = "2.4.1"
varisat = "0.2.2"
walkdir = "2.3.3"
windows-sys = "0.48"
[package]
name = "cargo"
-version = "0.74.0"
+version = "0.75.0"
edition.workspace = true
license.workspace = true
homepage = "https://crates.io"
@@ -119,6 +120,8 @@ name = "cargo"
path = "src/cargo/lib.rs"
[dependencies]
+anstream.workspace = true
+anstyle.workspace = true
anyhow.workspace = true
base64.workspace = true
bytesize.workspace = true
@@ -128,6 +131,7 @@ cargo-credential-libsecret.workspace = true
cargo-credential-macos-keychain.workspace = true
cargo-credential-wincred.workspace = true
cargo-util.workspace = true
+color-print.workspace = true
clap = { workspace = true, features = ["wrap_help"] }
crates-io.workspace = true
curl = { workspace = true, features = ["http2"] }
@@ -162,16 +166,15 @@ rand.workspace = true
rustfix.workspace = true
semver.workspace = true
serde = { workspace = true, features = ["derive"] }
+serde-untagged.workspace = true
serde-value.workspace = true
serde_ignored.workspace = true
serde_json = { workspace = true, features = ["raw_value"] }
sha1.workspace = true
shell-escape.workspace = true
-strip-ansi-escapes.workspace = true
syn.workspace = true
tar.workspace = true
tempfile.workspace = true
-termcolor.workspace = true
time.workspace = true
toml.workspace = true
toml_edit.workspace = true
@@ -186,9 +189,6 @@ walkdir.workspace = true
[target.'cfg(not(windows))'.dependencies]
openssl = { workspace = true, optional = true }
-[target.'cfg(windows)'.dependencies]
-fwdansi.workspace = true
-
[target.'cfg(windows)'.dependencies.windows-sys]
workspace = true
features = [
diff --git a/src/tools/cargo/benches/benchsuite/Cargo.toml b/src/tools/cargo/benches/benchsuite/Cargo.toml
index c15798787..81413e761 100644
--- a/src/tools/cargo/benches/benchsuite/Cargo.toml
+++ b/src/tools/cargo/benches/benchsuite/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "benchsuite"
version = "0.0.0"
+rust-version.workspace = true
edition.workspace = true
license.workspace = true
homepage = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/benches/benchsuite/benches/resolve.rs b/src/tools/cargo/benches/benchsuite/benches/resolve.rs
index d03cd620e..f5e28322e 100644
--- a/src/tools/cargo/benches/benchsuite/benches/resolve.rs
+++ b/src/tools/cargo/benches/benchsuite/benches/resolve.rs
@@ -25,22 +25,24 @@ struct ResolveInfo<'cfg> {
fn do_resolve<'cfg>(config: &'cfg Config, ws_root: &Path) -> ResolveInfo<'cfg> {
let requested_kinds = [CompileKind::Host];
let ws = Workspace::new(&ws_root.join("Cargo.toml"), config).unwrap();
- let target_data = RustcTargetData::new(&ws, &requested_kinds).unwrap();
+ let mut target_data = RustcTargetData::new(&ws, &requested_kinds).unwrap();
let cli_features = CliFeatures::from_command_line(&[], false, true).unwrap();
let pkgs = cargo::ops::Packages::Default;
let specs = pkgs.to_package_id_specs(&ws).unwrap();
let has_dev_units = HasDevUnits::Yes;
let force_all_targets = ForceAllTargets::No;
+ let max_rust_version = None;
// Do an initial run to download anything necessary so that it does
// not confuse criterion's warmup.
let ws_resolve = cargo::ops::resolve_ws_with_opts(
&ws,
- &target_data,
+ &mut target_data,
&requested_kinds,
&cli_features,
&specs,
has_dev_units,
force_all_targets,
+ max_rust_version,
)
.unwrap();
ResolveInfo {
@@ -82,6 +84,7 @@ fn resolve_ws(c: &mut Criterion) {
force_all_targets,
..
} = lazy_info.get_or_insert_with(|| do_resolve(&config, &ws_root));
+ let max_rust_version = None;
b.iter(|| {
cargo::ops::resolve_ws_with_opts(
ws,
@@ -91,6 +94,7 @@ fn resolve_ws(c: &mut Criterion) {
specs,
*has_dev_units,
*force_all_targets,
+ max_rust_version,
)
.unwrap();
})
diff --git a/src/tools/cargo/benches/capture/Cargo.toml b/src/tools/cargo/benches/capture/Cargo.toml
index e42fe70e2..e300815d5 100644
--- a/src/tools/cargo/benches/capture/Cargo.toml
+++ b/src/tools/cargo/benches/capture/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "capture"
version = "0.1.0"
+rust-version.workspace = true
edition.workspace = true
license.workspace = true
description = "Tool for capturing a real-world workspace for benchmarking."
diff --git a/src/tools/cargo/clippy.toml b/src/tools/cargo/clippy.toml
index 050cc8716..f50e36588 100644
--- a/src/tools/cargo/clippy.toml
+++ b/src/tools/cargo/clippy.toml
@@ -1,8 +1,8 @@
allow-print-in-tests = true
allow-dbg-in-tests = true
disallowed-methods = [
- { path = "std::env::var", reason = "Use `Config::get_env` instead. See rust-lang/cargo#11588" },
- { path = "std::env::var_os", reason = "Use `Config::get_env_os` instead. See rust-lang/cargo#11588" },
- { path = "std::env::vars", reason = "Not recommended to use in Cargo. See rust-lang/cargo#11588" },
- { path = "std::env::vars_os", reason = "Not recommended to use in Cargo. See rust-lang/cargo#11588" },
+ { path = "std::env::var", reason = "use `Config::get_env` instead. See rust-lang/cargo#11588" },
+ { path = "std::env::var_os", reason = "use `Config::get_env_os` instead. See rust-lang/cargo#11588" },
+ { path = "std::env::vars", reason = "not recommended to use in Cargo. See rust-lang/cargo#11588" },
+ { path = "std::env::vars_os", reason = "not recommended to use in Cargo. See rust-lang/cargo#11588" },
]
diff --git a/src/tools/cargo/crates/cargo-platform/Cargo.toml b/src/tools/cargo/crates/cargo-platform/Cargo.toml
index e7f22cf87..016ead686 100644
--- a/src/tools/cargo/crates/cargo-platform/Cargo.toml
+++ b/src/tools/cargo/crates/cargo-platform/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cargo-platform"
-version = "0.1.4"
+version = "0.1.5"
edition.workspace = true
license.workspace = true
homepage = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/crates/cargo-platform/examples/matches.rs b/src/tools/cargo/crates/cargo-platform/examples/matches.rs
index 9ad5d10dd..1b438fb11 100644
--- a/src/tools/cargo/crates/cargo-platform/examples/matches.rs
+++ b/src/tools/cargo/crates/cargo-platform/examples/matches.rs
@@ -35,8 +35,8 @@ fn get_target() -> String {
.expect("rustc failed to run");
let stdout = String::from_utf8(output.stdout).unwrap();
for line in stdout.lines() {
- if line.starts_with("host: ") {
- return String::from(&line[6..]);
+ if let Some(line) = line.strip_prefix("host: ") {
+ return String::from(line);
}
}
panic!("Failed to find host: {}", stdout);
diff --git a/src/tools/cargo/crates/cargo-platform/src/error.rs b/src/tools/cargo/crates/cargo-platform/src/error.rs
index bf4b35f27..2d5b315f9 100644
--- a/src/tools/cargo/crates/cargo-platform/src/error.rs
+++ b/src/tools/cargo/crates/cargo-platform/src/error.rs
@@ -21,7 +21,7 @@ pub enum ParseErrorKind {
}
impl fmt::Display for ParseError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to parse `{}` as a cfg expression: {}",
@@ -31,7 +31,7 @@ impl fmt::Display for ParseError {
}
impl fmt::Display for ParseErrorKind {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ParseErrorKind::*;
match self {
UnterminatedString => write!(f, "unterminated string in cfg"),
diff --git a/src/tools/cargo/crates/cargo-platform/src/lib.rs b/src/tools/cargo/crates/cargo-platform/src/lib.rs
index 0a3dcf1af..7911e484e 100644
--- a/src/tools/cargo/crates/cargo-platform/src/lib.rs
+++ b/src/tools/cargo/crates/cargo-platform/src/lib.rs
@@ -126,8 +126,7 @@ impl FromStr for Platform {
type Err = ParseError;
fn from_str(s: &str) -> Result<Platform, ParseError> {
- if s.starts_with("cfg(") && s.ends_with(')') {
- let s = &s[4..s.len() - 1];
+ if let Some(s) = s.strip_prefix("cfg(").and_then(|s| s.strip_suffix(')')) {
s.parse().map(Platform::Cfg)
} else {
Platform::validate_named_platform(s)?;
diff --git a/src/tools/cargo/crates/cargo-test-macro/Cargo.toml b/src/tools/cargo/crates/cargo-test-macro/Cargo.toml
index b5da0522f..1e81ab314 100644
--- a/src/tools/cargo/crates/cargo-test-macro/Cargo.toml
+++ b/src/tools/cargo/crates/cargo-test-macro/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "cargo-test-macro"
version = "0.1.0"
+rust-version.workspace = true
edition.workspace = true
license.workspace = true
homepage = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/crates/cargo-test-macro/src/lib.rs b/src/tools/cargo/crates/cargo-test-macro/src/lib.rs
index aa06f477d..937fbce6b 100644
--- a/src/tools/cargo/crates/cargo-test-macro/src/lib.rs
+++ b/src/tools/cargo/crates/cargo-test-macro/src/lib.rs
@@ -1,5 +1,3 @@
-extern crate proc_macro;
-
use proc_macro::*;
use std::process::Command;
use std::sync::Once;
diff --git a/src/tools/cargo/crates/cargo-test-support/Cargo.toml b/src/tools/cargo/crates/cargo-test-support/Cargo.toml
index 085041aff..fc32e1c9c 100644
--- a/src/tools/cargo/crates/cargo-test-support/Cargo.toml
+++ b/src/tools/cargo/crates/cargo-test-support/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "cargo-test-support"
version = "0.1.0"
+rust-version.workspace = true
license.workspace = true
edition.workspace = true
publish = false
@@ -9,6 +10,8 @@ publish = false
doctest = false
[dependencies]
+anstream.workspace = true
+anstyle.workspace = true
anyhow.workspace = true
cargo-test-macro.workspace = true
cargo-util.workspace = true
@@ -18,13 +21,11 @@ flate2.workspace = true
git2.workspace = true
glob.workspace = true
itertools.workspace = true
-lazy_static.workspace = true
pasetors.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
snapbox.workspace = true
tar.workspace = true
-termcolor.workspace = true
time.workspace = true
toml.workspace = true
url.workspace = true
diff --git a/src/tools/cargo/crates/cargo-test-support/src/compare.rs b/src/tools/cargo/crates/cargo-test-support/src/compare.rs
index 21eb64d28..09e3a5a0c 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/compare.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/compare.rs
@@ -206,6 +206,7 @@ fn substitute_macros(input: &str) -> String {
("[UPDATING]", " Updating"),
("[ADDING]", " Adding"),
("[REMOVING]", " Removing"),
+ ("[REMOVED]", " Removed"),
("[DOCTEST]", " Doc-tests"),
("[PACKAGING]", " Packaging"),
("[PACKAGED]", " Packaged"),
diff --git a/src/tools/cargo/crates/cargo-test-support/src/diff.rs b/src/tools/cargo/crates/cargo-test-support/src/diff.rs
index f3b283b10..3fedc839b 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/diff.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/diff.rs
@@ -7,7 +7,6 @@
use std::fmt;
use std::io::Write;
-use termcolor::{Ansi, Color, ColorSpec, NoColor, WriteColor};
/// A single line change to be applied to the original.
#[derive(Debug, Eq, PartialEq)]
@@ -111,42 +110,35 @@ where
}
pub fn render_colored_changes<T: fmt::Display>(changes: &[Change<T>]) -> String {
- // termcolor is not very ergonomic, but I don't want to bring in another dependency.
- let mut red = ColorSpec::new();
- red.set_fg(Some(Color::Red));
- let mut green = ColorSpec::new();
- green.set_fg(Some(Color::Green));
- let mut dim = ColorSpec::new();
- dim.set_dimmed(true);
- let mut v = Vec::new();
- let mut result: Box<dyn WriteColor> = if crate::is_ci() {
+ // anstyle is not very ergonomic, but I don't want to bring in another dependency.
+ let red = anstyle::AnsiColor::Red.on_default().render();
+ let green = anstyle::AnsiColor::Green.on_default().render();
+ let dim = (anstyle::Style::new() | anstyle::Effects::DIMMED).render();
+ let bold = (anstyle::Style::new() | anstyle::Effects::BOLD).render();
+ let reset = anstyle::Reset.render();
+
+ let choice = if crate::is_ci() {
// Don't use color on CI. Even though GitHub can display colors, it
// makes reading the raw logs more difficult.
- Box::new(NoColor::new(&mut v))
+ anstream::ColorChoice::Never
} else {
- Box::new(Ansi::new(&mut v))
+ anstream::AutoStream::choice(&std::io::stdout())
};
+ let mut buffer = anstream::AutoStream::new(Vec::new(), choice);
for change in changes {
let (nums, sign, color, text) = match change {
- Change::Add(i, s) => (format!(" {:<4} ", i), '+', &green, s),
- Change::Remove(i, s) => (format!("{:<4} ", i), '-', &red, s),
- Change::Keep(x, y, s) => (format!("{:<4}{:<4} ", x, y), ' ', &dim, s),
+ Change::Add(i, s) => (format!(" {:<4} ", i), '+', green, s),
+ Change::Remove(i, s) => (format!("{:<4} ", i), '-', red, s),
+ Change::Keep(x, y, s) => (format!("{:<4}{:<4} ", x, y), ' ', dim, s),
};
- result.set_color(&dim).unwrap();
- write!(result, "{}", nums).unwrap();
- let mut bold = color.clone();
- bold.set_bold(true);
- result.set_color(&bold).unwrap();
- write!(result, "{}", sign).unwrap();
- result.reset().unwrap();
- result.set_color(&color).unwrap();
- write!(result, "{}", text).unwrap();
- result.reset().unwrap();
- writeln!(result).unwrap();
+ write!(
+ buffer,
+ "{dim}{nums}{reset}{bold}{sign}{reset}{color}{text}{reset}"
+ )
+ .unwrap();
}
- drop(result);
- String::from_utf8(v).unwrap()
+ String::from_utf8(buffer.into_inner()).unwrap()
}
#[cfg(test)]
diff --git a/src/tools/cargo/crates/cargo-test-support/src/git.rs b/src/tools/cargo/crates/cargo-test-support/src/git.rs
index 6fde96467..236011ca1 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/git.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/git.rs
@@ -10,7 +10,7 @@ Example:
```
let git_project = git::new("dep1", |project| {
project
- .file("Cargo.toml", &basic_manifest("dep1"))
+ .file("Cargo.toml", &basic_manifest("dep1", "1.0.0"))
.file("src/lib.rs", r#"pub fn f() { println!("hi!"); } "#)
});
@@ -177,25 +177,8 @@ where
/// Add all files in the working directory to the git index.
pub fn add(repo: &git2::Repository) {
- // FIXME(libgit2/libgit2#2514): apparently, `add_all` will add all submodules
- // as well, and then fail because they're directories. As a stop-gap, we just
- // ignore all submodules.
- let mut s = t!(repo.submodules());
- for submodule in s.iter_mut() {
- t!(submodule.add_to_index(false));
- }
let mut index = t!(repo.index());
- t!(index.add_all(
- ["*"].iter(),
- git2::IndexAddOption::DEFAULT,
- Some(
- &mut (|a, _b| if s.iter().any(|s| a.starts_with(s.path())) {
- 1
- } else {
- 0
- })
- )
- ));
+ t!(index.add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None));
t!(index.write());
}
diff --git a/src/tools/cargo/crates/cargo-test-support/src/lib.rs b/src/tools/cargo/crates/cargo-test-support/src/lib.rs
index a2fa54c60..1a8742720 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/lib.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/lib.rs
@@ -12,6 +12,7 @@ use std::os;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
use std::str;
+use std::sync::OnceLock;
use std::time::{self, Duration};
use anyhow::{bail, Result};
@@ -569,6 +570,7 @@ pub struct Execs {
expect_stdout_contains_n: Vec<(String, usize)>,
expect_stdout_not_contains: Vec<String>,
expect_stderr_not_contains: Vec<String>,
+ expect_stdout_unordered: Vec<String>,
expect_stderr_unordered: Vec<String>,
expect_stderr_with_without: Vec<(Vec<String>, Vec<String>)>,
expect_json: Option<String>,
@@ -670,6 +672,15 @@ impl Execs {
self
}
+ /// Verifies that all of the stdout output is equal to the given lines,
+ /// ignoring the order of the lines.
+ ///
+ /// See [`Execs::with_stderr_unordered`] for more details.
+ pub fn with_stdout_unordered<S: ToString>(&mut self, expected: S) -> &mut Self {
+ self.expect_stdout_unordered.push(expected.to_string());
+ self
+ }
+
/// Verifies that all of the stderr output is equal to the given lines,
/// ignoring the order of the lines.
///
@@ -838,7 +849,7 @@ impl Execs {
/// Enables nightly features for testing
///
/// The list of reasons should be why nightly cargo is needed. If it is
- /// becuase of an unstable feature put the name of the feature as the reason,
+ /// because of an unstable feature put the name of the feature as the reason,
/// e.g. `&["print-im-a-teapot"]`
pub fn masquerade_as_nightly_cargo(&mut self, reasons: &[&str]) -> &mut Self {
if let Some(ref mut p) = self.process_builder {
@@ -931,6 +942,7 @@ impl Execs {
&& self.expect_stdout_contains_n.is_empty()
&& self.expect_stdout_not_contains.is_empty()
&& self.expect_stderr_not_contains.is_empty()
+ && self.expect_stdout_unordered.is_empty()
&& self.expect_stderr_unordered.is_empty()
&& self.expect_stderr_with_without.is_empty()
&& self.expect_json.is_none()
@@ -1035,6 +1047,9 @@ impl Execs {
for expect in self.expect_stderr_not_contains.iter() {
compare::match_does_not_contain(expect, stderr, cwd)?;
}
+ for expect in self.expect_stdout_unordered.iter() {
+ compare::match_unordered(expect, stdout, cwd)?;
+ }
for expect in self.expect_stderr_unordered.iter() {
compare::match_unordered(expect, stderr, cwd)?;
}
@@ -1074,6 +1089,7 @@ pub fn execs() -> Execs {
expect_stdout_contains_n: Vec::new(),
expect_stdout_not_contains: Vec::new(),
expect_stderr_not_contains: Vec::new(),
+ expect_stdout_unordered: Vec::new(),
expect_stderr_unordered: Vec::new(),
expect_stderr_with_without: Vec::new(),
expect_json: None,
@@ -1157,13 +1173,14 @@ impl RustcInfo {
}
}
-lazy_static::lazy_static! {
- static ref RUSTC_INFO: RustcInfo = RustcInfo::new();
+fn rustc_info() -> &'static RustcInfo {
+ static RUSTC_INFO: OnceLock<RustcInfo> = OnceLock::new();
+ RUSTC_INFO.get_or_init(RustcInfo::new)
}
/// The rustc host such as `x86_64-unknown-linux-gnu`.
pub fn rustc_host() -> &'static str {
- &RUSTC_INFO.host
+ &rustc_info().host
}
/// The host triple suitable for use in a cargo environment variable (uppercased).
@@ -1172,7 +1189,7 @@ pub fn rustc_host_env() -> String {
}
pub fn is_nightly() -> bool {
- let vv = &RUSTC_INFO.verbose_version;
+ let vv = &rustc_info().verbose_version;
// CARGO_TEST_DISABLE_NIGHTLY is set in rust-lang/rust's CI so that all
// nightly-only tests are disabled there. Otherwise, it could make it
// difficult to land changes which would need to be made simultaneously in
@@ -1194,7 +1211,7 @@ fn _process(t: &OsStr) -> ProcessBuilder {
/// Enable nightly features for testing
pub trait ChannelChanger {
/// The list of reasons should be why nightly cargo is needed. If it is
- /// becuase of an unstable feature put the name of the feature as the reason,
+ /// because of an unstable feature put the name of the feature as the reason,
/// e.g. `&["print-im-a-teapot"]`.
fn masquerade_as_nightly_cargo(self, _reasons: &[&str]) -> Self;
}
@@ -1225,28 +1242,27 @@ pub trait TestEnv: Sized {
if env::var_os("RUSTUP_TOOLCHAIN").is_some() {
// Override the PATH to avoid executing the rustup wrapper thousands
// of times. This makes the testsuite run substantially faster.
- lazy_static::lazy_static! {
- static ref RUSTC_DIR: PathBuf = {
- match ProcessBuilder::new("rustup")
- .args(&["which", "rustc"])
- .exec_with_output()
- {
- Ok(output) => {
- let s = str::from_utf8(&output.stdout).expect("utf8").trim();
- let mut p = PathBuf::from(s);
- p.pop();
- p
- }
- Err(e) => {
- panic!("RUSTUP_TOOLCHAIN was set, but could not run rustup: {}", e);
- }
+ static RUSTC_DIR: OnceLock<PathBuf> = OnceLock::new();
+ let rustc_dir = RUSTC_DIR.get_or_init(|| {
+ match ProcessBuilder::new("rustup")
+ .args(&["which", "rustc"])
+ .exec_with_output()
+ {
+ Ok(output) => {
+ let s = str::from_utf8(&output.stdout).expect("utf8").trim();
+ let mut p = PathBuf::from(s);
+ p.pop();
+ p
}
- };
- }
+ Err(e) => {
+ panic!("RUSTUP_TOOLCHAIN was set, but could not run rustup: {}", e);
+ }
+ }
+ });
let path = env::var_os("PATH").unwrap_or_default();
let paths = env::split_paths(&path);
let new_path =
- env::join_paths(std::iter::once(RUSTC_DIR.clone()).chain(paths)).unwrap();
+ env::join_paths(std::iter::once(rustc_dir.clone()).chain(paths)).unwrap();
self = self.env("PATH", new_path);
}
@@ -1408,11 +1424,14 @@ pub fn is_coarse_mtime() -> bool {
/// Architectures that do not have a modern processor, hardware emulation, etc.
/// This provides a way for those setups to increase the cut off for all the time based test.
pub fn slow_cpu_multiplier(main: u64) -> Duration {
- lazy_static::lazy_static! {
- static ref SLOW_CPU_MULTIPLIER: u64 =
- env::var("CARGO_TEST_SLOW_CPU_MULTIPLIER").ok().and_then(|m| m.parse().ok()).unwrap_or(1);
- }
- Duration::from_secs(*SLOW_CPU_MULTIPLIER * main)
+ static SLOW_CPU_MULTIPLIER: OnceLock<u64> = OnceLock::new();
+ let slow_cpu_multiplier = SLOW_CPU_MULTIPLIER.get_or_init(|| {
+ env::var("CARGO_TEST_SLOW_CPU_MULTIPLIER")
+ .ok()
+ .and_then(|m| m.parse().ok())
+ .unwrap_or(1)
+ });
+ Duration::from_secs(slow_cpu_multiplier * main)
}
#[cfg(windows)]
diff --git a/src/tools/cargo/crates/cargo-test-support/src/publish.rs b/src/tools/cargo/crates/cargo-test-support/src/publish.rs
index dccc8356d..f850330c1 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/publish.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/publish.rs
@@ -131,8 +131,11 @@ pub fn validate_crate_contents(
(name, contents)
})
.collect();
- assert!(expected_crate_name.ends_with(".crate"));
- let base_crate_name = Path::new(&expected_crate_name[..expected_crate_name.len() - 6]);
+ let base_crate_name = Path::new(
+ expected_crate_name
+ .strip_suffix(".crate")
+ .expect("must end with .crate"),
+ );
let actual_files: HashSet<PathBuf> = files.keys().cloned().collect();
let expected_files: HashSet<PathBuf> = expected_files
.iter()
diff --git a/src/tools/cargo/crates/cargo-test-support/src/registry.rs b/src/tools/cargo/crates/cargo-test-support/src/registry.rs
index 27c319656..853829c56 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/registry.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/registry.rs
@@ -549,7 +549,9 @@ pub struct Dependency {
name: String,
vers: String,
kind: String,
- artifact: Option<(String, Option<String>)>,
+ artifact: Option<String>,
+ bindep_target: Option<String>,
+ lib: bool,
target: Option<String>,
features: Vec<String>,
registry: Option<String>,
@@ -779,6 +781,7 @@ impl HttpServer {
let buf = buf.get_mut();
write!(buf, "HTTP/1.1 {}\r\n", response.code).unwrap();
write!(buf, "Content-Length: {}\r\n", response.body.len()).unwrap();
+ write!(buf, "Connection: close\r\n").unwrap();
for header in response.headers {
write!(buf, "{}\r\n", header).unwrap();
}
@@ -788,7 +791,7 @@ impl HttpServer {
}
}
- fn check_authorized(&self, req: &Request, mutation: Option<Mutation>) -> bool {
+ fn check_authorized(&self, req: &Request, mutation: Option<Mutation<'_>>) -> bool {
let (private_key, private_key_subject) = if mutation.is_some() || self.auth_required {
match &self.token {
Token::Plaintext(token) => return Some(token) == req.authorization.as_ref(),
@@ -830,7 +833,8 @@ impl HttpServer {
url: &'a str,
kip: &'a str,
}
- let footer: Footer = t!(serde_json::from_slice(untrusted_token.untrusted_footer()).ok());
+ let footer: Footer<'_> =
+ t!(serde_json::from_slice(untrusted_token.untrusted_footer()).ok());
if footer.kip != paserk_pub_key_id {
return false;
}
@@ -844,7 +848,6 @@ impl HttpServer {
if footer.url != "https://github.com/rust-lang/crates.io-index"
&& footer.url != &format!("sparse+http://{}/index/", self.addr.to_string())
{
- dbg!(footer.url);
return false;
}
@@ -860,20 +863,18 @@ impl HttpServer {
_challenge: Option<&'a str>, // todo: PASETO with challenges
v: Option<u8>,
}
- let message: Message = t!(serde_json::from_str(trusted_token.payload()).ok());
+ let message: Message<'_> = t!(serde_json::from_str(trusted_token.payload()).ok());
let token_time = t!(OffsetDateTime::parse(message.iat, &Rfc3339).ok());
let now = OffsetDateTime::now_utc();
if (now - token_time) > Duration::MINUTE {
return false;
}
if private_key_subject.as_deref() != message.sub {
- dbg!(message.sub);
return false;
}
// - If the claim v is set, that it has the value of 1.
if let Some(v) = message.v {
if v != 1 {
- dbg!(message.v);
return false;
}
}
@@ -883,22 +884,18 @@ impl HttpServer {
if let Some(mutation) = mutation {
// - That the operation matches the mutation field and is one of publish, yank, or unyank.
if message.mutation != Some(mutation.mutation) {
- dbg!(message.mutation);
return false;
}
// - That the package, and version match the request.
if message.name != mutation.name {
- dbg!(message.name);
return false;
}
if message.vers != mutation.vers {
- dbg!(message.vers);
return false;
}
// - If the mutation is publish, that the version has not already been published, and that the hash matches the request.
if mutation.mutation == "publish" {
if message.cksum != mutation.cksum {
- dbg!(message.cksum);
return false;
}
}
@@ -1409,13 +1406,20 @@ impl Package {
(true, Some("alternative")) => None,
_ => panic!("registry_dep currently only supports `alternative`"),
};
+ let artifact = if let Some(artifact) = &dep.artifact {
+ serde_json::json!([artifact])
+ } else {
+ serde_json::json!(null)
+ };
serde_json::json!({
"name": dep.name,
"req": dep.vers,
"features": dep.features,
"default_features": true,
"target": dep.target,
- "artifact": dep.artifact,
+ "artifact": artifact,
+ "bindep_target": dep.bindep_target,
+ "lib": dep.lib,
"optional": dep.optional,
"kind": dep.kind,
"registry": registry_url,
@@ -1536,11 +1540,14 @@ impl Package {
"#,
target, kind, dep.name, dep.vers
));
- if let Some((artifact, target)) = &dep.artifact {
+ if let Some(artifact) = &dep.artifact {
manifest.push_str(&format!("artifact = \"{}\"\n", artifact));
- if let Some(target) = &target {
- manifest.push_str(&format!("target = \"{}\"\n", target))
- }
+ }
+ if let Some(target) = &dep.bindep_target {
+ manifest.push_str(&format!("target = \"{}\"\n", target));
+ }
+ if dep.lib {
+ manifest.push_str("lib = true\n");
}
if let Some(registry) = &dep.registry {
assert_eq!(registry, "alternative");
@@ -1617,6 +1624,8 @@ impl Dependency {
vers: vers.to_string(),
kind: "normal".to_string(),
artifact: None,
+ bindep_target: None,
+ lib: false,
target: None,
features: Vec::new(),
package: None,
@@ -1646,7 +1655,8 @@ impl Dependency {
/// Change the artifact to be of the given kind, like "bin", or "staticlib",
/// along with a specific target triple if provided.
pub fn artifact(&mut self, kind: &str, target: Option<String>) -> &mut Self {
- self.artifact = Some((kind.to_string(), target));
+ self.artifact = Some(kind.to_string());
+ self.bindep_target = target;
self
}
diff --git a/src/tools/cargo/crates/cargo-util/Cargo.toml b/src/tools/cargo/crates/cargo-util/Cargo.toml
index 99a59422d..cba00f917 100644
--- a/src/tools/cargo/crates/cargo-util/Cargo.toml
+++ b/src/tools/cargo/crates/cargo-util/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "cargo-util"
-version = "0.2.6"
+version = "0.2.7"
+rust-version.workspace = true
edition.workspace = true
license.workspace = true
homepage = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/crates/cargo-util/src/paths.rs b/src/tools/cargo/crates/cargo-util/src/paths.rs
index ce6755859..888ca1af5 100644
--- a/src/tools/cargo/crates/cargo-util/src/paths.rs
+++ b/src/tools/cargo/crates/cargo-util/src/paths.rs
@@ -4,7 +4,7 @@ use anyhow::{Context, Result};
use filetime::FileTime;
use std::env;
use std::ffi::{OsStr, OsString};
-use std::fs::{self, File, OpenOptions};
+use std::fs::{self, File, Metadata, OpenOptions};
use std::io;
use std::io::prelude::*;
use std::iter;
@@ -136,6 +136,24 @@ pub fn resolve_executable(exec: &Path) -> Result<PathBuf> {
}
}
+/// Returns metadata for a file (follows symlinks).
+///
+/// Equivalent to [`std::fs::metadata`] with better error messages.
+pub fn metadata<P: AsRef<Path>>(path: P) -> Result<Metadata> {
+ let path = path.as_ref();
+ std::fs::metadata(path)
+ .with_context(|| format!("failed to load metadata for path `{}`", path.display()))
+}
+
+/// Returns metadata for a file without following symlinks.
+///
+/// Equivalent to [`std::fs::metadata`] with better error messages.
+pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> Result<Metadata> {
+ let path = path.as_ref();
+ std::fs::symlink_metadata(path)
+ .with_context(|| format!("failed to load metadata for path `{}`", path.display()))
+}
+
/// Reads a file to a string.
///
/// Equivalent to [`std::fs::read_to_string`] with better error messages.
@@ -216,16 +234,14 @@ pub fn open<P: AsRef<Path>>(path: P) -> Result<File> {
/// Returns the last modification time of a file.
pub fn mtime(path: &Path) -> Result<FileTime> {
- let meta =
- fs::metadata(path).with_context(|| format!("failed to stat `{}`", path.display()))?;
+ let meta = metadata(path)?;
Ok(FileTime::from_last_modification_time(&meta))
}
/// Returns the maximum mtime of the given path, recursing into
/// subdirectories, and following symlinks.
pub fn mtime_recursive(path: &Path) -> Result<FileTime> {
- let meta =
- fs::metadata(path).with_context(|| format!("failed to stat `{}`", path.display()))?;
+ let meta = metadata(path)?;
if !meta.is_dir() {
return Ok(FileTime::from_last_modification_time(&meta));
}
@@ -432,10 +448,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(p: P) -> Result<()> {
}
fn _remove_dir_all(p: &Path) -> Result<()> {
- if p.symlink_metadata()
- .with_context(|| format!("could not get metadata for `{}` to remove", p.display()))?
- .is_symlink()
- {
+ if symlink_metadata(p)?.is_symlink() {
return remove_file(p);
}
let entries = p
diff --git a/src/tools/cargo/crates/crates-io/Cargo.toml b/src/tools/cargo/crates/crates-io/Cargo.toml
index 139b8aa97..d06dacdfa 100644
--- a/src/tools/cargo/crates/crates-io/Cargo.toml
+++ b/src/tools/cargo/crates/crates-io/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "crates-io"
-version = "0.38.0"
+version = "0.39.0"
+rust-version.workspace = true
edition.workspace = true
license.workspace = true
repository = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/crates/crates-io/lib.rs b/src/tools/cargo/crates/crates-io/lib.rs
index 6ce39cefd..757241fd3 100644
--- a/src/tools/cargo/crates/crates-io/lib.rs
+++ b/src/tools/cargo/crates/crates-io/lib.rs
@@ -73,6 +73,16 @@ pub struct NewCrateDependency {
pub registry: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub explicit_name_in_toml: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub artifact: Option<Vec<String>>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub bindep_target: Option<String>,
+ #[serde(default, skip_serializing_if = "is_false")]
+ pub lib: bool,
+}
+
+fn is_false(x: &bool) -> bool {
+ *x == false
}
#[derive(Deserialize)]
@@ -132,7 +142,7 @@ pub enum Error {
#[error(transparent)]
Curl(#[from] curl::Error),
- /// Error from seriailzing the request payload and deserialzing the
+ /// Error from seriailzing the request payload and deserializing the
/// response body (like response body didn't match expected structure).
#[error(transparent)]
Json(#[from] serde_json::Error),
diff --git a/src/tools/cargo/crates/mdman/Cargo.toml b/src/tools/cargo/crates/mdman/Cargo.toml
index ba1d4b462..fd33da3c2 100644
--- a/src/tools/cargo/crates/mdman/Cargo.toml
+++ b/src/tools/cargo/crates/mdman/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "mdman"
version = "0.0.0"
+rust-version.workspace = true
edition.workspace = true
license.workspace = true
description = "Creates a man page page from markdown."
diff --git a/src/tools/cargo/crates/mdman/src/format.rs b/src/tools/cargo/crates/mdman/src/format/mod.rs
index 7bc9781b9..7bc9781b9 100644
--- a/src/tools/cargo/crates/mdman/src/format.rs
+++ b/src/tools/cargo/crates/mdman/src/format/mod.rs
diff --git a/src/tools/cargo/crates/mdman/src/hbs.rs b/src/tools/cargo/crates/mdman/src/hbs.rs
index 81ad7ee45..055eb3f28 100644
--- a/src/tools/cargo/crates/mdman/src/hbs.rs
+++ b/src/tools/cargo/crates/mdman/src/hbs.rs
@@ -12,7 +12,7 @@ use std::path::Path;
type FormatterRef<'a> = &'a (dyn Formatter + Send + Sync);
/// Processes the handlebars template at the given file.
-pub fn expand(file: &Path, formatter: FormatterRef) -> Result<String, Error> {
+pub fn expand(file: &Path, formatter: FormatterRef<'_>) -> Result<String, Error> {
let mut handlebars = Handlebars::new();
handlebars.set_strict_mode(true);
handlebars.register_helper("lower", Box::new(lower));
@@ -174,10 +174,10 @@ impl HelperDef for ManLinkHelper<'_> {
///
/// This sets a variable to a value within the template context.
fn set_decorator(
- d: &Decorator,
- _: &Handlebars,
+ d: &Decorator<'_, '_>,
+ _: &Handlebars<'_>,
_ctx: &Context,
- rc: &mut RenderContext,
+ rc: &mut RenderContext<'_, '_>,
) -> Result<(), RenderError> {
let data_to_set = d.hash();
for (k, v) in data_to_set {
@@ -187,7 +187,7 @@ fn set_decorator(
}
/// Sets a variable to a value within the context.
-fn set_in_context(rc: &mut RenderContext, key: &str, value: serde_json::Value) {
+fn set_in_context(rc: &mut RenderContext<'_, '_>, key: &str, value: serde_json::Value) {
let mut ctx = match rc.context() {
Some(c) => (*c).clone(),
None => Context::wraps(serde_json::Value::Object(serde_json::Map::new())).unwrap(),
@@ -201,7 +201,7 @@ fn set_in_context(rc: &mut RenderContext, key: &str, value: serde_json::Value) {
}
/// Removes a variable from the context.
-fn remove_from_context(rc: &mut RenderContext, key: &str) {
+fn remove_from_context(rc: &mut RenderContext<'_, '_>, key: &str) {
let ctx = rc.context().expect("cannot remove from null context");
let mut ctx = (*ctx).clone();
if let serde_json::Value::Object(m) = ctx.data_mut() {
diff --git a/src/tools/cargo/crates/mdman/src/lib.rs b/src/tools/cargo/crates/mdman/src/lib.rs
index 01c3c8d31..5cfb3f4ca 100644
--- a/src/tools/cargo/crates/mdman/src/lib.rs
+++ b/src/tools/cargo/crates/mdman/src/lib.rs
@@ -64,7 +64,7 @@ pub fn convert(
type EventIter<'a> = Box<dyn Iterator<Item = (Event<'a>, Range<usize>)> + 'a>;
/// Creates a new markdown parser with the given input.
-pub(crate) fn md_parser(input: &str, url: Option<Url>) -> EventIter {
+pub(crate) fn md_parser(input: &str, url: Option<Url>) -> EventIter<'_> {
let mut options = Options::empty();
options.insert(Options::ENABLE_TABLES);
options.insert(Options::ENABLE_FOOTNOTES);
diff --git a/src/tools/cargo/crates/mdman/src/main.rs b/src/tools/cargo/crates/mdman/src/main.rs
index 2bdf96d72..facaa5120 100644
--- a/src/tools/cargo/crates/mdman/src/main.rs
+++ b/src/tools/cargo/crates/mdman/src/main.rs
@@ -48,7 +48,7 @@ fn run() -> Result<(), Error> {
if same_file::is_same_file(source, &out_path).unwrap_or(false) {
bail!("cannot output to the same file as the source");
}
- println!("Converting {} -> {}", source.display(), out_path.display());
+ eprintln!("Converting {} -> {}", source.display(), out_path.display());
let result = mdman::convert(&source, opts.format, opts.url.clone(), opts.man_map.clone())
.with_context(|| format!("failed to translate {}", source.display()))?;
@@ -98,15 +98,16 @@ fn process_args() -> Result<Options, Error> {
let man = args
.next()
.ok_or_else(|| format_err!("--man requires a value"))?;
- let parts: Vec<_> = man.splitn(2, '=').collect();
- let key_parts: Vec<_> = parts[0].splitn(2, ':').collect();
- if parts.len() != 2 || key_parts.len() != 2 {
- bail!("--man expected value with form name:1=link");
- }
- let section: u8 = key_parts[1].parse().with_context(|| {
- format!("expected unsigned integer for section, got `{}`", parts[1])
+ let parts = man.split_once('=').ok_or_else(|| {
+ anyhow::format_err!("--man expected value with form name:1=link")
+ })?;
+ let key_parts = parts.0.split_once(':').ok_or_else(|| {
+ anyhow::format_err!("--man expected value with form name:1=link")
+ })?;
+ let section: u8 = key_parts.1.parse().with_context(|| {
+ format!("expected unsigned integer for section, got `{}`", parts.1)
})?;
- man_map.insert((key_parts[0].to_string(), section), parts[1].to_string());
+ man_map.insert((key_parts.0.to_string(), section), parts.1.to_string());
}
s => {
sources.push(PathBuf::from(s));
diff --git a/src/tools/cargo/crates/resolver-tests/Cargo.toml b/src/tools/cargo/crates/resolver-tests/Cargo.toml
index 5e69d7367..8750a3d97 100644
--- a/src/tools/cargo/crates/resolver-tests/Cargo.toml
+++ b/src/tools/cargo/crates/resolver-tests/Cargo.toml
@@ -1,12 +1,12 @@
[package]
name = "resolver-tests"
version = "0.0.0"
+rust-version.workspace = true
edition.workspace = true
publish = false
[dependencies]
cargo.workspace = true
cargo-util.workspace = true
-lazy_static.workspace = true
proptest.workspace = true
varisat.workspace = true
diff --git a/src/tools/cargo/crates/resolver-tests/src/lib.rs b/src/tools/cargo/crates/resolver-tests/src/lib.rs
index ab34e8663..9bdeb8674 100644
--- a/src/tools/cargo/crates/resolver-tests/src/lib.rs
+++ b/src/tools/cargo/crates/resolver-tests/src/lib.rs
@@ -7,15 +7,17 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::fmt;
use std::fmt::Write;
use std::rc::Rc;
+use std::sync::OnceLock;
use std::task::Poll;
use std::time::Instant;
use cargo::core::dependency::DepKind;
use cargo::core::resolver::{self, ResolveOpts, VersionPreferences};
-use cargo::core::source::{GitReference, QueryKind, SourceId};
use cargo::core::Resolve;
use cargo::core::{Dependency, PackageId, Registry, Summary};
-use cargo::util::{CargoResult, Config, Graph, IntoUrl};
+use cargo::core::{GitReference, SourceId};
+use cargo::sources::source::QueryKind;
+use cargo::util::{CargoResult, Config, Graph, IntoUrl, RustVersion};
use proptest::collection::{btree_map, vec};
use proptest::prelude::*;
@@ -161,8 +163,8 @@ pub fn resolve_with_config_raw(
if std::thread::panicking() && self.list.len() != self.used.len() {
// we found a case that causes a panic and did not use all of the input.
// lets print the part of the input that was used for minimization.
- println!(
- "{:?}",
+ eprintln!(
+ "Part used befor drop: {:?}",
PrettyPrintRegistry(
self.list
.iter()
@@ -183,11 +185,12 @@ pub fn resolve_with_config_raw(
deps,
&BTreeMap::new(),
None::<&String>,
- None::<&String>,
+ None::<RustVersion>,
)
.unwrap();
let opts = ResolveOpts::everything();
let start = Instant::now();
+ let max_rust_version = None;
let resolve = resolver::resolve(
&[(summary, opts)],
&[],
@@ -195,6 +198,7 @@ pub fn resolve_with_config_raw(
&VersionPreferences::default(),
Some(config),
true,
+ max_rust_version,
);
// The largest test in our suite takes less then 30 sec.
@@ -561,11 +565,11 @@ macro_rules! pkg {
}
fn registry_loc() -> SourceId {
- lazy_static::lazy_static! {
- static ref EXAMPLE_DOT_COM: SourceId =
- SourceId::for_registry(&"https://example.com".into_url().unwrap()).unwrap();
- }
- *EXAMPLE_DOT_COM
+ static EXAMPLE_DOT_COM: OnceLock<SourceId> = OnceLock::new();
+ let example_dot = EXAMPLE_DOT_COM.get_or_init(|| {
+ SourceId::for_registry(&"https://example.com".into_url().unwrap()).unwrap()
+ });
+ *example_dot
}
pub fn pkg<T: ToPkgId>(name: T) -> Summary {
@@ -584,7 +588,7 @@ pub fn pkg_dep<T: ToPkgId>(name: T, dep: Vec<Dependency>) -> Summary {
dep,
&BTreeMap::new(),
link,
- None::<&String>,
+ None::<RustVersion>,
)
.unwrap()
}
@@ -612,7 +616,7 @@ pub fn pkg_loc(name: &str, loc: &str) -> Summary {
Vec::new(),
&BTreeMap::new(),
link,
- None::<&String>,
+ None::<RustVersion>,
)
.unwrap()
}
@@ -626,7 +630,7 @@ pub fn remove_dep(sum: &Summary, ind: usize) -> Summary {
deps,
&BTreeMap::new(),
sum.links().map(|a| a.as_str()),
- None::<&String>,
+ None::<RustVersion>,
)
.unwrap()
}
diff --git a/src/tools/cargo/crates/resolver-tests/tests/resolve.rs b/src/tools/cargo/crates/resolver-tests/tests/resolve.rs
index 02486bfb5..dd21502d8 100644
--- a/src/tools/cargo/crates/resolver-tests/tests/resolve.rs
+++ b/src/tools/cargo/crates/resolver-tests/tests/resolve.rs
@@ -1562,3 +1562,36 @@ package `A v0.0.0 (registry `https://example.com/`)`
... which satisfies dependency `C = \"*\"` of package `A v0.0.0 (registry `https://example.com/`)`\
", error.to_string());
}
+
+#[test]
+fn shortest_path_in_error_message() {
+ let input = vec![
+ pkg!(("F", "0.1.2")),
+ pkg!(("F", "0.1.1") => [dep("bad"),]),
+ pkg!(("F", "0.1.0") => [dep("bad"),]),
+ pkg!("E" => [dep_req("F", "^0.1.2"),]),
+ pkg!("D" => [dep_req("F", "^0.1.2"),]),
+ pkg!("C" => [dep("D"),]),
+ pkg!("A" => [dep("C"),dep("E"),dep_req("F", "<=0.1.1"),]),
+ ];
+ let error = resolve(vec![dep("A")], &registry(input)).unwrap_err();
+ println!("{}", error);
+ assert_eq!(
+ "\
+failed to select a version for `F`.
+ ... required by package `A v1.0.0 (registry `https://example.com/`)`
+ ... which satisfies dependency `A = \"*\"` of package `root v1.0.0 (registry `https://example.com/`)`
+versions that meet the requirements `<=0.1.1` are: 0.1.1, 0.1.0
+
+all possible versions conflict with previously selected packages.
+
+ previously selected package `F v0.1.2 (registry `https://example.com/`)`
+ ... which satisfies dependency `F = \"^0.1.2\"` of package `E v1.0.0 (registry `https://example.com/`)`
+ ... which satisfies dependency `E = \"*\"` of package `A v1.0.0 (registry `https://example.com/`)`
+ ... which satisfies dependency `A = \"*\"` of package `root v1.0.0 (registry `https://example.com/`)`
+
+failed to select a version for `F` which could resolve this conflict\
+ ",
+ error.to_string()
+ );
+}
diff --git a/src/tools/cargo/crates/semver-check/Cargo.toml b/src/tools/cargo/crates/semver-check/Cargo.toml
index 17e696566..7387c3091 100644
--- a/src/tools/cargo/crates/semver-check/Cargo.toml
+++ b/src/tools/cargo/crates/semver-check/Cargo.toml
@@ -2,6 +2,7 @@
name = "semver-check"
version = "0.0.0"
authors = ["Eric Huss"]
+rust-version.workspace = true
edition.workspace = true
publish = false
diff --git a/src/tools/cargo/crates/semver-check/src/main.rs b/src/tools/cargo/crates/semver-check/src/main.rs
index 1ba405f57..9ea0d1244 100644
--- a/src/tools/cargo/crates/semver-check/src/main.rs
+++ b/src/tools/cargo/crates/semver-check/src/main.rs
@@ -20,7 +20,7 @@ use std::process::{Command, Output};
fn main() {
if let Err(e) = doit() {
- println!("error: {}", e);
+ eprintln!("error: {}", e);
std::process::exit(1);
}
}
@@ -103,7 +103,7 @@ fn doit() -> Result<(), Box<dyn Error>> {
result
};
let expect_success = parts[0][0].contains("MINOR");
- println!("Running test from line {}", block_start);
+ eprintln!("Running test from line {}", block_start);
let result = run_test(
join(parts[1]),
diff --git a/src/tools/cargo/crates/xtask-build-man/Cargo.toml b/src/tools/cargo/crates/xtask-build-man/Cargo.toml
index bec10c48c..9e92125a1 100644
--- a/src/tools/cargo/crates/xtask-build-man/Cargo.toml
+++ b/src/tools/cargo/crates/xtask-build-man/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "xtask-build-man"
version = "0.0.0"
+rust-version.workspace = true
edition.workspace = true
publish = false
diff --git a/src/tools/cargo/crates/xtask-bump-check/Cargo.toml b/src/tools/cargo/crates/xtask-bump-check/Cargo.toml
index e965ad09e..e878f7dda 100644
--- a/src/tools/cargo/crates/xtask-bump-check/Cargo.toml
+++ b/src/tools/cargo/crates/xtask-bump-check/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "xtask-bump-check"
version = "0.0.0"
+rust-version.workspace = true
edition.workspace = true
publish = false
diff --git a/src/tools/cargo/crates/xtask-bump-check/src/main.rs b/src/tools/cargo/crates/xtask-bump-check/src/main.rs
index 0461ab91a..11242696f 100644
--- a/src/tools/cargo/crates/xtask-bump-check/src/main.rs
+++ b/src/tools/cargo/crates/xtask-bump-check/src/main.rs
@@ -20,6 +20,7 @@ fn setup_logger() {
let env = tracing_subscriber::EnvFilter::from_env("CARGO_LOG");
tracing_subscriber::fmt()
+ .with_timer(tracing_subscriber::fmt::time::Uptime::default())
.with_ansi(std::io::IsTerminal::is_terminal(&std::io::stderr()))
.with_writer(std::io::stderr)
.with_env_filter(env)
diff --git a/src/tools/cargo/crates/xtask-bump-check/src/xtask.rs b/src/tools/cargo/crates/xtask-bump-check/src/xtask.rs
index f89152331..4bf3f03d5 100644
--- a/src/tools/cargo/crates/xtask-bump-check/src/xtask.rs
+++ b/src/tools/cargo/crates/xtask-bump-check/src/xtask.rs
@@ -18,10 +18,10 @@ use std::task;
use cargo::core::dependency::Dependency;
use cargo::core::registry::PackageRegistry;
use cargo::core::Package;
-use cargo::core::QueryKind;
use cargo::core::Registry;
use cargo::core::SourceId;
use cargo::core::Workspace;
+use cargo::sources::source::QueryKind;
use cargo::util::command_prelude::*;
use cargo::util::ToSemver;
use cargo::CargoResult;
@@ -105,7 +105,7 @@ fn config_configure(config: &mut Config, args: &ArgMatches) -> CliResult {
/// Main entry of `xtask-bump-check`.
///
/// Assumption: version number are incremental. We never have point release for old versions.
-fn bump_check(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> CargoResult<()> {
+fn bump_check(args: &clap::ArgMatches, config: &cargo::util::Config) -> CargoResult<()> {
let ws = args.workspace(config)?;
let repo = git2::Repository::open(ws.root())?;
let base_commit = get_base_commit(config, args, &repo)?;
@@ -161,7 +161,7 @@ fn bump_check(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> Carg
];
// Even when we test against baseline-rev, we still need to make sure a
- // change doesn't violate SemVer rules aginst crates.io releases. The
+ // change doesn't violate SemVer rules against crates.io releases. The
// possibility of this happening is nearly zero but no harm to check twice.
let mut cmd = ProcessBuilder::new("cargo");
cmd.arg("semver-checks")
@@ -184,7 +184,7 @@ fn bump_check(args: &clap::ArgMatches, config: &mut cargo::util::Config) -> Carg
status("no version bump needed for member crates.")?;
- return Ok(());
+ Ok(())
}
/// Returns the commit of upstream `master` branch if `base-rev` is missing.
@@ -256,7 +256,7 @@ fn get_referenced_commit<'a>(
repo: &'a git2::Repository,
base: &git2::Commit<'a>,
) -> CargoResult<Option<git2::Commit<'a>>> {
- let [beta, stable] = beta_and_stable_branch(&repo)?;
+ let [beta, stable] = beta_and_stable_branch(repo)?;
let rev_id = base.id();
let stable_commit = stable.get().peel_to_commit()?;
let beta_commit = beta.get().peel_to_commit()?;
@@ -397,7 +397,7 @@ fn check_crates_io<'a>(
Ok(())
}
-/// Checkouts a temporary workspace to do further version comparsions.
+/// Checkouts a temporary workspace to do further version comparisons.
fn checkout_ws<'cfg, 'a>(
ws: &Workspace<'cfg>,
repo: &'a git2::Repository,
diff --git a/src/tools/cargo/crates/xtask-stale-label/Cargo.toml b/src/tools/cargo/crates/xtask-stale-label/Cargo.toml
index b1f54a2f1..8d68536d2 100644
--- a/src/tools/cargo/crates/xtask-stale-label/Cargo.toml
+++ b/src/tools/cargo/crates/xtask-stale-label/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "xtask-stale-label"
version = "0.0.0"
+rust-version.workspace = true
edition.workspace = true
publish = false
diff --git a/src/tools/cargo/credential/cargo-credential-1password/Cargo.toml b/src/tools/cargo/credential/cargo-credential-1password/Cargo.toml
index a607e6da1..d7bd949d1 100644
--- a/src/tools/cargo/credential/cargo-credential-1password/Cargo.toml
+++ b/src/tools/cargo/credential/cargo-credential-1password/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cargo-credential-1password"
-version = "0.3.0"
+version = "0.4.0"
edition.workspace = true
license.workspace = true
repository = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/credential/cargo-credential-1password/README.md b/src/tools/cargo/credential/cargo-credential-1password/README.md
index 7cc15e05b..3648efe4b 100644
--- a/src/tools/cargo/credential/cargo-credential-1password/README.md
+++ b/src/tools/cargo/credential/cargo-credential-1password/README.md
@@ -1,7 +1,18 @@
# cargo-credential-1password
-This is the implementation for the Cargo credential helper for [1password].
-See the [credential-process] documentation for how to use this.
+A Cargo [credential provider] for [1password].
+
+`cargo-credential-1password` uses the 1password `op` CLI to store the token. You must
+install the `op` CLI from the [1password
+website](https://1password.com/downloads/command-line/). You must run `op signin`
+at least once with the appropriate arguments (such as `op signin my.1password.com user@example.com`),
+unless you provide the sign-in-address and email arguments. The master password will be required on each request
+unless the appropriate `OP_SESSION` environment variable is set. It supports
+the following command-line arguments:
+* `--account`: The account shorthand name to use.
+* `--vault`: The vault name to use.
+* `--sign-in-address`: The sign-in-address, which is a web address such as `my.1password.com`.
+* `--email`: The email address to sign in with.
[1password]: https://1password.com/
-[credential-process]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process
+[credential provider]: https://doc.rust-lang.org/nightly/cargo/reference/registry-authentication.html
diff --git a/src/tools/cargo/credential/cargo-credential-1password/src/main.rs b/src/tools/cargo/credential/cargo-credential-1password/src/main.rs
index a2607fd2f..921b52145 100644
--- a/src/tools/cargo/credential/cargo-credential-1password/src/main.rs
+++ b/src/tools/cargo/credential/cargo-credential-1password/src/main.rs
@@ -255,8 +255,8 @@ pub struct OnePasswordCredential {}
impl Credential for OnePasswordCredential {
fn perform(
&self,
- registry: &RegistryInfo,
- action: &Action,
+ registry: &RegistryInfo<'_>,
+ action: &Action<'_>,
args: &[&str],
) -> Result<CredentialResponse, Error> {
let op = OnePasswordKeychain::new(args)?;
diff --git a/src/tools/cargo/credential/cargo-credential-libsecret/Cargo.toml b/src/tools/cargo/credential/cargo-credential-libsecret/Cargo.toml
index 1bd4bb7d0..5bedad3b9 100644
--- a/src/tools/cargo/credential/cargo-credential-libsecret/Cargo.toml
+++ b/src/tools/cargo/credential/cargo-credential-libsecret/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cargo-credential-libsecret"
-version = "0.3.1"
+version = "0.3.2"
edition.workspace = true
license.workspace = true
repository = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/credential/cargo-credential-libsecret/README.md b/src/tools/cargo/credential/cargo-credential-libsecret/README.md
index f169323e0..aaba2887f 100644
--- a/src/tools/cargo/credential/cargo-credential-libsecret/README.md
+++ b/src/tools/cargo/credential/cargo-credential-libsecret/README.md
@@ -1,7 +1,9 @@
# cargo-credential-libsecret
This is the implementation for the Cargo credential helper for [GNOME libsecret].
-See the [credential-process] documentation for how to use this.
+See the [credential-provider] documentation for how to use this.
+
+This credential provider is built-in to cargo as `cargo:libsecret`.
[GNOME libsecret]: https://wiki.gnome.org/Projects/Libsecret
-[credential-process]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process
+[credential-provider]: https://doc.rust-lang.org/nightly/cargo/reference/registry-authentication.html
diff --git a/src/tools/cargo/credential/cargo-credential-libsecret/src/lib.rs b/src/tools/cargo/credential/cargo-credential-libsecret/src/lib.rs
index f83b424ee..ee1797605 100644
--- a/src/tools/cargo/credential/cargo-credential-libsecret/src/lib.rs
+++ b/src/tools/cargo/credential/cargo-credential-libsecret/src/lib.rs
@@ -104,16 +104,16 @@ mod linux {
impl Credential for LibSecretCredential {
fn perform(
&self,
- registry: &RegistryInfo,
- action: &Action,
+ registry: &RegistryInfo<'_>,
+ action: &Action<'_>,
_args: &[&str],
) -> Result<CredentialResponse, Error> {
// Dynamically load libsecret to avoid users needing to install
// additional -dev packages when building this provider.
let lib;
- let secret_password_lookup_sync: Symbol<SecretPasswordLookupSync>;
- let secret_password_store_sync: Symbol<SecretPasswordStoreSync>;
- let secret_password_clear_sync: Symbol<SecretPasswordClearSync>;
+ let secret_password_lookup_sync: Symbol<'_, SecretPasswordLookupSync>;
+ let secret_password_store_sync: Symbol<'_, SecretPasswordStoreSync>;
+ let secret_password_clear_sync: Symbol<'_, SecretPasswordClearSync>;
unsafe {
lib = Library::new("libsecret-1.so").context(
"failed to load libsecret: try installing the `libsecret` \
diff --git a/src/tools/cargo/credential/cargo-credential-macos-keychain/Cargo.toml b/src/tools/cargo/credential/cargo-credential-macos-keychain/Cargo.toml
index 342c771b5..172e9c10b 100644
--- a/src/tools/cargo/credential/cargo-credential-macos-keychain/Cargo.toml
+++ b/src/tools/cargo/credential/cargo-credential-macos-keychain/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cargo-credential-macos-keychain"
-version = "0.3.0"
+version = "0.3.1"
edition.workspace = true
license.workspace = true
repository = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/credential/cargo-credential-macos-keychain/README.md b/src/tools/cargo/credential/cargo-credential-macos-keychain/README.md
index 554116b55..f5efe496b 100644
--- a/src/tools/cargo/credential/cargo-credential-macos-keychain/README.md
+++ b/src/tools/cargo/credential/cargo-credential-macos-keychain/README.md
@@ -1,7 +1,10 @@
# cargo-credential-macos-keychain
This is the implementation for the Cargo credential helper for [macOS Keychain].
-See the [credential-process] documentation for how to use this.
+See the [credential-provider] documentation for how to use this.
+
+This credential provider is built-in to cargo as `cargo:macos-keychain`.
[macOS Keychain]: https://support.apple.com/guide/keychain-access/welcome/mac
-[credential-process]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process
+[credential-provider]: https://doc.rust-lang.org/nightly/cargo/reference/registry-authentication.html
+
diff --git a/src/tools/cargo/credential/cargo-credential-wincred/Cargo.toml b/src/tools/cargo/credential/cargo-credential-wincred/Cargo.toml
index 8c609dc4e..6da6578a5 100644
--- a/src/tools/cargo/credential/cargo-credential-wincred/Cargo.toml
+++ b/src/tools/cargo/credential/cargo-credential-wincred/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cargo-credential-wincred"
-version = "0.3.0"
+version = "0.3.1"
edition.workspace = true
license.workspace = true
repository = "https://github.com/rust-lang/cargo"
diff --git a/src/tools/cargo/credential/cargo-credential-wincred/README.md b/src/tools/cargo/credential/cargo-credential-wincred/README.md
index 8c8d18789..1995e9d76 100644
--- a/src/tools/cargo/credential/cargo-credential-wincred/README.md
+++ b/src/tools/cargo/credential/cargo-credential-wincred/README.md
@@ -1,7 +1,9 @@
# cargo-credential-wincred
This is the implementation for the Cargo credential helper for [Windows Credential Manager].
-See the [credential-process] documentation for how to use this.
+See the [credential-provider] documentation for how to use this.
+
+This credential provider is built-in to cargo as `cargo:wincred`.
[Windows Credential Manager]: https://support.microsoft.com/en-us/windows/accessing-credential-manager-1b5c916a-6a16-889f-8581-fc16e8165ac0
-[credential-process]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process
+[credential-provider]: https://doc.rust-lang.org/nightly/cargo/reference/registry-authentication.html
diff --git a/src/tools/cargo/credential/cargo-credential-wincred/src/lib.rs b/src/tools/cargo/credential/cargo-credential-wincred/src/lib.rs
index 9200ca58f..24b072ee2 100644
--- a/src/tools/cargo/credential/cargo-credential-wincred/src/lib.rs
+++ b/src/tools/cargo/credential/cargo-credential-wincred/src/lib.rs
@@ -38,8 +38,8 @@ mod win {
impl Credential for WindowsCredential {
fn perform(
&self,
- registry: &RegistryInfo,
- action: &Action,
+ registry: &RegistryInfo<'_>,
+ action: &Action<'_>,
_args: &[&str],
) -> Result<CredentialResponse, Error> {
match action {
diff --git a/src/tools/cargo/credential/cargo-credential/Cargo.toml b/src/tools/cargo/credential/cargo-credential/Cargo.toml
index 8cd1348be..c8db996bf 100644
--- a/src/tools/cargo/credential/cargo-credential/Cargo.toml
+++ b/src/tools/cargo/credential/cargo-credential/Cargo.toml
@@ -1,8 +1,9 @@
[package]
name = "cargo-credential"
-version = "0.3.0"
+version = "0.4.0"
edition.workspace = true
license.workspace = true
+rust-version = "1.70.0"
repository = "https://github.com/rust-lang/cargo"
description = "A library to assist writing Cargo credential helpers."
diff --git a/src/tools/cargo/credential/cargo-credential/README.md b/src/tools/cargo/credential/cargo-credential/README.md
index 049b3ba55..d87d41bb8 100644
--- a/src/tools/cargo/credential/cargo-credential/README.md
+++ b/src/tools/cargo/credential/cargo-credential/README.md
@@ -5,7 +5,7 @@ provides an interface to store tokens for authorizing access to a registry
such as https://crates.io/.
Documentation about credential processes may be found at
-https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process
+https://doc.rust-lang.org/nightly/cargo/reference/credential-provider-protocol.html
Example implementations may be found at
https://github.com/rust-lang/cargo/tree/master/credential
@@ -18,7 +18,7 @@ Create a Cargo project with this as a dependency:
# Add this to your Cargo.toml:
[dependencies]
-cargo-credential = "0.3"
+cargo-credential = "0.4"
```
And then include a `main.rs` binary which implements the `Credential` trait, and calls
diff --git a/src/tools/cargo/credential/cargo-credential/examples/file-provider.rs b/src/tools/cargo/credential/cargo-credential/examples/file-provider.rs
index d11958536..3ed312cb8 100644
--- a/src/tools/cargo/credential/cargo-credential/examples/file-provider.rs
+++ b/src/tools/cargo/credential/cargo-credential/examples/file-provider.rs
@@ -12,8 +12,8 @@ struct FileCredential;
impl Credential for FileCredential {
fn perform(
&self,
- registry: &RegistryInfo,
- action: &Action,
+ registry: &RegistryInfo<'_>,
+ action: &Action<'_>,
_args: &[&str],
) -> Result<CredentialResponse, cargo_credential::Error> {
if registry.index_url != "https://github.com/rust-lang/crates.io-index" {
diff --git a/src/tools/cargo/credential/cargo-credential/examples/stdout-redirected.rs b/src/tools/cargo/credential/cargo-credential/examples/stdout-redirected.rs
index 0b9bcc2f7..75a2d16d1 100644
--- a/src/tools/cargo/credential/cargo-credential/examples/stdout-redirected.rs
+++ b/src/tools/cargo/credential/cargo-credential/examples/stdout-redirected.rs
@@ -7,8 +7,8 @@ struct MyCredential;
impl Credential for MyCredential {
fn perform(
&self,
- _registry: &RegistryInfo,
- _action: &Action,
+ _registry: &RegistryInfo<'_>,
+ _action: &Action<'_>,
_args: &[&str],
) -> Result<CredentialResponse, Error> {
// Informational messages should be sent on stderr.
diff --git a/src/tools/cargo/credential/cargo-credential/src/error.rs b/src/tools/cargo/credential/cargo-credential/src/error.rs
index 2ebaf9977..8c5fe19e5 100644
--- a/src/tools/cargo/credential/cargo-credential/src/error.rs
+++ b/src/tools/cargo/credential/cargo-credential/src/error.rs
@@ -42,9 +42,9 @@ pub enum Error {
}
impl From<String> for Error {
- fn from(err: String) -> Self {
+ fn from(message: String) -> Self {
Box::new(StringTypedError {
- message: err.to_string(),
+ message,
source: None,
})
.into()
diff --git a/src/tools/cargo/credential/cargo-credential/src/lib.rs b/src/tools/cargo/credential/cargo-credential/src/lib.rs
index 0fb495ed3..60bce65be 100644
--- a/src/tools/cargo/credential/cargo-credential/src/lib.rs
+++ b/src/tools/cargo/credential/cargo-credential/src/lib.rs
@@ -50,7 +50,7 @@ pub use secret::Secret;
use stdio::stdin_stdout_to_console;
/// Message sent by the credential helper on startup
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct CredentialHello {
// Protocol versions supported by the credential process.
pub v: Vec<u32>,
@@ -61,8 +61,8 @@ pub struct UnsupportedCredential;
impl Credential for UnsupportedCredential {
fn perform(
&self,
- _registry: &RegistryInfo,
- _action: &Action,
+ _registry: &RegistryInfo<'_>,
+ _action: &Action<'_>,
_args: &[&str],
) -> Result<CredentialResponse, Error> {
Err(Error::UrlNotSupported)
@@ -70,7 +70,7 @@ impl Credential for UnsupportedCredential {
}
/// Message sent by Cargo to the credential helper after the hello
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct CredentialRequest<'a> {
// Cargo will respond with the highest common protocol supported by both.
@@ -80,23 +80,25 @@ pub struct CredentialRequest<'a> {
#[serde(borrow, flatten)]
pub action: Action<'a>,
/// Additional command-line arguments passed to the credential provider.
+ #[serde(skip_serializing_if = "Vec::is_empty", default)]
pub args: Vec<&'a str>,
}
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct RegistryInfo<'a> {
/// Registry index url
pub index_url: &'a str,
/// Name of the registry in configuration. May not be available.
/// The crates.io registry will be `crates-io` (`CRATES_IO_REGISTRY`).
+ #[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<&'a str>,
/// Headers from attempting to access a registry that resulted in a HTTP 401.
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub headers: Vec<String>,
}
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum Action<'a> {
@@ -119,17 +121,19 @@ impl<'a> Display for Action<'a> {
}
}
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct LoginOptions<'a> {
/// Token passed on the command line via --token or from stdin
+ #[serde(skip_serializing_if = "Option::is_none")]
pub token: Option<Secret<&'a str>>,
/// Optional URL that the user can visit to log in to the registry
+ #[serde(skip_serializing_if = "Option::is_none")]
pub login_url: Option<&'a str>,
}
/// A record of what kind of operation is happening that we should generate a token for.
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
#[serde(tag = "operation", rename_all = "kebab-case")]
pub enum Operation<'a> {
@@ -168,12 +172,13 @@ pub enum Operation<'a> {
}
/// Message sent by the credential helper
-#[derive(Serialize, Deserialize, Clone, Debug)]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(tag = "kind", rename_all = "kebab-case")]
#[non_exhaustive]
pub enum CredentialResponse {
Get {
token: Secret<String>,
+ #[serde(flatten)]
cache: CacheControl,
operation_independent: bool,
},
@@ -183,30 +188,35 @@ pub enum CredentialResponse {
Unknown,
}
-#[derive(Serialize, Deserialize, Clone, Debug)]
-#[serde(rename_all = "kebab-case")]
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+#[serde(tag = "cache", rename_all = "kebab-case")]
#[non_exhaustive]
pub enum CacheControl {
/// Do not cache this result.
Never,
/// Cache this result and use it for subsequent requests in the current Cargo invocation until the specified time.
- Expires(#[serde(with = "time::serde::timestamp")] OffsetDateTime),
+ Expires {
+ #[serde(with = "time::serde::timestamp")]
+ expiration: OffsetDateTime,
+ },
/// Cache this result and use it for all subsequent requests in the current Cargo invocation.
Session,
#[serde(other)]
Unknown,
}
-/// Credential process JSON protocol version. Incrementing
-/// this version will prevent new credential providers
-/// from working with older versions of Cargo.
+/// Credential process JSON protocol version. If the protocol needs to make
+/// a breaking change, a new protocol version should be defined (`PROTOCOL_VERSION_2`).
+/// This library should offer support for both protocols if possible, by signaling
+/// in the `CredentialHello` message. Cargo will then choose which protocol to use,
+/// or it will error if there are no common protocol versions available.
pub const PROTOCOL_VERSION_1: u32 = 1;
pub trait Credential {
/// Retrieves a token for the given registry.
fn perform(
&self,
- registry: &RegistryInfo,
- action: &Action,
+ registry: &RegistryInfo<'_>,
+ action: &Action<'_>,
args: &[&str],
) -> Result<CredentialResponse, Error>;
}
@@ -236,11 +246,7 @@ fn doit(
if len == 0 {
return Ok(());
}
- let request: CredentialRequest = serde_json::from_str(&buffer)?;
- if request.v != PROTOCOL_VERSION_1 {
- return Err(format!("unsupported protocol version {}", request.v).into());
- }
-
+ let request = deserialize_request(&buffer)?;
let response = stdin_stdout_to_console(|| {
credential.perform(&request.registry, &request.action, &request.args)
})?;
@@ -250,6 +256,17 @@ fn doit(
}
}
+/// Deserialize a request from Cargo.
+fn deserialize_request(
+ value: &str,
+) -> Result<CredentialRequest<'_>, Box<dyn std::error::Error + Send + Sync>> {
+ let request: CredentialRequest<'_> = serde_json::from_str(&value)?;
+ if request.v != PROTOCOL_VERSION_1 {
+ return Err(format!("unsupported protocol version {}", request.v).into());
+ }
+ Ok(request)
+}
+
/// Read a line of text from stdin.
pub fn read_line() -> Result<String, io::Error> {
let mut buf = String::new();
@@ -259,8 +276,8 @@ pub fn read_line() -> Result<String, io::Error> {
/// Prompt the user for a token.
pub fn read_token(
- login_options: &LoginOptions,
- registry: &RegistryInfo,
+ login_options: &LoginOptions<'_>,
+ registry: &RegistryInfo<'_>,
) -> Result<Secret<String>, Error> {
if let Some(token) = &login_options.token {
return Ok(token.to_owned());
@@ -276,3 +293,142 @@ pub fn read_token(
Ok(Secret::from(read_line().map_err(Box::new)?))
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn unsupported_version() {
+ // This shouldn't ever happen in practice, since the credential provider signals to Cargo which
+ // protocol versions it supports, and Cargo should only attempt to use one of those.
+ let msg = r#"{"v":999, "registry": {"index-url":""}, "args":[], "kind": "unexpected"}"#;
+ assert_eq!(
+ "unsupported protocol version 999",
+ deserialize_request(msg).unwrap_err().to_string()
+ );
+ }
+
+ #[test]
+ fn cache_control() {
+ let cc = CacheControl::Expires {
+ expiration: OffsetDateTime::from_unix_timestamp(1693928537).unwrap(),
+ };
+ let json = serde_json::to_string(&cc).unwrap();
+ assert_eq!(json, r#"{"cache":"expires","expiration":1693928537}"#);
+
+ let cc = CacheControl::Session;
+ let json = serde_json::to_string(&cc).unwrap();
+ assert_eq!(json, r#"{"cache":"session"}"#);
+
+ let cc: CacheControl = serde_json::from_str(r#"{"cache":"unknown-kind"}"#).unwrap();
+ assert_eq!(cc, CacheControl::Unknown);
+
+ assert_eq!(
+ "missing field `expiration`",
+ serde_json::from_str::<CacheControl>(r#"{"cache":"expires"}"#)
+ .unwrap_err()
+ .to_string()
+ );
+ }
+
+ #[test]
+ fn credential_response() {
+ let cr = CredentialResponse::Get {
+ cache: CacheControl::Never,
+ operation_independent: true,
+ token: Secret::from("value".to_string()),
+ };
+ let json = serde_json::to_string(&cr).unwrap();
+ assert_eq!(
+ json,
+ r#"{"kind":"get","token":"value","cache":"never","operation_independent":true}"#
+ );
+
+ let cr = CredentialResponse::Login;
+ let json = serde_json::to_string(&cr).unwrap();
+ assert_eq!(json, r#"{"kind":"login"}"#);
+
+ let cr: CredentialResponse =
+ serde_json::from_str(r#"{"kind":"unknown-kind","extra-data":true}"#).unwrap();
+ assert_eq!(cr, CredentialResponse::Unknown);
+
+ let cr: CredentialResponse =
+ serde_json::from_str(r#"{"kind":"login","extra-data":true}"#).unwrap();
+ assert_eq!(cr, CredentialResponse::Login);
+
+ let cr: CredentialResponse = serde_json::from_str(r#"{"kind":"get","token":"value","cache":"never","operation_independent":true,"extra-field-ignored":123}"#).unwrap();
+ assert_eq!(
+ cr,
+ CredentialResponse::Get {
+ cache: CacheControl::Never,
+ operation_independent: true,
+ token: Secret::from("value".to_string())
+ }
+ );
+ }
+
+ #[test]
+ fn credential_request() {
+ let get_oweners = CredentialRequest {
+ v: PROTOCOL_VERSION_1,
+ args: vec![],
+ registry: RegistryInfo {
+ index_url: "url",
+ name: None,
+ headers: vec![],
+ },
+ action: Action::Get(Operation::Owners { name: "pkg" }),
+ };
+
+ let json = serde_json::to_string(&get_oweners).unwrap();
+ assert_eq!(
+ json,
+ r#"{"v":1,"registry":{"index-url":"url"},"kind":"get","operation":"owners","name":"pkg"}"#
+ );
+
+ let cr: CredentialRequest<'_> =
+ serde_json::from_str(r#"{"extra-1":true,"v":1,"registry":{"index-url":"url","extra-2":true},"kind":"get","operation":"owners","name":"pkg","args":[]}"#).unwrap();
+ assert_eq!(cr, get_oweners);
+ }
+
+ #[test]
+ fn credential_request_logout() {
+ let unknown = CredentialRequest {
+ v: PROTOCOL_VERSION_1,
+ args: vec![],
+ registry: RegistryInfo {
+ index_url: "url",
+ name: None,
+ headers: vec![],
+ },
+ action: Action::Logout,
+ };
+
+ let cr: CredentialRequest<'_> = serde_json::from_str(
+ r#"{"v":1,"registry":{"index-url":"url"},"kind":"logout","extra-1":true,"args":[]}"#,
+ )
+ .unwrap();
+ assert_eq!(cr, unknown);
+ }
+
+ #[test]
+ fn credential_request_unknown() {
+ let unknown = CredentialRequest {
+ v: PROTOCOL_VERSION_1,
+ args: vec![],
+ registry: RegistryInfo {
+ index_url: "",
+ name: None,
+ headers: vec![],
+ },
+ action: Action::Unknown,
+ };
+
+ let cr: CredentialRequest<'_> = serde_json::from_str(
+ r#"{"v":1,"registry":{"index-url":""},"kind":"unexpected-1","extra-1":true,"args":[]}"#,
+ )
+ .unwrap();
+ assert_eq!(cr, unknown);
+ }
+}
diff --git a/src/tools/cargo/deny.toml b/src/tools/cargo/deny.toml
index 383648171..746113f3c 100644
--- a/src/tools/cargo/deny.toml
+++ b/src/tools/cargo/deny.toml
@@ -192,11 +192,11 @@ wildcards = "allow"
# * all - Both lowest-version and simplest-path are used
highlight = "all"
# The default lint level for `default` features for crates that are members of
-# the workspace that is being checked. This can be overriden by allowing/denying
+# the workspace that is being checked. This can be overridden by allowing/denying
# `default` on a crate-by-crate basis if desired.
workspace-default-features = "allow"
# The default lint level for `default` features for external crates that are not
-# members of the workspace. This can be overriden by allowing/denying `default`
+# members of the workspace. This can be overridden by allowing/denying `default`
# on a crate-by-crate basis if desired.
external-default-features = "allow"
# List of crates that are allowed. Use with care!
diff --git a/src/tools/cargo/publish.py b/src/tools/cargo/publish.py
index 13077a69b..87ea0e896 100755
--- a/src/tools/cargo/publish.py
+++ b/src/tools/cargo/publish.py
@@ -11,12 +11,16 @@
import os
import re
import subprocess
-import time
import urllib.request
from urllib.error import HTTPError
TO_PUBLISH = [
+ 'credential/cargo-credential',
+ 'credential/cargo-credential-libsecret',
+ 'credential/cargo-credential-wincred',
+ 'credential/cargo-credential-1password',
+ 'credential/cargo-credential-macos-keychain',
'crates/cargo-platform',
'crates/cargo-util',
'crates/crates-io',
@@ -47,13 +51,9 @@ def maybe_publish(path):
def main():
print('Starting publish...')
- for i, path in enumerate(TO_PUBLISH):
- if maybe_publish(path):
- if i < len(TO_PUBLISH)-1:
- # Sleep to allow the index to update. This should probably
- # check that the index is updated, or use a retry loop
- # instead.
- time.sleep(5)
+ for path in TO_PUBLISH:
+ maybe_publish(path)
+
print('Publish complete!')
diff --git a/src/tools/cargo/src/bin/cargo/cli.rs b/src/tools/cargo/src/bin/cargo/cli.rs
index eb337d681..06b4a20e2 100644
--- a/src/tools/cargo/src/bin/cargo/cli.rs
+++ b/src/tools/cargo/src/bin/cargo/cli.rs
@@ -12,7 +12,9 @@ use std::fmt::Write;
use super::commands;
use super::list_commands;
use crate::command_prelude::*;
+use crate::util::is_rustup;
use cargo::core::features::HIDDEN;
+use cargo::util::style;
pub fn main(config: &mut LazyConfig) -> CliResult {
let args = cli().try_get_matches()?;
@@ -312,7 +314,7 @@ For more information, see issue #10049 <https://github.com/rust-lang/cargo/issue
} else {
config.shell().warn(format_args!(
"\
-user-defined alias `{cmd}` has the appearance of a manfiest-command
+user-defined alias `{cmd}` has the appearance of a manifest-command
This was previously accepted but will be phased out when `-Zscript` is stabilized.
For more information, see issue #12207 <https://github.com/rust-lang/cargo/issues/12207>."
))?;
@@ -447,7 +449,7 @@ impl Exec {
if !config.cli_unstable().script && ext_path.is_some() {
config.shell().warn(format_args!(
"\
-external subcommand `{cmd}` has the appearance of a manfiest-command
+external subcommand `{cmd}` has the appearance of a manifest-command
This was previously accepted but will be phased out when `-Zscript` is stabilized.
For more information, see issue #12207 <https://github.com/rust-lang/cargo/issues/12207>.",
))?;
@@ -511,15 +513,23 @@ impl GlobalArgs {
}
pub fn cli() -> Command {
- // ALLOWED: `RUSTUP_HOME` should only be read from process env, otherwise
- // other tools may point to executables from incompatible distributions.
- #[allow(clippy::disallowed_methods)]
- let is_rustup = std::env::var_os("RUSTUP_HOME").is_some();
- let usage = if is_rustup {
- "cargo [+toolchain] [OPTIONS] [COMMAND]\n cargo [+toolchain] [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]..."
+ let usage = if is_rustup() {
+ color_print::cstr!("<cyan,bold>cargo</> <cyan>[+toolchain] [OPTIONS] [COMMAND]</>\n <cyan,bold>cargo</> <cyan>[+toolchain] [OPTIONS]</> <cyan,bold>-Zscript</> <cyan><<MANIFEST_RS>> [ARGS]...</>")
} else {
- "cargo [OPTIONS] [COMMAND]\n cargo [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]..."
+ color_print::cstr!("<cyan,bold>cargo</> <cyan>[OPTIONS] [COMMAND]</>\n <cyan,bold>cargo</> <cyan>[OPTIONS]</> <cyan,bold>-Zscript</> <cyan><<MANIFEST_RS>> [ARGS]...</>")
};
+
+ let styles = {
+ clap::builder::styling::Styles::styled()
+ .header(style::HEADER)
+ .usage(style::USAGE)
+ .literal(style::LITERAL)
+ .placeholder(style::PLACEHOLDER)
+ .error(style::ERROR)
+ .valid(style::VALID)
+ .invalid(style::INVALID)
+ };
+
Command::new("cargo")
// Subcommands all count their args' display order independently (from 0),
// which makes their args interspersed with global args. This puts global args last.
@@ -527,44 +537,49 @@ pub fn cli() -> Command {
// We also want these to come before auto-generated `--help`
.next_display_order(800)
.allow_external_subcommands(true)
- // Doesn't mix well with our list of common cargo commands. See clap-rs/clap#3108 for
- // opening clap up to allow us to style our help template
- .disable_colored_help(true)
+ .styles(styles)
// Provide a custom help subcommand for calling into man pages
.disable_help_subcommand(true)
.override_usage(usage)
- .help_template(
+ .help_template(color_print::cstr!(
"\
Rust's package manager
-Usage: {usage}
+<green,bold>Usage:</> {usage}
-Options:
+<green,bold>Options:</>
{options}
-Some common cargo commands are (see all commands with --list):
- build, b Compile the current package
- check, c Analyze the current package and report errors, but don't build object files
- clean Remove the target directory
- doc, d Build this package's and its dependencies' documentation
- new Create a new cargo package
- init Create a new cargo package in an existing directory
- add Add dependencies to a manifest file
- remove Remove dependencies from a manifest file
- run, r Run a binary or example of the local package
- test, t Run the tests
- bench Run the benchmarks
- update Update dependencies listed in Cargo.lock
- search Search registry for crates
- publish Package and upload this package to the registry
- install Install a Rust binary. Default location is $HOME/.cargo/bin
- uninstall Uninstall a Rust binary
-
-See 'cargo help <command>' for more information on a specific command.\n",
- )
+<green,bold>Commands:</>
+ <cyan,bold>build</>, <cyan,bold>b</> Compile the current package
+ <cyan,bold>check</>, <cyan,bold>c</> Analyze the current package and report errors, but don't build object files
+ <cyan,bold>clean</> Remove the target directory
+ <cyan,bold>doc</>, <cyan,bold>d</> Build this package's and its dependencies' documentation
+ <cyan,bold>new</> Create a new cargo package
+ <cyan,bold>init</> Create a new cargo package in an existing directory
+ <cyan,bold>add</> Add dependencies to a manifest file
+ <cyan,bold>remove</> Remove dependencies from a manifest file
+ <cyan,bold>run</>, <cyan,bold>r</> Run a binary or example of the local package
+ <cyan,bold>test</>, <cyan,bold>t</> Run the tests
+ <cyan,bold>bench</> Run the benchmarks
+ <cyan,bold>update</> Update dependencies listed in Cargo.lock
+ <cyan,bold>search</> Search registry for crates
+ <cyan,bold>publish</> Package and upload this package to the registry
+ <cyan,bold>install</> Install a Rust binary. Default location is $HOME/.cargo/bin
+ <cyan,bold>uninstall</> Uninstall a Rust binary
+ <cyan>...</> See all commands with <cyan,bold>--list</>
+
+See '<cyan,bold>cargo help</> <cyan><<command>></>' for more information on a specific command.\n",
+ ))
.arg(flag("version", "Print version info and exit").short('V'))
.arg(flag("list", "List installed commands"))
- .arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE"))
+ .arg(
+ opt(
+ "explain",
+ "Provide a detailed explanation of a rustc error message",
+ )
+ .value_name("CODE"),
+ )
.arg(
opt(
"verbose",
diff --git a/src/tools/cargo/src/bin/cargo/commands/add.rs b/src/tools/cargo/src/bin/cargo/commands/add.rs
index 56df76268..344cd2af3 100644
--- a/src/tools/cargo/src/bin/cargo/commands/add.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/add.rs
@@ -18,12 +18,12 @@ pub fn cli() -> Command {
clap::Command::new("add")
.about("Add dependencies to a Cargo.toml manifest file")
.override_usage(
- "\
- cargo add [OPTIONS] <DEP>[@<VERSION>] ...
- cargo add [OPTIONS] --path <PATH> ...
- cargo add [OPTIONS] --git <URL> ..."
- )
- .after_help("Run `cargo help add` for more detailed information.\n")
+ color_print::cstr!("\
+ <cyan,bold>cargo add</> <cyan>[OPTIONS] <<DEP>>[@<<VERSION>>] ...</>
+ <cyan,bold>cargo add</> <cyan>[OPTIONS]</> <cyan,bold>--path</> <cyan><<PATH>> ...</>
+ <cyan,bold>cargo add</> <cyan>[OPTIONS]</> <cyan,bold>--git</> <cyan><<URL>> ...</>"
+ ))
+ .after_help(color_print::cstr!("Run `<cyan,bold>cargo help add</>` for more detailed information.\n"))
.group(clap::ArgGroup::new("selected").multiple(true).required(true))
.args([
clap::Arg::new("crates")
diff --git a/src/tools/cargo/src/bin/cargo/commands/bench.rs b/src/tools/cargo/src/bin/cargo/commands/bench.rs
index bb2c193b0..1a97d84a4 100644
--- a/src/tools/cargo/src/bin/cargo/commands/bench.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/bench.rs
@@ -42,30 +42,22 @@ pub fn cli() -> Command {
"Benchmark all targets",
)
.arg_features()
- .arg_jobs_without_keep_going()
- .arg(flag("keep-going", "Use `--no-fail-fast` instead").hide(true)) // See rust-lang/cargo#11702
+ .arg_jobs()
+ .arg_unsupported_keep_going()
.arg_profile("Build artifacts with the specified profile")
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
- .after_help("Run `cargo help bench` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help bench</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
- if args.keep_going() {
- return Err(anyhow::format_err!(
- "\
-unexpected argument `--keep-going` found
-
- tip: to run as many benchmarks as possible without failing fast, use `--no-fail-fast`"
- )
- .into());
- }
-
let mut compile_opts = args.compile_options(
config,
CompileMode::Bench,
diff --git a/src/tools/cargo/src/bin/cargo/commands/build.rs b/src/tools/cargo/src/bin/cargo/commands/build.rs
index e25638aa0..d503f43dd 100644
--- a/src/tools/cargo/src/bin/cargo/commands/build.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/build.rs
@@ -30,8 +30,9 @@ pub fn cli() -> Command {
)
.arg_features()
.arg_release("Build artifacts in release mode, with optimizations")
+ .arg_redundant_default_mode("debug", "build", "release")
.arg_profile("Build artifacts with the specified profile")
- .arg_jobs()
+ .arg_parallel()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg(
@@ -46,7 +47,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
- .after_help("Run `cargo help build` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help build</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/check.rs b/src/tools/cargo/src/bin/cargo/commands/check.rs
index ab6f99048..a54e84cdc 100644
--- a/src/tools/cargo/src/bin/cargo/commands/check.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/check.rs
@@ -29,7 +29,7 @@ pub fn cli() -> Command {
"Check all targets",
)
.arg_features()
- .arg_jobs()
+ .arg_parallel()
.arg_release("Check artifacts in release mode, with optimizations")
.arg_profile("Check artifacts with the specified profile")
.arg_target_triple("Check for the target triple")
@@ -37,7 +37,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
- .after_help("Run `cargo help check` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help check</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/clean.rs b/src/tools/cargo/src/bin/cargo/commands/clean.rs
index 9fa3c8527..8596561c9 100644
--- a/src/tools/cargo/src/bin/cargo/commands/clean.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/clean.rs
@@ -14,7 +14,10 @@ pub fn cli() -> Command {
.arg_target_triple("Target triple to clean output for")
.arg_target_dir()
.arg_manifest_path()
- .after_help("Run `cargo help clean` for more detailed information.\n")
+ .arg_dry_run("Display what would be deleted without deleting anything")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help clean</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -27,10 +30,11 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let opts = CleanOptions {
config,
spec: values(args, "package"),
- targets: args.targets(),
+ targets: args.targets()?,
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Custom)?,
profile_specified: args.contains_id("profile") || args.flag("release"),
doc: args.flag("doc"),
+ dry_run: args.dry_run(),
};
ops::clean(&ws, &opts)?;
Ok(())
diff --git a/src/tools/cargo/src/bin/cargo/commands/doc.rs b/src/tools/cargo/src/bin/cargo/commands/doc.rs
index c3dfe426d..43a6ee950 100644
--- a/src/tools/cargo/src/bin/cargo/commands/doc.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/doc.rs
@@ -32,7 +32,7 @@ pub fn cli() -> Command {
"Document only the specified example",
"Document all examples",
)
- .arg_jobs()
+ .arg_parallel()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_target_triple("Build for the target triple")
@@ -40,7 +40,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
- .after_help("Run `cargo help doc` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help doc</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/fetch.rs b/src/tools/cargo/src/bin/cargo/commands/fetch.rs
index 4b1fcb40f..794dbf9b0 100644
--- a/src/tools/cargo/src/bin/cargo/commands/fetch.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/fetch.rs
@@ -9,7 +9,9 @@ pub fn cli() -> Command {
.arg_quiet()
.arg_target_triple("Fetch dependencies for the target triple")
.arg_manifest_path()
- .after_help("Run `cargo help fetch` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help fetch</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -17,7 +19,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let opts = FetchOptions {
config,
- targets: args.targets(),
+ targets: args.targets()?,
};
let _ = ops::fetch(&ws, &opts)?;
Ok(())
diff --git a/src/tools/cargo/src/bin/cargo/commands/fix.rs b/src/tools/cargo/src/bin/cargo/commands/fix.rs
index 1f98dd67e..0ecf47450 100644
--- a/src/tools/cargo/src/bin/cargo/commands/fix.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/fix.rs
@@ -47,14 +47,16 @@ pub fn cli() -> Command {
"Fix all targets (default)",
)
.arg_features()
- .arg_jobs()
+ .arg_parallel()
.arg_release("Fix artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_target_triple("Fix for the target triple")
.arg_target_dir()
.arg_timings()
.arg_manifest_path()
- .after_help("Run `cargo help fix` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help fix</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/generate_lockfile.rs b/src/tools/cargo/src/bin/cargo/commands/generate_lockfile.rs
index 7d06aad59..4f1382ee5 100644
--- a/src/tools/cargo/src/bin/cargo/commands/generate_lockfile.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/generate_lockfile.rs
@@ -7,7 +7,9 @@ pub fn cli() -> Command {
.about("Generate the lockfile for a package")
.arg_quiet()
.arg_manifest_path()
- .after_help("Run `cargo help generate-lockfile` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help generate-lockfile</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/init.rs b/src/tools/cargo/src/bin/cargo/commands/init.rs
index fdb3dc208..48409d827 100644
--- a/src/tools/cargo/src/bin/cargo/commands/init.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/init.rs
@@ -7,9 +7,11 @@ pub fn cli() -> Command {
.about("Create a new cargo package in an existing directory")
.arg(Arg::new("path").action(ArgAction::Set).default_value("."))
.arg_new_opts()
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .arg_registry("Registry to use")
.arg_quiet()
- .after_help("Run `cargo help init` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help init</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/install.rs b/src/tools/cargo/src/bin/cargo/commands/install.rs
index 8abb00190..2e5163bdc 100644
--- a/src/tools/cargo/src/bin/cargo/commands/install.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/install.rs
@@ -1,24 +1,27 @@
use crate::command_prelude::*;
use anyhow::anyhow;
+use anyhow::bail;
+use anyhow::format_err;
use cargo::core::{GitReference, SourceId, Workspace};
use cargo::ops;
use cargo::util::IntoUrl;
+use cargo::util::ToSemver;
+use cargo::util::VersionReqExt;
+use cargo::CargoResult;
+use semver::VersionReq;
use cargo_util::paths;
pub fn cli() -> Command {
subcommand("install")
.about("Install a Rust binary. Default location is $HOME/.cargo/bin")
- .arg(
- Arg::new("crate")
- .value_parser(clap::builder::NonEmptyStringValueParser::new())
- .num_args(0..),
- )
+ .arg(Arg::new("crate").value_parser(parse_crate).num_args(0..))
.arg(
opt("version", "Specify a version to install")
.alias("vers")
.value_name("VERSION")
+ .value_parser(parse_semver_flag)
.requires("crate"),
)
.arg(
@@ -75,16 +78,19 @@ pub fn cli() -> Command {
"Install all examples",
)
.arg_features()
- .arg_jobs()
+ .arg_parallel()
.arg(flag(
"debug",
"Build in debug mode (with the 'dev' profile) instead of release mode",
))
+ .arg_redundant_default_mode("release", "install", "debug")
.arg_profile("Install artifacts with the specified profile")
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_timings()
- .after_help("Run `cargo help install` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help install</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -102,11 +108,12 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
// but not `Config::reload_rooted_at` which is always cwd)
let path = path.map(|p| paths::normalize_path(&p));
- let version = args.get_one::<String>("version").map(String::as_str);
+ let version = args.get_one::<VersionReq>("version");
let krates = args
- .get_many::<String>("crate")
+ .get_many::<CrateVersion>("crate")
.unwrap_or_default()
- .map(|k| resolve_crate(k, version))
+ .cloned()
+ .map(|(krate, local_version)| resolve_crate(krate, local_version, version))
.collect::<crate::CargoResult<Vec<_>>>()?;
for (crate_name, _) in krates.iter() {
@@ -117,6 +124,16 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
)
.into());
}
+
+ if let Ok(url) = crate_name.into_url() {
+ if matches!(url.scheme(), "http" | "https") {
+ return Err(anyhow!(
+ "invalid package name: `{url}`
+ Use `cargo install --git {url}` if you meant to install from a git repository."
+ )
+ .into());
+ }
+ }
}
let mut from_cwd = false;
@@ -138,10 +155,11 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
} else if krates.is_empty() {
from_cwd = true;
SourceId::for_path(config.cwd())?
- } else if let Some(index) = args.get_one::<String>("index") {
- SourceId::for_registry(&index.into_url()?)?
- } else if let Some(registry) = args.registry(config)? {
- SourceId::alt_registry(config, &registry)?
+ } else if let Some(reg_or_index) = args.registry_or_index(config)? {
+ match reg_or_index {
+ ops::RegistryOrIndex::Registry(r) => SourceId::alt_registry(config, &r)?,
+ ops::RegistryOrIndex::Index(url) => SourceId::for_registry(&url)?,
+ }
} else {
SourceId::crates_io(config)?
};
@@ -190,20 +208,86 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
Ok(())
}
-fn resolve_crate<'k>(
- mut krate: &'k str,
- mut version: Option<&'k str>,
-) -> crate::CargoResult<(&'k str, Option<&'k str>)> {
- if let Some((k, v)) = krate.split_once('@') {
- if version.is_some() {
- anyhow::bail!("cannot specify both `@{v}` and `--version`");
- }
+type CrateVersion = (String, Option<VersionReq>);
+
+fn parse_crate(krate: &str) -> crate::CargoResult<CrateVersion> {
+ let (krate, version) = if let Some((k, v)) = krate.split_once('@') {
if k.is_empty() {
// by convention, arguments starting with `@` are response files
- anyhow::bail!("missing crate name for `@{v}`");
+ anyhow::bail!("missing crate name before '@'");
}
- krate = k;
- version = Some(v);
+ let krate = k.to_owned();
+ let version = Some(parse_semver_flag(v)?);
+ (krate, version)
+ } else {
+ let krate = krate.to_owned();
+ let version = None;
+ (krate, version)
+ };
+
+ if krate.is_empty() {
+ anyhow::bail!("crate name is empty");
}
+
+ Ok((krate, version))
+}
+
+/// Parses x.y.z as if it were =x.y.z, and gives CLI-specific error messages in the case of invalid
+/// values.
+fn parse_semver_flag(v: &str) -> CargoResult<VersionReq> {
+ // If the version begins with character <, >, =, ^, ~ parse it as a
+ // version range, otherwise parse it as a specific version
+ let first = v
+ .chars()
+ .next()
+ .ok_or_else(|| format_err!("no version provided for the `--version` flag"))?;
+
+ let is_req = "<>=^~".contains(first) || v.contains('*');
+ if is_req {
+ match v.parse::<VersionReq>() {
+ Ok(v) => Ok(v),
+ Err(_) => bail!(
+ "the `--version` provided, `{}`, is \
+ not a valid semver version requirement\n\n\
+ Please have a look at \
+ https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html \
+ for the correct format",
+ v
+ ),
+ }
+ } else {
+ match v.to_semver() {
+ Ok(v) => Ok(VersionReq::exact(&v)),
+ Err(e) => {
+ let mut msg = e.to_string();
+
+ // If it is not a valid version but it is a valid version
+ // requirement, add a note to the warning
+ if v.parse::<VersionReq>().is_ok() {
+ msg.push_str(&format!(
+ "\n\n tip: if you want to specify SemVer range, \
+ add an explicit qualifier, like '^{}'",
+ v
+ ));
+ }
+ bail!(msg);
+ }
+ }
+ }
+}
+
+fn resolve_crate(
+ krate: String,
+ local_version: Option<VersionReq>,
+ version: Option<&VersionReq>,
+) -> crate::CargoResult<CrateVersion> {
+ let version = match (local_version, version) {
+ (Some(_), Some(_)) => {
+ anyhow::bail!("cannot specify both `@<VERSION>` and `--version <VERSION>`");
+ }
+ (Some(l), None) => Some(l),
+ (None, Some(g)) => Some(g.to_owned()),
+ (None, None) => None,
+ };
Ok((krate, version))
}
diff --git a/src/tools/cargo/src/bin/cargo/commands/locate_project.rs b/src/tools/cargo/src/bin/cargo/commands/locate_project.rs
index 69f015300..217bdcac9 100644
--- a/src/tools/cargo/src/bin/cargo/commands/locate_project.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/locate_project.rs
@@ -16,7 +16,9 @@ pub fn cli() -> Command {
)
.arg_quiet()
.arg_manifest_path()
- .after_help("Run `cargo help locate-project` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help locate-project</>` for more detailed information.\n"
+ ))
}
#[derive(Serialize)]
diff --git a/src/tools/cargo/src/bin/cargo/commands/login.rs b/src/tools/cargo/src/bin/cargo/commands/login.rs
index e51adaa1c..118b03310 100644
--- a/src/tools/cargo/src/bin/cargo/commands/login.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/login.rs
@@ -1,24 +1,32 @@
-use crate::command_prelude::*;
-
use cargo::ops;
+use cargo::ops::RegistryOrIndex;
+
+use crate::command_prelude::*;
pub fn cli() -> Command {
subcommand("login")
.about("Log in to a registry.")
.arg(Arg::new("token").action(ArgAction::Set))
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .arg_registry("Registry to use")
.arg(
Arg::new("args")
- .help("Arguments for the credential provider (unstable)")
+ .help("Additional arguments for the credential provider")
.num_args(0..)
.last(true),
)
.arg_quiet()
- .after_help("Run `cargo help login` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help login</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
+ let reg = args.registry_or_index(config)?;
+ assert!(
+ !matches!(reg, Some(RegistryOrIndex::Index(..))),
+ "must not be index URL"
+ );
+
let extra_args = args
.get_many::<String>("args")
.unwrap_or_default()
@@ -27,7 +35,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
ops::registry_login(
config,
args.get_one::<String>("token").map(|s| s.as_str().into()),
- registry.as_deref(),
+ reg.as_ref(),
&extra_args,
)?;
Ok(())
diff --git a/src/tools/cargo/src/bin/cargo/commands/logout.rs b/src/tools/cargo/src/bin/cargo/commands/logout.rs
index 4320240c6..e7bacca86 100644
--- a/src/tools/cargo/src/bin/cargo/commands/logout.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/logout.rs
@@ -1,16 +1,25 @@
-use crate::command_prelude::*;
use cargo::ops;
+use cargo::ops::RegistryOrIndex;
+
+use crate::command_prelude::*;
pub fn cli() -> Command {
subcommand("logout")
.about("Remove an API token from the registry locally")
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .arg_registry("Registry to use")
.arg_quiet()
- .after_help("Run `cargo help logout` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help logout</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
- ops::registry_logout(config, registry.as_deref())?;
+ let reg = args.registry_or_index(config)?;
+ assert!(
+ !matches!(reg, Some(RegistryOrIndex::Index(..))),
+ "must not be index URL"
+ );
+
+ ops::registry_logout(config, reg)?;
Ok(())
}
diff --git a/src/tools/cargo/src/bin/cargo/commands/metadata.rs b/src/tools/cargo/src/bin/cargo/commands/metadata.rs
index 54257dee3..09064de7d 100644
--- a/src/tools/cargo/src/bin/cargo/commands/metadata.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/metadata.rs
@@ -26,7 +26,9 @@ pub fn cli() -> Command {
.arg_quiet()
.arg_features()
.arg_manifest_path()
- .after_help("Run `cargo help metadata` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help metadata</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/new.rs b/src/tools/cargo/src/bin/cargo/commands/new.rs
index 6124444c0..c8d19218f 100644
--- a/src/tools/cargo/src/bin/cargo/commands/new.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/new.rs
@@ -7,9 +7,11 @@ pub fn cli() -> Command {
.about("Create a new cargo package at <path>")
.arg(Arg::new("path").action(ArgAction::Set).required(true))
.arg_new_opts()
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .arg_registry("Registry to use")
.arg_quiet()
- .after_help("Run `cargo help new` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help new</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/owner.rs b/src/tools/cargo/src/bin/cargo/commands/owner.rs
index 223327c31..00080b829 100644
--- a/src/tools/cargo/src/bin/cargo/commands/owner.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/owner.rs
@@ -24,19 +24,20 @@ pub fn cli() -> Command {
.short('r'),
)
.arg(flag("list", "List owners of a crate").short('l'))
- .arg(opt("index", "Registry index to modify owners for").value_name("INDEX"))
+ .arg_index("Registry index URL to modify owners for")
+ .arg_registry("Registry to modify owners for")
.arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
.arg_quiet()
- .after_help("Run `cargo help owner` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help owner</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
let opts = OwnersOptions {
krate: args.get_one::<String>("crate").cloned(),
token: args.get_one::<String>("token").cloned().map(Secret::from),
- index: args.get_one::<String>("index").cloned(),
+ reg_or_index: args.registry_or_index(config)?,
to_add: args
.get_many::<String>("add")
.map(|xs| xs.cloned().collect()),
@@ -44,7 +45,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
.get_many::<String>("remove")
.map(|xs| xs.cloned().collect()),
list: args.flag("list"),
- registry,
};
ops::modify_owners(config, &opts)?;
Ok(())
diff --git a/src/tools/cargo/src/bin/cargo/commands/package.rs b/src/tools/cargo/src/bin/cargo/commands/package.rs
index cf4ac795c..0020e365e 100644
--- a/src/tools/cargo/src/bin/cargo/commands/package.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/package.rs
@@ -33,9 +33,11 @@ pub fn cli() -> Command {
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
- .arg_jobs()
+ .arg_parallel()
.arg_manifest_path()
- .after_help("Run `cargo help package` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help package</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -58,7 +60,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
check_metadata: !args.flag("no-metadata"),
allow_dirty: args.flag("allow-dirty"),
to_package: specs,
- targets: args.targets(),
+ targets: args.targets()?,
jobs: args.jobs()?,
keep_going: args.keep_going(),
cli_features: args.cli_features()?,
diff --git a/src/tools/cargo/src/bin/cargo/commands/pkgid.rs b/src/tools/cargo/src/bin/cargo/commands/pkgid.rs
index ba4540cf1..9d7a6c712 100644
--- a/src/tools/cargo/src/bin/cargo/commands/pkgid.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/pkgid.rs
@@ -10,7 +10,9 @@ pub fn cli() -> Command {
.arg_quiet()
.arg_package("Argument to get the package ID specifier for")
.arg_manifest_path()
- .after_help("Run `cargo help pkgid` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help pkgid</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/publish.rs b/src/tools/cargo/src/bin/cargo/commands/publish.rs
index bda240c8c..8ce2ffc5b 100644
--- a/src/tools/cargo/src/bin/cargo/commands/publish.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/publish.rs
@@ -6,8 +6,8 @@ pub fn cli() -> Command {
subcommand("publish")
.about("Upload a package to the registry")
.arg_dry_run("Perform all checks without uploading")
- .arg_index()
- .arg(opt("registry", "Registry to publish to").value_name("REGISTRY"))
+ .arg_index("Registry index URL to upload the package to")
+ .arg_registry("Registry to upload the package to")
.arg(opt("token", "Token to use when uploading").value_name("TOKEN"))
.arg(flag(
"no-verify",
@@ -20,15 +20,17 @@ pub fn cli() -> Command {
.arg_quiet()
.arg_package("Package to publish")
.arg_features()
- .arg_jobs()
+ .arg_parallel()
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_manifest_path()
- .after_help("Run `cargo help publish` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help publish</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
+ let reg_or_index = args.registry_or_index(config)?;
let ws = args.workspace(config)?;
if ws.root_maybe().is_embedded() {
return Err(anyhow::format_err!(
@@ -37,7 +39,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
)
.into());
}
- let index = args.index()?;
ops::publish(
&ws,
@@ -46,15 +47,14 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
token: args
.get_one::<String>("token")
.map(|s| s.to_string().into()),
- index,
+ reg_or_index,
verify: !args.flag("no-verify"),
allow_dirty: args.flag("allow-dirty"),
to_publish: args.packages_from_flags()?,
- targets: args.targets(),
+ targets: args.targets()?,
jobs: args.jobs()?,
keep_going: args.keep_going(),
dry_run: args.dry_run(),
- registry,
cli_features: args.cli_features()?,
},
)?;
diff --git a/src/tools/cargo/src/bin/cargo/commands/read_manifest.rs b/src/tools/cargo/src/bin/cargo/commands/read_manifest.rs
index a1f42bfb0..6625d60f5 100644
--- a/src/tools/cargo/src/bin/cargo/commands/read_manifest.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/read_manifest.rs
@@ -2,13 +2,13 @@ use crate::command_prelude::*;
pub fn cli() -> Command {
subcommand("read-manifest")
- .about(
+ .about(color_print::cstr!(
"\
Print a JSON representation of a Cargo.toml manifest.
-Deprecated, use `cargo metadata --no-deps` instead.\
-",
- )
+Deprecated, use `<cyan,bold>cargo metadata --no-deps</>` instead.\
+"
+ ))
.arg_quiet()
.arg_manifest_path()
}
diff --git a/src/tools/cargo/src/bin/cargo/commands/remove.rs b/src/tools/cargo/src/bin/cargo/commands/remove.rs
index 798e6fff6..c6508a6b2 100644
--- a/src/tools/cargo/src/bin/cargo/commands/remove.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/remove.rs
@@ -50,6 +50,9 @@ pub fn cli() -> clap::Command {
])
.arg_package("Package to remove from")
.arg_manifest_path()
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help remove</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -216,7 +219,6 @@ fn gc_workspace(workspace: &Workspace<'_>) -> CargoResult<()> {
//
// Example tables:
// - profile.dev.package.foo
- // - profile.release.package."*"
// - profile.release.package."foo:2.1.0"
if let Some(toml_edit::Item::Table(profile_section_table)) = manifest.get_mut("profile") {
profile_section_table.set_implicit(true);
@@ -231,8 +233,14 @@ fn gc_workspace(workspace: &Workspace<'_>) -> CargoResult<()> {
package_table.set_implicit(true);
for (key, item) in package_table.iter_mut() {
+ let key = key.get();
+ // Skip globs. Can't do anything with them.
+ // For example, profile.release.package."*".
+ if crate::util::restricted_names::is_glob_pattern(key) {
+ continue;
+ }
if !spec_has_match(
- &PackageIdSpec::parse(key.get())?,
+ &PackageIdSpec::parse(key)?,
&dependencies,
workspace.config(),
)? {
@@ -280,7 +288,7 @@ fn spec_has_match(
}
let version_matches = match (spec.version(), dep.version()) {
- (Some(v), Some(vq)) => semver::VersionReq::parse(vq)?.matches(v),
+ (Some(v), Some(vq)) => semver::VersionReq::parse(vq)?.matches(&v),
(Some(_), None) => false,
(None, None | Some(_)) => true,
};
diff --git a/src/tools/cargo/src/bin/cargo/commands/report.rs b/src/tools/cargo/src/bin/cargo/commands/report.rs
index 275a8f7c0..bc00d5bb8 100644
--- a/src/tools/cargo/src/bin/cargo/commands/report.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/report.rs
@@ -5,7 +5,9 @@ use cargo::drop_println;
pub fn cli() -> Command {
subcommand("report")
.about("Generate and display various kinds of reports")
- .after_help("Run `cargo help report` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help report</>` for more detailed information.\n"
+ ))
.subcommand_required(true)
.arg_required_else_help(true)
.subcommand(
@@ -42,7 +44,7 @@ fn report_future_incompatibilities(config: &Config, args: &ArgMatches) -> CliRes
.value_of_u32("id")?
.unwrap_or_else(|| reports.last_id());
let krate = args.get_one::<String>("package").map(String::as_str);
- let report = reports.get_report(id, config, krate)?;
+ let report = reports.get_report(id, krate)?;
drop_println!(config, "{}", REPORT_PREAMBLE);
drop(config.shell().print_ansi_stdout(report.as_bytes()));
Ok(())
diff --git a/src/tools/cargo/src/bin/cargo/commands/run.rs b/src/tools/cargo/src/bin/cargo/commands/run.rs
index 1649f72ac..029c9ee56 100644
--- a/src/tools/cargo/src/bin/cargo/commands/run.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/run.rs
@@ -30,7 +30,7 @@ pub fn cli() -> Command {
"Name of the example target to run",
)
.arg_features()
- .arg_jobs()
+ .arg_parallel()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_target_triple("Build for the target triple")
@@ -38,7 +38,9 @@ pub fn cli() -> Command {
.arg_manifest_path()
.arg_unit_graph()
.arg_timings()
- .after_help("Run `cargo help run` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help run</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/rustc.rs b/src/tools/cargo/src/bin/cargo/commands/rustc.rs
index 0a0364e37..60f0b9d60 100644
--- a/src/tools/cargo/src/bin/cargo/commands/rustc.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/rustc.rs
@@ -44,7 +44,7 @@ pub fn cli() -> Command {
"Build all targets",
)
.arg_features()
- .arg_jobs()
+ .arg_parallel()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_target_triple("Target triple which compiles will be for")
@@ -52,7 +52,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
- .after_help("Run `cargo help rustc` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help rustc</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/rustdoc.rs b/src/tools/cargo/src/bin/cargo/commands/rustdoc.rs
index 488256ba7..8cb2f10de 100644
--- a/src/tools/cargo/src/bin/cargo/commands/rustdoc.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/rustdoc.rs
@@ -32,7 +32,7 @@ pub fn cli() -> Command {
"Build all targets",
)
.arg_features()
- .arg_jobs()
+ .arg_parallel()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_target_triple("Build for the target triple")
@@ -40,7 +40,9 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
- .after_help("Run `cargo help rustdoc` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help rustdoc</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/search.rs b/src/tools/cargo/src/bin/cargo/commands/search.rs
index 656172e77..9cacfc7e8 100644
--- a/src/tools/cargo/src/bin/cargo/commands/search.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/search.rs
@@ -15,15 +15,16 @@ pub fn cli() -> Command {
)
.value_name("LIMIT"),
)
- .arg_index()
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .arg_index("Registry index URL to search packages in")
+ .arg_registry("Registry to search packages in")
.arg_quiet()
- .after_help("Run `cargo help search` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help search</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
- let index = args.index()?;
+ let reg_or_index = args.registry_or_index(config)?;
let limit = args.value_of_u32("limit")?;
let limit = min(100, limit.unwrap_or(10));
let query: Vec<&str> = args
@@ -32,6 +33,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
.map(String::as_str)
.collect();
let query: String = query.join("+");
- ops::search(&query, config, index, limit, registry)?;
+ ops::search(&query, config, reg_or_index, limit)?;
Ok(())
}
diff --git a/src/tools/cargo/src/bin/cargo/commands/test.rs b/src/tools/cargo/src/bin/cargo/commands/test.rs
index 80c935d62..3c7af506d 100644
--- a/src/tools/cargo/src/bin/cargo/commands/test.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/test.rs
@@ -48,8 +48,8 @@ pub fn cli() -> Command {
"Test all targets (does not include doctests)",
)
.arg_features()
- .arg_jobs_without_keep_going()
- .arg(flag("keep-going", "Use `--no-fail-fast` instead").hide(true)) // See rust-lang/cargo#11702
+ .arg_jobs()
+ .arg_unsupported_keep_going()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_profile("Build artifacts with the specified profile")
.arg_target_triple("Build for the target triple")
@@ -57,25 +57,15 @@ pub fn cli() -> Command {
.arg_unit_graph()
.arg_timings()
.arg_manifest_path()
- .after_help(
- "Run `cargo help test` for more detailed information.\n\
- Run `cargo test -- --help` for test binary options.\n",
- )
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help test</>` for more detailed information.\n\
+ Run `<cyan,bold>cargo test -- --help</>` for test binary options.\n",
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
- if args.keep_going() {
- return Err(anyhow::format_err!(
- "\
-unexpected argument `--keep-going` found
-
- tip: to run as many tests as possible without failing fast, use `--no-fail-fast`"
- )
- .into());
- }
-
let mut compile_opts = args.compile_options(
config,
CompileMode::Test,
diff --git a/src/tools/cargo/src/bin/cargo/commands/tree.rs b/src/tools/cargo/src/bin/cargo/commands/tree.rs
index 4472765a9..1fe6a3a14 100644
--- a/src/tools/cargo/src/bin/cargo/commands/tree.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/tree.rs
@@ -96,7 +96,9 @@ pub fn cli() -> Command {
Pass `all` to include all targets.",
)
.arg_manifest_path()
- .after_help("Run `cargo help tree` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help tree</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -136,7 +138,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
.warn("the --all-targets flag has been changed to --target=all")?;
vec!["all".to_string()]
} else {
- args._values_of("target")
+ args.targets()?
};
let target = tree::Target::from_cli(targets);
diff --git a/src/tools/cargo/src/bin/cargo/commands/uninstall.rs b/src/tools/cargo/src/bin/cargo/commands/uninstall.rs
index 398979bf4..9585d290b 100644
--- a/src/tools/cargo/src/bin/cargo/commands/uninstall.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/uninstall.rs
@@ -13,7 +13,9 @@ pub fn cli() -> Command {
multi_opt("bin", "NAME", "Only uninstall the binary NAME")
.help_heading(heading::TARGET_SELECTION),
)
- .after_help("Run `cargo help uninstall` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help uninstall</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/update.rs b/src/tools/cargo/src/bin/cargo/commands/update.rs
index 31175ef16..e06e8e51e 100644
--- a/src/tools/cargo/src/bin/cargo/commands/update.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/update.rs
@@ -1,26 +1,39 @@
use crate::command_prelude::*;
+use anyhow::anyhow;
use cargo::ops::{self, UpdateOptions};
use cargo::util::print_available_packages;
pub fn cli() -> Command {
subcommand("update")
.about("Update dependencies as recorded in the local lock file")
+ .args([clap::Arg::new("package2")
+ .action(clap::ArgAction::Append)
+ .num_args(1..)
+ .value_name("SPEC")
+ .help_heading(heading::PACKAGE_SELECTION)
+ .group("package-group")
+ .help("Package to update")])
+ .arg(
+ optional_multi_opt("package", "SPEC", "Package to update")
+ .short('p')
+ .hide(true)
+ .help_heading(heading::PACKAGE_SELECTION)
+ .group("package-group"),
+ )
.arg_dry_run("Don't actually write the lockfile")
.arg(
flag(
- "aggressive",
- "Force updating all dependencies of SPEC as well when used with -p",
+ "recursive",
+ "Force updating all dependencies of [SPEC]... as well",
)
+ .alias("aggressive")
.conflicts_with("precise"),
)
.arg(
- opt(
- "precise",
- "Update a single dependency to exactly PRECISE when used with -p",
- )
- .value_name("PRECISE")
- .requires("package"),
+ opt("precise", "Update [SPEC] to exactly PRECISE")
+ .value_name("PRECISE")
+ .requires("package-group"),
)
.arg_quiet()
.arg(
@@ -28,9 +41,10 @@ pub fn cli() -> Command {
.short('w')
.help_heading(heading::PACKAGE_SELECTION),
)
- .arg_package_spec_simple("Package to update")
.arg_manifest_path()
- .after_help("Run `cargo help update` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help update</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -40,10 +54,26 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
print_available_packages(&ws)?;
}
+ let to_update = if args.contains_id("package") {
+ "package"
+ } else {
+ "package2"
+ };
+ let to_update = values(args, to_update);
+ for crate_name in to_update.iter() {
+ if let Some(toolchain) = crate_name.strip_prefix("+") {
+ return Err(anyhow!(
+ "invalid character `+` in package name: `+{toolchain}`
+ Use `cargo +{toolchain} update` if you meant to use the `{toolchain}` toolchain."
+ )
+ .into());
+ }
+ }
+
let update_opts = UpdateOptions {
- aggressive: args.flag("aggressive"),
+ recursive: args.flag("recursive"),
precise: args.get_one::<String>("precise").map(String::as_str),
- to_update: values(args, "package"),
+ to_update,
dry_run: args.dry_run(),
workspace: args.flag("workspace"),
config,
diff --git a/src/tools/cargo/src/bin/cargo/commands/vendor.rs b/src/tools/cargo/src/bin/cargo/commands/vendor.rs
index 69b4ee380..3f9c2dcaf 100644
--- a/src/tools/cargo/src/bin/cargo/commands/vendor.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/vendor.rs
@@ -32,13 +32,27 @@ pub fn cli() -> Command {
"versioned-dirs",
"Always include version in subdir name",
))
- .arg(flag("no-merge-sources", "Not supported").hide(true))
- .arg(flag("relative-path", "Not supported").hide(true))
- .arg(flag("only-git-deps", "Not supported").hide(true))
- .arg(flag("disallow-duplicates", "Not supported").hide(true))
- .arg_quiet()
+ .arg(unsupported("no-merge-sources"))
+ .arg(unsupported("relative-path"))
+ .arg(unsupported("only-git-deps"))
+ .arg(unsupported("disallow-duplicates"))
+ .arg_quiet_without_unknown_silent_arg_tip()
.arg_manifest_path()
- .after_help("Run `cargo help vendor` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help vendor</>` for more detailed information.\n"
+ ))
+}
+
+fn unsupported(name: &'static str) -> Arg {
+ // When we moved `cargo vendor` into Cargo itself we didn't stabilize a few
+ // flags, so try to provide a helpful error message in that case to ensure
+ // that users currently using the flag aren't tripped up.
+ let value_parser = clap::builder::UnknownArgumentValueParser::suggest("the crates.io `cargo vendor` command has been merged into Cargo")
+ .and_suggest(format!("and the flag `--{name}` isn't supported currently"))
+ .and_suggest("to continue using the flag, execute `cargo-vendor vendor ...`")
+ .and_suggest("to suggest this flag supported in Cargo, file an issue at <https://github.com/rust-lang/cargo/issues/new>");
+
+ flag(name, "").value_parser(value_parser).hide(true)
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
@@ -50,34 +64,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
config.values_mut()?.remove("source");
}
- // When we moved `cargo vendor` into Cargo itself we didn't stabilize a few
- // flags, so try to provide a helpful error message in that case to ensure
- // that users currently using the flag aren't tripped up.
- let crates_io_cargo_vendor_flag = if args.flag("no-merge-sources") {
- Some("--no-merge-sources")
- } else if args.flag("relative-path") {
- Some("--relative-path")
- } else if args.flag("only-git-deps") {
- Some("--only-git-deps")
- } else if args.flag("disallow-duplicates") {
- Some("--disallow-duplicates")
- } else {
- None
- };
- if let Some(flag) = crates_io_cargo_vendor_flag {
- return Err(anyhow::format_err!(
- "\
-the crates.io `cargo vendor` command has now been merged into Cargo itself
-and does not support the flag `{}` currently; to continue using the flag you
-can execute `cargo-vendor vendor ...`, and if you would like to see this flag
-supported in Cargo itself please feel free to file an issue at
-https://github.com/rust-lang/cargo/issues/new
-",
- flag
- )
- .into());
- }
-
let ws = args.workspace(config)?;
let path = args
.get_one::<PathBuf>("path")
diff --git a/src/tools/cargo/src/bin/cargo/commands/verify_project.rs b/src/tools/cargo/src/bin/cargo/commands/verify_project.rs
index 4d5492606..35bb747a4 100644
--- a/src/tools/cargo/src/bin/cargo/commands/verify_project.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/verify_project.rs
@@ -8,7 +8,9 @@ pub fn cli() -> Command {
.about("Check correctness of crate manifest")
.arg_quiet()
.arg_manifest_path()
- .after_help("Run `cargo help verify-project` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help verify-project</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/version.rs b/src/tools/cargo/src/bin/cargo/commands/version.rs
index ac1681f5b..65e1c6c47 100644
--- a/src/tools/cargo/src/bin/cargo/commands/version.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/version.rs
@@ -5,7 +5,9 @@ pub fn cli() -> Command {
subcommand("version")
.about("Show version information")
.arg_quiet()
- .after_help("Run `cargo help version` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help version</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
diff --git a/src/tools/cargo/src/bin/cargo/commands/yank.rs b/src/tools/cargo/src/bin/cargo/commands/yank.rs
index e6700bd2f..62d1821c3 100644
--- a/src/tools/cargo/src/bin/cargo/commands/yank.rs
+++ b/src/tools/cargo/src/bin/cargo/commands/yank.rs
@@ -16,16 +16,16 @@ pub fn cli() -> Command {
"undo",
"Undo a yank, putting a version back into the index",
))
- .arg(opt("index", "Registry index to yank from").value_name("INDEX"))
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .arg_index("Registry index URL to yank from")
+ .arg_registry("Registry to yank from")
.arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
.arg_quiet()
- .after_help("Run `cargo help yank` for more detailed information.\n")
+ .after_help(color_print::cstr!(
+ "Run `<cyan,bold>cargo help yank</>` for more detailed information.\n"
+ ))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
-
let (krate, version) = resolve_crate(
args.get_one::<String>("crate").map(String::as_str),
args.get_one::<String>("version").map(String::as_str),
@@ -39,9 +39,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
krate.map(|s| s.to_string()),
version.map(|s| s.to_string()),
args.get_one::<String>("token").cloned().map(Secret::from),
- args.get_one::<String>("index").cloned(),
+ args.registry_or_index(config)?,
args.flag("undo"),
- registry,
)?;
Ok(())
}
diff --git a/src/tools/cargo/src/bin/cargo/main.rs b/src/tools/cargo/src/bin/cargo/main.rs
index d96c1423d..16e4f24f3 100644
--- a/src/tools/cargo/src/bin/cargo/main.rs
+++ b/src/tools/cargo/src/bin/cargo/main.rs
@@ -41,10 +41,12 @@ fn setup_logger() {
let env = tracing_subscriber::EnvFilter::from_env("CARGO_LOG");
tracing_subscriber::fmt()
+ .with_timer(tracing_subscriber::fmt::time::Uptime::default())
.with_ansi(std::io::IsTerminal::is_terminal(&std::io::stderr()))
.with_writer(std::io::stderr)
.with_env_filter(env)
.init();
+ tracing::trace!(start = humantime::format_rfc3339(std::time::SystemTime::now()).to_string());
}
/// Table for defining the aliases which come builtin in `Cargo`.
@@ -104,17 +106,18 @@ fn list_commands(config: &Config) -> BTreeMap<String, CommandInfo> {
};
for entry in entries.filter_map(|e| e.ok()) {
let path = entry.path();
- let filename = match path.file_name().and_then(|s| s.to_str()) {
- Some(filename) => filename,
- _ => continue,
+ let Some(filename) = path.file_name().and_then(|s| s.to_str()) else {
+ continue;
};
- if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
+ let Some(name) = filename
+ .strip_prefix(prefix)
+ .and_then(|s| s.strip_suffix(suffix))
+ else {
continue;
- }
+ };
if is_executable(entry.path()) {
- let end = filename.len() - suffix.len();
commands.insert(
- filename[prefix.len()..end].to_string(),
+ name.to_string(),
CommandInfo::External { path: path.clone() },
);
}
diff --git a/src/tools/cargo/src/cargo/core/compiler/build_config.rs b/src/tools/cargo/src/cargo/core/compiler/build_config.rs
index 5d4d754bf..f091df2ad 100644
--- a/src/tools/cargo/src/cargo/core/compiler/build_config.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/build_config.rs
@@ -7,7 +7,7 @@ use cargo_util::ProcessBuilder;
use serde::ser;
use std::cell::RefCell;
use std::path::PathBuf;
-use std::sync::Arc;
+use std::rc::Rc;
use std::thread::available_parallelism;
/// Configuration information for a rustc build.
@@ -35,7 +35,7 @@ pub struct BuildConfig {
pub primary_unit_rustc: Option<ProcessBuilder>,
/// A thread used by `cargo fix` to receive messages on a socket regarding
/// the success/failure of applying fixes.
- pub rustfix_diagnostic_server: Arc<RefCell<Option<RustfixDiagnosticServer>>>,
+ pub rustfix_diagnostic_server: Rc<RefCell<Option<RustfixDiagnosticServer>>>,
/// The directory to copy final artifacts to. Note that even if `out_dir` is
/// set, a copy of artifacts still could be found a `target/(debug\release)`
/// as usual.
@@ -113,7 +113,7 @@ impl BuildConfig {
build_plan: false,
unit_graph: false,
primary_unit_rustc: None,
- rustfix_diagnostic_server: Arc::new(RefCell::new(None)),
+ rustfix_diagnostic_server: Rc::new(RefCell::new(None)),
export_dir: None,
future_incompat_report: false,
timing_outputs: Vec::new(),
diff --git a/src/tools/cargo/src/cargo/core/compiler/build_context/mod.rs b/src/tools/cargo/src/cargo/core/compiler/build_context/mod.rs
index f35084e2b..19dee718b 100644
--- a/src/tools/cargo/src/cargo/core/compiler/build_context/mod.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/build_context/mod.rs
@@ -10,7 +10,6 @@ use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
use crate::util::Rustc;
use std::collections::{HashMap, HashSet};
-use std::path::PathBuf;
mod target_info;
pub use self::target_info::{
@@ -120,15 +119,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
&self.target_data.rustc
}
- /// Gets the user-specified linker for a particular host or target.
- pub fn linker(&self, kind: CompileKind) -> Option<PathBuf> {
- self.target_data
- .target_config(kind)
- .linker
- .as_ref()
- .map(|l| l.val.clone().resolve_program(self.config))
- }
-
/// Gets the host architecture triple.
///
/// For example, x86_64-unknown-linux-gnu, would be
diff --git a/src/tools/cargo/src/cargo/core/compiler/build_context/target_info.rs b/src/tools/cargo/src/cargo/core/compiler/build_context/target_info.rs
index 754adcf3c..c3b3dd48a 100644
--- a/src/tools/cargo/src/cargo/core/compiler/build_context/target_info.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/build_context/target_info.rs
@@ -367,9 +367,8 @@ impl TargetInfo {
&*v.insert(value)
}
};
- let (prefix, suffix) = match *crate_type_info {
- Some((ref prefix, ref suffix)) => (prefix, suffix),
- None => return Ok(None),
+ let Some((prefix, suffix)) = crate_type_info else {
+ return Ok(None);
};
let mut ret = vec![FileType {
suffix: suffix.clone(),
@@ -466,7 +465,7 @@ impl TargetInfo {
// the names to match.
should_replace_hyphens: false,
})
- } else if target_triple.ends_with("-msvc") {
+ } else if target_triple.ends_with("-msvc") || target_triple.ends_with("-uefi") {
ret.push(FileType {
suffix: ".pdb".to_string(),
prefix: prefix.clone(),
@@ -612,13 +611,12 @@ fn parse_crate_type(
if not_supported {
return Ok(None);
}
- let line = match lines.next() {
- Some(line) => line,
- None => anyhow::bail!(
+ let Some(line) = lines.next() else {
+ anyhow::bail!(
"malformed output when learning about crate-type {} information\n{}",
crate_type,
output_err_info(cmd, output, error)
- ),
+ )
};
let mut parts = line.trim().split("___");
let prefix = parts.next().unwrap();
@@ -948,7 +946,7 @@ impl<'cfg> RustcTargetData<'cfg> {
}
/// Insert `kind` into our `target_info` and `target_config` members if it isn't present yet.
- fn merge_compile_kind(&mut self, kind: CompileKind) -> CargoResult<()> {
+ pub fn merge_compile_kind(&mut self, kind: CompileKind) -> CargoResult<()> {
if let CompileKind::Target(target) = kind {
if !self.target_config.contains_key(&target) {
self.target_config
@@ -978,9 +976,8 @@ impl<'cfg> RustcTargetData<'cfg> {
pub fn dep_platform_activated(&self, dep: &Dependency, kind: CompileKind) -> bool {
// If this dependency is only available for certain platforms,
// make sure we're only enabling it for that platform.
- let platform = match dep.platform() {
- Some(p) => p,
- None => return true,
+ let Some(platform) = dep.platform() else {
+ return true;
};
let name = self.short_name(&kind);
platform.matches(name, self.cfg(kind))
@@ -1058,13 +1055,12 @@ impl RustDocFingerprint {
serde_json::to_string(&actual_rustdoc_target_data)?,
)
};
- let rustdoc_data = match paths::read(&fingerprint_path) {
- Ok(rustdoc_data) => rustdoc_data,
+ let Ok(rustdoc_data) = paths::read(&fingerprint_path) else {
// If the fingerprint does not exist, do not clear out the doc
// directories. Otherwise this ran into problems where projects
// like rustbuild were creating the doc directory before running
// `cargo doc` in a way that deleting it would break it.
- Err(_) => return write_fingerprint(),
+ return write_fingerprint();
};
match serde_json::from_str::<RustDocFingerprint>(&rustdoc_data) {
Ok(fingerprint) => {
diff --git a/src/tools/cargo/src/cargo/core/compiler/build_plan.rs b/src/tools/cargo/src/cargo/core/compiler/build_plan.rs
index a823aa952..a024d4990 100644
--- a/src/tools/cargo/src/cargo/core/compiler/build_plan.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/build_plan.rs
@@ -86,10 +86,7 @@ impl Invocation {
);
}
for (var, value) in cmd.get_envs() {
- let value = match value {
- Some(s) => s,
- None => continue,
- };
+ let Some(value) = value else { continue };
self.env.insert(
var.clone(),
value
diff --git a/src/tools/cargo/src/cargo/core/compiler/compilation.rs b/src/tools/cargo/src/cargo/core/compiler/compilation.rs
index b263119b0..e03a08d39 100644
--- a/src/tools/cargo/src/cargo/core/compiler/compilation.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/compilation.rs
@@ -104,6 +104,8 @@ pub struct Compilation<'cfg> {
primary_rustc_process: Option<ProcessBuilder>,
target_runners: HashMap<CompileKind, Option<(PathBuf, Vec<String>)>>,
+ /// The linker to use for each host or target.
+ target_linkers: HashMap<CompileKind, Option<PathBuf>>,
}
impl<'cfg> Compilation<'cfg> {
@@ -150,6 +152,13 @@ impl<'cfg> Compilation<'cfg> {
.chain(Some(&CompileKind::Host))
.map(|kind| Ok((*kind, target_runner(bcx, *kind)?)))
.collect::<CargoResult<HashMap<_, _>>>()?,
+ target_linkers: bcx
+ .build_config
+ .requested_kinds
+ .iter()
+ .chain(Some(&CompileKind::Host))
+ .map(|kind| Ok((*kind, target_linker(bcx, *kind)?)))
+ .collect::<CargoResult<HashMap<_, _>>>()?,
})
}
@@ -221,6 +230,11 @@ impl<'cfg> Compilation<'cfg> {
self.target_runners.get(&kind).and_then(|x| x.as_ref())
}
+ /// Gets the user-specified linker for a particular host or target.
+ pub fn target_linker(&self, kind: CompileKind) -> Option<PathBuf> {
+ self.target_linkers.get(&kind).and_then(|x| x.clone())
+ }
+
/// Returns a [`ProcessBuilder`] appropriate for running a process for the
/// target platform. This is typically used for `cargo run` and `cargo
/// test`.
@@ -312,6 +326,7 @@ impl<'cfg> Compilation<'cfg> {
// crate properties which might require rebuild upon change
// consider adding the corresponding properties to the hash
// in BuildContext::target_metadata()
+ let rust_version = pkg.rust_version().as_ref().map(ToString::to_string);
cmd.env("CARGO_MANIFEST_DIR", pkg.root())
.env("CARGO_PKG_VERSION_MAJOR", &pkg.version().major.to_string())
.env("CARGO_PKG_VERSION_MINOR", &pkg.version().minor.to_string())
@@ -342,7 +357,7 @@ impl<'cfg> Compilation<'cfg> {
.env("CARGO_PKG_AUTHORS", &pkg.authors().join(":"))
.env(
"CARGO_PKG_RUST_VERSION",
- &pkg.rust_version().unwrap_or(&String::new()),
+ &rust_version.as_deref().unwrap_or_default(),
)
.env(
"CARGO_PKG_README",
@@ -441,3 +456,39 @@ fn target_runner(
)
}))
}
+
+/// Gets the user-specified linker for a particular host or target from the configuration.
+fn target_linker(bcx: &BuildContext<'_, '_>, kind: CompileKind) -> CargoResult<Option<PathBuf>> {
+ // Try host.linker and target.{}.linker.
+ if let Some(path) = bcx
+ .target_data
+ .target_config(kind)
+ .linker
+ .as_ref()
+ .map(|l| l.val.clone().resolve_program(bcx.config))
+ {
+ return Ok(Some(path));
+ }
+
+ // Try target.'cfg(...)'.linker.
+ let target_cfg = bcx.target_data.info(kind).cfg();
+ let mut cfgs = bcx
+ .config
+ .target_cfgs()?
+ .iter()
+ .filter_map(|(key, cfg)| cfg.linker.as_ref().map(|linker| (key, linker)))
+ .filter(|(key, _linker)| CfgExpr::matches_key(key, target_cfg));
+ let matching_linker = cfgs.next();
+ if let Some((key, linker)) = cfgs.next() {
+ anyhow::bail!(
+ "several matching instances of `target.'cfg(..)'.linker` in configurations\n\
+ first match `{}` located in {}\n\
+ second match `{}` located in {}",
+ matching_linker.unwrap().0,
+ matching_linker.unwrap().1.definition,
+ key,
+ linker.definition
+ );
+ }
+ Ok(matching_linker.map(|(_k, linker)| linker.val.clone().resolve_program(bcx.config)))
+}
diff --git a/src/tools/cargo/src/cargo/core/compiler/context/compilation_files.rs b/src/tools/cargo/src/cargo/core/compiler/context/compilation_files.rs
index 126e17112..d83dbf10c 100644
--- a/src/tools/cargo/src/cargo/core/compiler/context/compilation_files.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/context/compilation_files.rs
@@ -547,7 +547,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
/// Gets the metadata hash for the given [`Unit`].
///
-/// Whne a metadata hash doesn't exist for the given unit,
+/// When a metadata hash doesn't exist for the given unit,
/// this calls itself recursively to compute metadata hashes of all its dependencies.
/// See [`compute_metadata`] for how a single metadata hash is computed.
fn metadata_of<'a>(
diff --git a/src/tools/cargo/src/cargo/core/compiler/context/mod.rs b/src/tools/cargo/src/cargo/core/compiler/context/mod.rs
index 3f13f086c..010fe2793 100644
--- a/src/tools/cargo/src/cargo/core/compiler/context/mod.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/context/mod.rs
@@ -272,7 +272,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
unit: unit.clone(),
args,
unstable_opts,
- linker: self.bcx.linker(unit.kind),
+ linker: self.compilation.target_linker(unit.kind).clone(),
script_meta,
env: artifact::get_env(&self, self.unit_deps(unit))?,
});
diff --git a/src/tools/cargo/src/cargo/core/compiler/custom_build.rs b/src/tools/cargo/src/cargo/core/compiler/custom_build.rs
index 85306aaac..3eeeaa0ee 100644
--- a/src/tools/cargo/src/cargo/core/compiler/custom_build.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/custom_build.rs
@@ -240,7 +240,7 @@ fn emit_build_output(
///
/// The construction includes:
///
-/// * Set environment varibles for the build script run.
+/// * Set environment variables for the build script run.
/// * Create the output dir (`OUT_DIR`) for the build script output.
/// * Determine if the build script needs a re-run.
/// * Run the build script and store its output.
@@ -281,7 +281,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
.env("NUM_JOBS", &bcx.jobs().to_string())
.env("TARGET", bcx.target_data.short_name(&unit.kind))
.env("DEBUG", debug.to_string())
- .env("OPT_LEVEL", &unit.profile.opt_level.to_string())
+ .env("OPT_LEVEL", &unit.profile.opt_level)
.env(
"PROFILE",
match unit.profile.root {
@@ -299,11 +299,8 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
cmd.env(&var, value);
}
- if let Some(linker) = &bcx.target_data.target_config(unit.kind).linker {
- cmd.env(
- "RUSTC_LINKER",
- linker.val.clone().resolve_program(bcx.config),
- );
+ if let Some(linker) = &cx.compilation.target_linker(unit.kind) {
+ cmd.env("RUSTC_LINKER", linker);
}
if let Some(links) = unit.pkg.manifest().links() {
@@ -446,7 +443,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
))
})?;
let data = &script_output.metadata;
- for &(ref key, ref value) in data.iter() {
+ for (key, value) in data.iter() {
cmd.env(
&format!("DEP_{}_{}", super::envify(&name), super::envify(key)),
value,
@@ -684,32 +681,24 @@ impl BuildOutput {
Ok(line) => line.trim(),
Err(..) => continue,
};
- let mut iter = line.splitn(2, ':');
- if iter.next() != Some("cargo") {
- // skip this line since it doesn't start with "cargo:"
- continue;
- }
- let data = match iter.next() {
- Some(val) => {
+ let data = match line.split_once(':') {
+ Some(("cargo", val)) => {
if val.starts_with(":") {
// Line started with `cargo::`.
- bail!("unsupported output in {}: `{}`\n\
+ bail!("unsupported output in {whence}: `{line}`\n\
Found a `cargo::key=value` build directive which is reserved for future use.\n\
Either change the directive to `cargo:key=value` syntax (note the single `:`) or upgrade your version of Rust.\n\
See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
- for more information about build script outputs.", whence, line);
+ for more information about build script outputs.");
}
val
}
- None => continue,
+ _ => continue,
};
// getting the `key=value` part of the line
- let mut iter = data.splitn(2, '=');
- let key = iter.next();
- let value = iter.next();
- let (key, value) = match (key, value) {
- (Some(a), Some(b)) => (a, b.trim_end()),
+ let (key, value) = match data.split_once('=') {
+ Some((a,b)) => (a, b.trim_end()),
// Line started with `cargo:` but didn't match `key=value`.
_ => bail!("invalid output in {}: `{}`\n\
Expected a line with `cargo:key=value` with an `=` character, \
@@ -768,9 +757,7 @@ impl BuildOutput {
check_and_add_target!("bin", Target::is_bin, LinkArgTarget::Bin);
}
"rustc-link-arg-bin" => {
- let mut parts = value.splitn(2, '=');
- let bin_name = parts.next().unwrap().to_string();
- let arg = parts.next().ok_or_else(|| {
+ let (bin_name, arg) = value.split_once('=').ok_or_else(|| {
anyhow::format_err!(
"invalid instruction `cargo:{}={}` from {}\n\
The instruction should have the form cargo:{}=BIN=ARG",
@@ -793,7 +780,10 @@ impl BuildOutput {
bin_name
);
}
- linker_args.push((LinkArgTarget::SingleBin(bin_name), arg.to_string()));
+ linker_args.push((
+ LinkArgTarget::SingleBin(bin_name.to_owned()),
+ arg.to_string(),
+ ));
}
"rustc-link-arg-tests" => {
check_and_add_target!("test", Target::is_test, LinkArgTarget::Test);
@@ -837,7 +827,7 @@ impl BuildOutput {
None => return false,
Some(n) => n,
};
- // ALLOWED: the process of rustc boostrapping reads this through
+ // ALLOWED: the process of rustc bootstrapping reads this through
// `std::env`. We should make the behavior consistent. Also, we
// don't advertise this for bypassing nightly.
#[allow(clippy::disallowed_methods)]
@@ -939,12 +929,9 @@ impl BuildOutput {
///
/// [`cargo:rustc-env`]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-env
pub fn parse_rustc_env(value: &str, whence: &str) -> CargoResult<(String, String)> {
- let mut iter = value.splitn(2, '=');
- let name = iter.next();
- let val = iter.next();
- match (name, val) {
- (Some(n), Some(v)) => Ok((n.to_owned(), v.to_owned())),
- _ => bail!("Variable rustc-env has no value in {}: {}", whence, value),
+ match value.split_once('=') {
+ Some((n, v)) => Ok((n.to_owned(), v.to_owned())),
+ _ => bail!("Variable rustc-env has no value in {whence}: {value}"),
}
}
}
diff --git a/src/tools/cargo/src/cargo/core/compiler/fingerprint/mod.rs b/src/tools/cargo/src/cargo/core/compiler/fingerprint/mod.rs
index 2e6fb7eed..b1040be41 100644
--- a/src/tools/cargo/src/cargo/core/compiler/fingerprint/mod.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/fingerprint/mod.rs
@@ -811,9 +811,8 @@ impl LocalFingerprint {
// rustc.
LocalFingerprint::CheckDepInfo { dep_info } => {
let dep_info = target_root.join(dep_info);
- let info = match parse_dep_info(pkg_root, target_root, &dep_info)? {
- Some(info) => info,
- None => return Ok(Some(StaleItem::MissingFile(dep_info))),
+ let Some(info) = parse_dep_info(pkg_root, target_root, &dep_info)? else {
+ return Ok(Some(StaleItem::MissingFile(dep_info)));
};
for (key, previous) in info.env.iter() {
let current = if key == CARGO_ENV {
@@ -1038,16 +1037,16 @@ impl Fingerprint {
for (a, b) in self.deps.iter().zip(old.deps.iter()) {
if a.name != b.name {
return DirtyReason::UnitDependencyNameChanged {
- old: b.name.clone(),
- new: a.name.clone(),
+ old: b.name,
+ new: a.name,
};
}
if a.fingerprint.hash_u64() != b.fingerprint.hash_u64() {
return DirtyReason::UnitDependencyInfoChanged {
- new_name: a.name.clone(),
+ new_name: a.name,
new_fingerprint: a.fingerprint.hash_u64(),
- old_name: b.name.clone(),
+ old_name: b.name,
old_fingerprint: b.fingerprint.hash_u64(),
};
}
@@ -1103,16 +1102,12 @@ impl Fingerprint {
}
let opt_max = mtimes.iter().max_by_key(|kv| kv.1);
- let (max_path, max_mtime) = match opt_max {
- Some(mtime) => mtime,
-
+ let Some((max_path, max_mtime)) = opt_max else {
// We had no output files. This means we're an overridden build
// script and we're just always up to date because we aren't
// watching the filesystem.
- None => {
- self.fs_status = FsStatus::UpToDate { mtimes };
- return Ok(());
- }
+ self.fs_status = FsStatus::UpToDate { mtimes };
+ return Ok(());
};
debug!(
"max output mtime for {:?} is {:?} {}",
@@ -1127,9 +1122,7 @@ impl Fingerprint {
| FsStatus::StaleItem(_)
| FsStatus::StaleDependency { .. }
| FsStatus::StaleDepFingerprint { .. } => {
- self.fs_status = FsStatus::StaleDepFingerprint {
- name: dep.name.clone(),
- };
+ self.fs_status = FsStatus::StaleDepFingerprint { name: dep.name };
return Ok(());
}
};
@@ -1171,7 +1164,7 @@ impl Fingerprint {
);
self.fs_status = FsStatus::StaleDependency {
- name: dep.name.clone(),
+ name: dep.name,
dep_mtime: *dep_mtime,
max_mtime: *max_mtime,
};
@@ -1426,7 +1419,7 @@ fn calculate_normal(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Finger
let m = unit.pkg.manifest().metadata();
let metadata = util::hash_u64((&m.authors, &m.description, &m.homepage, &m.repository));
let mut config = StableHasher::new();
- if let Some(linker) = cx.bcx.linker(unit.kind) {
+ if let Some(linker) = cx.compilation.target_linker(unit.kind) {
linker.hash(&mut config);
}
if unit.mode.is_doc() && cx.bcx.config.cli_unstable().rustdoc_map {
@@ -1771,7 +1764,7 @@ fn compare_old_fingerprint(
/// Logs the result of fingerprint comparison.
///
-/// TODO: Obsolete and mostly superceded by [`DirtyReason`]. Could be removed.
+/// TODO: Obsolete and mostly superseded by [`DirtyReason`]. Could be removed.
fn log_compare(unit: &Unit, compare: &CargoResult<Option<DirtyReason>>) {
match compare {
Ok(None) => {}
@@ -1808,16 +1801,12 @@ pub fn parse_dep_info(
target_root: &Path,
dep_info: &Path,
) -> CargoResult<Option<RustcDepInfo>> {
- let data = match paths::read_bytes(dep_info) {
- Ok(data) => data,
- Err(_) => return Ok(None),
+ let Ok(data) = paths::read_bytes(dep_info) else {
+ return Ok(None);
};
- let info = match EncodedDepInfo::parse(&data) {
- Some(info) => info,
- None => {
- tracing::warn!("failed to parse cargo's dep-info at {:?}", dep_info);
- return Ok(None);
- }
+ let Some(info) = EncodedDepInfo::parse(&data) else {
+ tracing::warn!("failed to parse cargo's dep-info at {:?}", dep_info);
+ return Ok(None);
};
let mut ret = RustcDepInfo::default();
ret.env = info.env;
@@ -1831,7 +1820,7 @@ pub fn parse_dep_info(
Ok(Some(ret))
}
-/// Calcuates the fingerprint of a unit thats contains no dep-info files.
+/// Calculates the fingerprint of a unit thats contains no dep-info files.
fn pkg_fingerprint(bcx: &BuildContext<'_, '_>, pkg: &Package) -> CargoResult<String> {
let source_id = pkg.package_id().source_id();
let sources = bcx.packages.sources();
@@ -1852,9 +1841,8 @@ where
I: IntoIterator,
I::Item: AsRef<Path>,
{
- let reference_mtime = match paths::mtime(reference) {
- Ok(mtime) => mtime,
- Err(..) => return Some(StaleItem::MissingFile(reference.to_path_buf())),
+ let Ok(reference_mtime) = paths::mtime(reference) else {
+ return Some(StaleItem::MissingFile(reference.to_path_buf()));
};
let skipable_dirs = if let Ok(cargo_home) = home::cargo_home() {
@@ -1882,9 +1870,8 @@ where
let path_mtime = match mtime_cache.entry(path.to_path_buf()) {
Entry::Occupied(o) => *o.get(),
Entry::Vacant(v) => {
- let mtime = match paths::mtime_recursive(path) {
- Ok(mtime) => mtime,
- Err(..) => return Some(StaleItem::MissingFile(path.to_path_buf())),
+ let Ok(mtime) = paths::mtime_recursive(path) else {
+ return Some(StaleItem::MissingFile(path.to_path_buf()));
};
*v.insert(mtime)
}
@@ -2156,9 +2143,8 @@ pub fn parse_rustc_dep_info(rustc_dep_info: &Path) -> CargoResult<RustcDepInfo>
for line in contents.lines() {
if let Some(rest) = line.strip_prefix("# env-dep:") {
let mut parts = rest.splitn(2, '=');
- let env_var = match parts.next() {
- Some(s) => s,
- None => continue,
+ let Some(env_var) = parts.next() else {
+ continue;
};
let env_val = match parts.next() {
Some(s) => Some(unescape_env(s)?),
diff --git a/src/tools/cargo/src/cargo/core/compiler/future_incompat.rs b/src/tools/cargo/src/cargo/core/compiler/future_incompat.rs
index ccea28b94..907a0f97d 100644
--- a/src/tools/cargo/src/cargo/core/compiler/future_incompat.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/future_incompat.rs
@@ -34,9 +34,10 @@
//! [2]: https://github.com/rust-lang/rust/blob/9bb6e60d1f1360234aae90c97964c0fa5524f141/compiler/rustc_errors/src/json.rs#L312-L315
use crate::core::compiler::BuildContext;
-use crate::core::{Dependency, PackageId, QueryKind, Workspace};
+use crate::core::{Dependency, PackageId, Workspace};
+use crate::sources::source::QueryKind;
use crate::sources::SourceConfigMap;
-use crate::util::{iter_join, CargoResult, Config};
+use crate::util::{iter_join, CargoResult};
use anyhow::{bail, format_err, Context};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
@@ -223,12 +224,8 @@ impl OnDiskReports {
self.reports.last().map(|r| r.id).unwrap()
}
- pub fn get_report(
- &self,
- id: u32,
- config: &Config,
- package: Option<&str>,
- ) -> CargoResult<String> {
+ /// Returns an ANSI-styled report
+ pub fn get_report(&self, id: u32, package: Option<&str>) -> CargoResult<String> {
let report = self.reports.iter().find(|r| r.id == id).ok_or_else(|| {
let available = iter_join(self.reports.iter().map(|r| r.id.to_string()), ", ");
format_err!(
@@ -266,15 +263,6 @@ impl OnDiskReports {
};
to_display += &package_report;
- let shell = config.shell();
-
- let to_display = if shell.err_supports_color() && shell.out_supports_color() {
- to_display
- } else {
- strip_ansi_escapes::strip(&to_display)
- .map(|v| String::from_utf8(v).expect("utf8"))
- .expect("strip should never fail")
- };
Ok(to_display)
}
}
@@ -332,13 +320,11 @@ fn get_updates(ws: &Workspace<'_>, package_ids: &BTreeSet<PackageId>) -> Option<
let mut summaries = Vec::new();
while !package_ids.is_empty() {
package_ids.retain(|&pkg_id| {
- let source = match sources.get_mut(&pkg_id.source_id()) {
- Some(s) => s,
- None => return false,
+ let Some(source) = sources.get_mut(&pkg_id.source_id()) else {
+ return false;
};
- let dep = match Dependency::parse(pkg_id.name(), None, pkg_id.source_id()) {
- Ok(dep) => dep,
- Err(_) => return false,
+ let Ok(dep) = Dependency::parse(pkg_id.name(), None, pkg_id.source_id()) else {
+ return false;
};
match source.query_vec(&dep, QueryKind::Exact) {
Poll::Ready(Ok(sum)) => {
diff --git a/src/tools/cargo/src/cargo/core/compiler/job_queue/mod.rs b/src/tools/cargo/src/cargo/core/compiler/job_queue/mod.rs
index 26fcd4826..738c8c267 100644
--- a/src/tools/cargo/src/cargo/core/compiler/job_queue/mod.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/job_queue/mod.rs
@@ -941,9 +941,8 @@ impl<'cfg> DrainState<'cfg> {
cx: &mut Context<'_, '_>,
) -> CargoResult<()> {
let outputs = cx.build_script_outputs.lock().unwrap();
- let metadata = match cx.find_build_script_metadata(unit) {
- Some(metadata) => metadata,
- None => return Ok(()),
+ let Some(metadata) = cx.find_build_script_metadata(unit) else {
+ return Ok(());
};
let bcx = &mut cx.bcx;
if let Some(output) = outputs.get(metadata) {
diff --git a/src/tools/cargo/src/cargo/core/compiler/links.rs b/src/tools/cargo/src/cargo/core/compiler/links.rs
index 4cef2eb39..cfbf92ef0 100644
--- a/src/tools/cargo/src/cargo/core/compiler/links.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/links.rs
@@ -27,9 +27,8 @@ pub fn validate_links(resolve: &Resolve, unit_graph: &UnitGraph) -> CargoResult<
if !validated.insert(unit.pkg.package_id()) {
continue;
}
- let lib = match unit.pkg.manifest().links() {
- Some(lib) => lib,
- None => continue,
+ let Some(lib) = unit.pkg.manifest().links() else {
+ continue;
};
if let Some(&prev) = links.get(lib) {
let prev_path = resolve
diff --git a/src/tools/cargo/src/cargo/core/compiler/mod.rs b/src/tools/cargo/src/cargo/core/compiler/mod.rs
index 7024a2ac5..b0f15bd61 100644
--- a/src/tools/cargo/src/cargo/core/compiler/mod.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/mod.rs
@@ -11,7 +11,7 @@
//! like what rustc has done[^1]. Also, no one knows if Cargo really needs that.
//! To be pragmatic, here we list a handful of items you may want to learn:
//!
-//! * [`BuildContext`] is a static context containg all information you need
+//! * [`BuildContext`] is a static context containing all information you need
//! before a build gets started.
//! * [`Context`] is the center of the world, coordinating a running build and
//! collecting information from it.
@@ -19,7 +19,7 @@
//! * [`fingerprint`] not only defines but also executes a set of rules to
//! determine if a re-compile is needed.
//! * [`job_queue`] is where the parallelism, job scheduling, and communication
-//! machinary happen between Cargo and the compiler.
+//! machinery happen between Cargo and the compiler.
//! * [`layout`] defines and manages output artifacts of a build in the filesystem.
//! * [`unit_dependencies`] is for building a dependency graph for compilation
//! from a result of dependency resolution.
@@ -202,7 +202,6 @@ fn compile<'cfg>(
&unit.target,
cx.files().message_cache_path(unit),
cx.bcx.build_config.message_format,
- cx.bcx.config.shell().err_supports_color(),
unit.show_warnings(bcx.config),
);
// Need to link targets on both the dirty and fresh.
@@ -252,7 +251,7 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
let mut rustc = prepare_rustc(cx, unit)?;
let build_plan = cx.bcx.build_config.build_plan;
- let name = unit.pkg.name().to_string();
+ let name = unit.pkg.name();
let buildkey = unit.buildkey();
let outputs = cx.outputs(unit)?;
@@ -543,12 +542,9 @@ fn link_targets(cx: &mut Context<'_, '_>, unit: &Unit, fresh: bool) -> CargoResu
if !src.exists() {
continue;
}
- let dst = match output.hardlink.as_ref() {
- Some(dst) => dst,
- None => {
- destinations.push(src.clone());
- continue;
- }
+ let Some(dst) = output.hardlink.as_ref() else {
+ destinations.push(src.clone());
+ continue;
};
destinations.push(dst.clone());
paths::link_or_copy(src, dst)?;
@@ -634,19 +630,9 @@ where
{
let mut search_path = vec![];
for dir in paths {
- let dir = match dir.to_str() {
- Some(s) => {
- let mut parts = s.splitn(2, '=');
- match (parts.next(), parts.next()) {
- (Some("native"), Some(path))
- | (Some("crate"), Some(path))
- | (Some("dependency"), Some(path))
- | (Some("framework"), Some(path))
- | (Some("all"), Some(path)) => path.into(),
- _ => dir.clone(),
- }
- }
- None => dir.clone(),
+ let dir = match dir.to_str().and_then(|s| s.split_once("=")) {
+ Some(("native" | "crate" | "dependency" | "framework" | "all", path)) => path.into(),
+ _ => dir.clone(),
};
if dir.starts_with(&root_output) {
search_path.push(dir);
@@ -785,7 +771,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
paths::create_dir_all(&doc_dir)?;
let target_desc = unit.target.description_named();
- let name = unit.pkg.name().to_string();
+ let name = unit.pkg.name();
let build_script_outputs = Arc::clone(&cx.build_script_outputs);
let package_id = unit.pkg.package_id();
let manifest_path = PathBuf::from(unit.pkg.manifest_path());
@@ -1117,7 +1103,10 @@ fn build_base_args(cx: &Context<'_, '_>, cmd: &mut ProcessBuilder, unit: &Unit)
cmd,
"-C",
"linker=",
- bcx.linker(unit.kind).as_ref().map(|s| s.as_ref()),
+ cx.compilation
+ .target_linker(unit.kind)
+ .as_ref()
+ .map(|s| s.as_ref()),
);
if incremental {
let dir = cx.files().layout(unit.kind).incremental().as_os_str();
@@ -1328,7 +1317,7 @@ fn add_custom_flags(
cmd.arg("--check-cfg").arg(check_cfg);
}
}
- for &(ref name, ref value) in output.env.iter() {
+ for (name, value) in output.env.iter() {
cmd.env(name, value);
}
}
@@ -1426,8 +1415,6 @@ fn envify(s: &str) -> String {
struct OutputOptions {
/// What format we're emitting from Cargo itself.
format: MessageFormat,
- /// Whether or not to display messages in color.
- color: bool,
/// Where to write the JSON messages to support playback later if the unit
/// is fresh. The file is created lazily so that in the normal case, lots
/// of empty files are not created. If this is None, the output will not
@@ -1449,14 +1436,12 @@ struct OutputOptions {
impl OutputOptions {
fn new(cx: &Context<'_, '_>, unit: &Unit) -> OutputOptions {
- let color = cx.bcx.config.shell().err_supports_color();
let path = cx.files().message_cache_path(unit);
// Remove old cache, ignore ENOENT, which is the common case.
drop(fs::remove_file(&path));
let cache_cell = Some((path, LazyCell::new()));
OutputOptions {
format: cx.bcx.build_config.message_format,
- color,
cache_cell,
show_diagnostics: true,
warnings_seen: 0,
@@ -1596,15 +1581,7 @@ fn on_stderr_line_inner(
if msg.rendered.ends_with('\n') {
msg.rendered.pop();
}
- let rendered = if options.color {
- msg.rendered
- } else {
- // Strip only fails if the Writer fails, which is Cursor
- // on a Vec, which should never fail.
- strip_ansi_escapes::strip(&msg.rendered)
- .map(|v| String::from_utf8(v).expect("utf8"))
- .expect("strip should never fail")
- };
+ let rendered = msg.rendered;
if options.show_diagnostics {
let machine_applicable: bool = msg
.children
@@ -1635,9 +1612,7 @@ fn on_stderr_line_inner(
other: std::collections::BTreeMap<String, serde_json::Value>,
}
if let Ok(mut error) = serde_json::from_str::<CompilerMessage>(compiler_message.get()) {
- error.rendered = strip_ansi_escapes::strip(&error.rendered)
- .map(|v| String::from_utf8(v).expect("utf8"))
- .unwrap_or(error.rendered);
+ error.rendered = anstream::adapter::strip_str(&error.rendered).to_string();
let new_line = serde_json::to_string(&error)?;
let new_msg: Box<serde_json::value::RawValue> = serde_json::from_str(&new_line)?;
compiler_message = new_msg;
@@ -1709,13 +1684,11 @@ fn replay_output_cache(
target: &Target,
path: PathBuf,
format: MessageFormat,
- color: bool,
show_diagnostics: bool,
) -> Work {
let target = target.clone();
let mut options = OutputOptions {
format,
- color,
cache_cell: None,
show_diagnostics,
warnings_seen: 0,
diff --git a/src/tools/cargo/src/cargo/core/compiler/standard_lib.rs b/src/tools/cargo/src/cargo/core/compiler/standard_lib.rs
index c456c58d5..5272c211b 100644
--- a/src/tools/cargo/src/cargo/core/compiler/standard_lib.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/standard_lib.rs
@@ -62,7 +62,7 @@ pub(crate) fn std_crates(config: &Config, units: Option<&[Unit]>) -> Option<Vec<
/// Resolve the standard library dependencies.
pub fn resolve_std<'cfg>(
ws: &Workspace<'cfg>,
- target_data: &RustcTargetData<'cfg>,
+ target_data: &mut RustcTargetData<'cfg>,
build_config: &BuildConfig,
crates: &[String],
) -> CargoResult<(PackageSet<'cfg>, Resolve, ResolvedFeatures)> {
@@ -145,6 +145,7 @@ pub fn resolve_std<'cfg>(
let cli_features = CliFeatures::from_command_line(
&features, /*all_features*/ false, /*uses_default_features*/ false,
)?;
+ let max_rust_version = ws.rust_version();
let resolve = ops::resolve_ws_with_opts(
&std_ws,
target_data,
@@ -153,6 +154,7 @@ pub fn resolve_std<'cfg>(
&specs,
HasDevUnits::No,
crate::core::resolver::features::ForceAllTargets::No,
+ max_rust_version,
)?;
Ok((
resolve.pkg_set,
diff --git a/src/tools/cargo/src/cargo/core/compiler/timings.rs b/src/tools/cargo/src/cargo/core/compiler/timings.rs
index 57ded9bf8..7c388bd10 100644
--- a/src/tools/cargo/src/cargo/core/compiler/timings.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/timings.rs
@@ -8,6 +8,7 @@ use crate::core::compiler::{BuildContext, Context, TimingOutput};
use crate::core::PackageId;
use crate::util::cpu::State;
use crate::util::machine_message::{self, Message};
+use crate::util::style;
use crate::util::{CargoResult, Config};
use anyhow::Context as _;
use cargo_util::paths;
@@ -193,9 +194,8 @@ impl<'cfg> Timings<'cfg> {
// `id` may not always be active. "fresh" units unconditionally
// generate `Message::Finish`, but this active map only tracks dirty
// units.
- let unit_time = match self.active.get_mut(&id) {
- Some(ut) => ut,
- None => return,
+ let Some(unit_time) = self.active.get_mut(&id) else {
+ return;
};
let t = self.start.elapsed().as_secs_f64();
unit_time.rmeta_time = Some(t - unit_time.start);
@@ -211,9 +211,8 @@ impl<'cfg> Timings<'cfg> {
return;
}
// See note above in `unit_rmeta_finished`, this may not always be active.
- let mut unit_time = match self.active.remove(&id) {
- Some(ut) => ut,
- None => return,
+ let Some(mut unit_time) = self.active.remove(&id) else {
+ return;
};
let t = self.start.elapsed().as_secs_f64();
unit_time.duration = t - unit_time.start;
@@ -264,9 +263,8 @@ impl<'cfg> Timings<'cfg> {
if !self.enabled {
return;
}
- let prev = match &mut self.last_cpu_state {
- Some(state) => state,
- None => return,
+ let Some(prev) = &mut self.last_cpu_state else {
+ return;
};
// Don't take samples too frequently, even if requested.
let now = Instant::now();
@@ -352,7 +350,7 @@ impl<'cfg> Timings<'cfg> {
paths::link_or_copy(&filename, &unstamped_filename)?;
self.config
.shell()
- .status_with_color("Timing", msg, termcolor::Color::Cyan)?;
+ .status_with_color("Timing", msg, &style::NOTE)?;
Ok(())
}
diff --git a/src/tools/cargo/src/cargo/core/compiler/unit_dependencies.rs b/src/tools/cargo/src/cargo/core/compiler/unit_dependencies.rs
index 686822356..7116ba207 100644
--- a/src/tools/cargo/src/cargo/core/compiler/unit_dependencies.rs
+++ b/src/tools/cargo/src/cargo/core/compiler/unit_dependencies.rs
@@ -273,10 +273,9 @@ fn compute_deps(
let mut ret = Vec::new();
let mut dev_deps = Vec::new();
for (dep_pkg_id, deps) in state.deps(unit, unit_for) {
- let dep_lib = match calc_artifact_deps(unit, unit_for, dep_pkg_id, &deps, state, &mut ret)?
- {
- Some(lib) => lib,
- None => continue,
+ let Some(dep_lib) = calc_artifact_deps(unit, unit_for, dep_pkg_id, &deps, state, &mut ret)?
+ else {
+ continue;
};
let dep_pkg = state.get(dep_pkg_id);
let mode = check_or_build_mode(unit.mode, dep_lib);
@@ -412,12 +411,9 @@ fn calc_artifact_deps<'a>(
let mut maybe_non_artifact_lib = false;
let artifact_pkg = state.get(dep_id);
for dep in deps {
- let artifact = match dep.artifact() {
- Some(a) => a,
- None => {
- maybe_non_artifact_lib = true;
- continue;
- }
+ let Some(artifact) = dep.artifact() else {
+ maybe_non_artifact_lib = true;
+ continue;
};
has_artifact_lib |= artifact.is_lib();
// Custom build scripts (build/compile) never get artifact dependencies,
@@ -611,9 +607,8 @@ fn compute_deps_doc(
// the documentation of the library being built.
let mut ret = Vec::new();
for (id, deps) in state.deps(unit, unit_for) {
- let dep_lib = match calc_artifact_deps(unit, unit_for, id, &deps, state, &mut ret)? {
- Some(lib) => lib,
- None => continue,
+ let Some(dep_lib) = calc_artifact_deps(unit, unit_for, id, &deps, state, &mut ret)? else {
+ continue;
};
let dep_pkg = state.get(id);
// Rustdoc only needs rmeta files for regular dependencies.
@@ -923,9 +918,8 @@ fn connect_run_custom_build_deps(state: &mut State<'_, '_>) {
{
// This list of dependencies all depend on `unit`, an execution of
// the build script.
- let reverse_deps = match reverse_deps_map.get(unit) {
- Some(set) => set,
- None => continue,
+ let Some(reverse_deps) = reverse_deps_map.get(unit) else {
+ continue;
};
let to_add = reverse_deps
diff --git a/src/tools/cargo/src/cargo/core/dependency.rs b/src/tools/cargo/src/cargo/core/dependency.rs
index c8fee6262..f00bb0590 100644
--- a/src/tools/cargo/src/cargo/core/dependency.rs
+++ b/src/tools/cargo/src/cargo/core/dependency.rs
@@ -12,7 +12,6 @@ use crate::core::compiler::{CompileKind, CompileTarget};
use crate::core::{PackageId, SourceId, Summary};
use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
-use crate::util::toml::StringOrVec;
use crate::util::OptVersionReq;
/// Information about a dependency requested by a Cargo manifest.
@@ -319,8 +318,8 @@ impl Dependency {
}
/// Sets the version requirement for this dependency.
- pub fn set_version_req(&mut self, req: VersionReq) -> &mut Dependency {
- Rc::make_mut(&mut self.inner).req = OptVersionReq::Req(req);
+ pub fn set_version_req(&mut self, req: OptVersionReq) -> &mut Dependency {
+ Rc::make_mut(&mut self.inner).req = req;
self
}
@@ -468,10 +467,7 @@ impl ser::Serialize for Artifact {
SerializedArtifact {
kinds: self.kinds(),
lib: self.is_lib,
- target: self.target.as_ref().map(|t| match t {
- ArtifactTarget::BuildDependencyAssumeTarget => "target",
- ArtifactTarget::Force(target) => target.rustc_target().as_str(),
- }),
+ target: self.target.as_ref().map(ArtifactTarget::as_str),
}
.serialize(s)
}
@@ -479,14 +475,14 @@ impl ser::Serialize for Artifact {
impl Artifact {
pub(crate) fn parse(
- artifacts: &StringOrVec,
+ artifacts: &[impl AsRef<str>],
is_lib: bool,
target: Option<&str>,
) -> CargoResult<Self> {
let kinds = ArtifactKind::validate(
artifacts
.iter()
- .map(|s| ArtifactKind::parse(s))
+ .map(|s| ArtifactKind::parse(s.as_ref()))
.collect::<Result<Vec<_>, _>>()?,
)?;
Ok(Artifact {
@@ -529,6 +525,13 @@ impl ArtifactTarget {
})
}
+ pub fn as_str(&self) -> &str {
+ match self {
+ ArtifactTarget::BuildDependencyAssumeTarget => "target",
+ ArtifactTarget::Force(target) => target.rustc_target().as_str(),
+ }
+ }
+
pub fn to_compile_kind(&self) -> Option<CompileKind> {
self.to_compile_target().map(CompileKind::Target)
}
@@ -539,6 +542,7 @@ impl ArtifactTarget {
ArtifactTarget::Force(target) => Some(*target),
}
}
+
pub(crate) fn to_resolved_compile_kind(
&self,
root_unit_compile_kind: CompileKind,
@@ -575,20 +579,13 @@ impl ser::Serialize for ArtifactKind {
where
S: ser::Serializer,
{
- let out: Cow<'_, str> = match *self {
- ArtifactKind::SelectedBinary(name) => format!("bin:{}", name.as_str()).into(),
- _ => self.crate_type().into(),
- };
- out.serialize(s)
+ self.as_str().serialize(s)
}
}
impl fmt::Display for ArtifactKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(match self {
- ArtifactKind::SelectedBinary(bin_name) => return write!(f, "bin:{bin_name}"),
- _ => self.crate_type(),
- })
+ f.write_str(&self.as_str())
}
}
@@ -604,7 +601,14 @@ impl ArtifactKind {
}
}
- fn parse(kind: &str) -> CargoResult<Self> {
+ pub fn as_str(&self) -> Cow<'static, str> {
+ match *self {
+ ArtifactKind::SelectedBinary(name) => format!("bin:{}", name.as_str()).into(),
+ _ => self.crate_type().into(),
+ }
+ }
+
+ pub fn parse(kind: &str) -> CargoResult<Self> {
Ok(match kind {
"bin" => ArtifactKind::AllBinaries,
"cdylib" => ArtifactKind::Cdylib,
diff --git a/src/tools/cargo/src/cargo/core/features.rs b/src/tools/cargo/src/cargo/core/features.rs
index 9b99d5a15..5faa2087e 100644
--- a/src/tools/cargo/src/cargo/core/features.rs
+++ b/src/tools/cargo/src/cargo/core/features.rs
@@ -518,9 +518,8 @@ impl Features {
) -> CargoResult<()> {
let nightly_features_allowed = self.nightly_features_allowed;
let is_local = self.is_local;
- let (slot, feature) = match self.status(feature_name) {
- Some(p) => p,
- None => bail!("unknown cargo feature `{}`", feature_name),
+ let Some((slot, feature)) = self.status(feature_name) else {
+ bail!("unknown cargo feature `{}`", feature_name)
};
if *slot {
@@ -531,15 +530,9 @@ impl Features {
}
let see_docs = || {
- let url_channel = match channel().as_str() {
- "dev" | "nightly" => "nightly/",
- "beta" => "beta/",
- _ => "",
- };
format!(
- "See https://doc.rust-lang.org/{}cargo/{} for more information \
- about using this feature.",
- url_channel, feature.docs
+ "See {} for more information about using this feature.",
+ cargo_docs_link(feature.docs)
)
};
@@ -718,6 +711,7 @@ unstable_cli_options!(
// All other unstable features.
// Please keep this list lexicographically ordered.
advanced_env: bool = (HIDDEN),
+ asymmetric_token: bool = ("Allows authenticating with asymmetric tokens"),
avoid_dev_deps: bool = ("Avoid installing dev-dependencies if possible"),
binary_dep_depinfo: bool = ("Track changes to dependency artifacts"),
bindeps: bool = ("Allow Cargo packages to depend on bin, cdylib, and staticlib crates, and use the artifacts built by those crates"),
@@ -728,7 +722,6 @@ unstable_cli_options!(
check_cfg: Option<(/*features:*/ bool, /*well_known_names:*/ bool, /*well_known_values:*/ bool, /*output:*/ bool)> = ("Specify scope of compile-time checking of `cfg` names/values"),
codegen_backend: bool = ("Enable the `codegen-backend` option in profiles in .cargo/config.toml file"),
config_include: bool = ("Enable the `include` key in config files"),
- credential_process: bool = ("Add a config setting to fetch registry authentication tokens by calling an external process"),
direct_minimal_versions: bool = ("Resolve minimal dependency versions instead of maximum (direct dependencies only)"),
doctest_xcompile: bool = ("Compile and run doctests for non-host target using runner config"),
dual_proc_macros: bool = ("Build proc-macros for both the host and the target"),
@@ -744,7 +737,6 @@ unstable_cli_options!(
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"),
- registry_auth: bool = ("Authentication for alternative registries, and generate registry authentication tokens using asymmetric cryptography"),
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
rustdoc_scrape_examples: bool = ("Allows Rustdoc to scrape code examples from reverse-dependencies"),
script: bool = ("Enable support for single-file, `.rs` packages"),
@@ -818,13 +810,18 @@ const STABILIZED_TERMINAL_WIDTH: &str =
const STABILISED_SPARSE_REGISTRY: &str = "The sparse protocol is now the default for crates.io";
+const STABILIZED_CREDENTIAL_PROCESS: &str =
+ "Authentication with a credential provider is always available.";
+
+const STABILIZED_REGISTRY_AUTH: &str =
+ "Authenticated registries are available if a credential provider is configured.";
+
fn deserialize_build_std<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
where
D: serde::Deserializer<'de>,
{
- let crates = match <Option<Vec<String>>>::deserialize(deserializer)? {
- Some(list) => list,
- None => return Ok(None),
+ let Some(crates) = <Option<Vec<String>>>::deserialize(deserializer)? else {
+ return Ok(None);
};
let v = crates.join(",");
Ok(Some(
@@ -839,9 +836,8 @@ where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
- let crates = match <Option<Vec<String>>>::deserialize(deserializer)? {
- Some(list) => list,
- None => return Ok(None),
+ let Some(crates) = <Option<Vec<String>>>::deserialize(deserializer)? else {
+ return Ok(None);
};
parse_check_cfg(crates.into_iter()).map_err(D::Error::custom)
@@ -1083,10 +1079,13 @@ impl CliUnstable {
"sparse-registry" => stabilized_warn(k, "1.68", STABILISED_SPARSE_REGISTRY),
"terminal-width" => stabilized_warn(k, "1.68", STABILIZED_TERMINAL_WIDTH),
"doctest-in-workspace" => stabilized_warn(k, "1.72", STABILIZED_DOCTEST_IN_WORKSPACE),
+ "credential-process" => stabilized_warn(k, "1.74", STABILIZED_CREDENTIAL_PROCESS),
+ "registry-auth" => stabilized_warn(k, "1.74", STABILIZED_REGISTRY_AUTH),
// Unstable features
// Sorted alphabetically:
"advanced-env" => self.advanced_env = parse_empty(k, v)?,
+ "asymmetric-token" => self.asymmetric_token = parse_empty(k, v)?,
"avoid-dev-deps" => self.avoid_dev_deps = parse_empty(k, v)?,
"binary-dep-depinfo" => self.binary_dep_depinfo = parse_empty(k, v)?,
"bindeps" => self.bindeps = parse_empty(k, v)?,
@@ -1099,7 +1098,6 @@ impl CliUnstable {
}
"codegen-backend" => self.codegen_backend = parse_empty(k, v)?,
"config-include" => self.config_include = parse_empty(k, v)?,
- "credential-process" => self.credential_process = parse_empty(k, v)?,
"direct-minimal-versions" => self.direct_minimal_versions = parse_empty(k, v)?,
"doctest-xcompile" => self.doctest_xcompile = parse_empty(k, v)?,
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
@@ -1120,7 +1118,6 @@ impl CliUnstable {
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
"publish-timeout" => self.publish_timeout = parse_empty(k, v)?,
- "registry-auth" => self.registry_auth = parse_empty(k, v)?,
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
"rustdoc-scrape-examples" => self.rustdoc_scrape_examples = parse_empty(k, v)?,
"separate-nightlies" => self.separate_nightlies = parse_empty(k, v)?,
@@ -1206,7 +1203,7 @@ pub fn channel() -> String {
if let Ok(override_channel) = env::var("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS") {
return override_channel;
}
- // ALLOWED: the process of rustc boostrapping reads this through
+ // ALLOWED: the process of rustc bootstrapping reads this through
// `std::env`. We should make the behavior consistent. Also, we
// don't advertise this for bypassing nightly.
#[allow(clippy::disallowed_methods)]
@@ -1228,3 +1225,14 @@ pub fn channel() -> String {
fn cargo_use_gitoxide_instead_of_git2() -> bool {
std::env::var_os("__CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2").map_or(false, |value| value == "1")
}
+
+/// Generate a link to Cargo documentation for the current release channel
+/// `path` is the URL component after `https://doc.rust-lang.org/{channel}/cargo/`
+pub fn cargo_docs_link(path: &str) -> String {
+ let url_channel = match channel().as_str() {
+ "dev" | "nightly" => "nightly/",
+ "beta" => "beta/",
+ _ => "",
+ };
+ format!("https://doc.rust-lang.org/{url_channel}cargo/{path}")
+}
diff --git a/src/tools/cargo/src/cargo/core/manifest.rs b/src/tools/cargo/src/cargo/core/manifest.rs
index 5d46a7e06..7886abec3 100644
--- a/src/tools/cargo/src/cargo/core/manifest.rs
+++ b/src/tools/cargo/src/cargo/core/manifest.rs
@@ -19,7 +19,7 @@ use crate::core::{Edition, Feature, Features, WorkspaceConfig};
use crate::util::errors::*;
use crate::util::interning::InternedString;
use crate::util::toml::{TomlManifest, TomlProfiles};
-use crate::util::{short_hash, Config, Filesystem};
+use crate::util::{short_hash, Config, Filesystem, RustVersion};
pub enum EitherManifest {
Real(Manifest),
@@ -58,7 +58,7 @@ pub struct Manifest {
original: Rc<TomlManifest>,
unstable_features: Features,
edition: Edition,
- rust_version: Option<String>,
+ rust_version: Option<RustVersion>,
im_a_teapot: Option<bool>,
default_run: Option<String>,
metabuild: Option<Vec<String>>,
@@ -112,7 +112,7 @@ pub struct ManifestMetadata {
pub documentation: Option<String>, // URL
pub badges: BTreeMap<String, BTreeMap<String, String>>,
pub links: Option<String>,
- pub rust_version: Option<String>,
+ pub rust_version: Option<RustVersion>,
}
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
@@ -401,7 +401,7 @@ impl Manifest {
workspace: WorkspaceConfig,
unstable_features: Features,
edition: Edition,
- rust_version: Option<String>,
+ rust_version: Option<RustVersion>,
im_a_teapot: Option<bool>,
default_run: Option<String>,
original: Rc<TomlManifest>,
@@ -570,8 +570,8 @@ impl Manifest {
self.edition
}
- pub fn rust_version(&self) -> Option<&str> {
- self.rust_version.as_deref()
+ pub fn rust_version(&self) -> Option<&RustVersion> {
+ self.rust_version.as_ref()
}
pub fn custom_metadata(&self) -> Option<&toml::Value> {
diff --git a/src/tools/cargo/src/cargo/core/mod.rs b/src/tools/cargo/src/cargo/core/mod.rs
index e36c678c4..9b56564a7 100644
--- a/src/tools/cargo/src/cargo/core/mod.rs
+++ b/src/tools/cargo/src/cargo/core/mod.rs
@@ -8,7 +8,7 @@ pub use self::package_id_spec::PackageIdSpec;
pub use self::registry::Registry;
pub use self::resolver::{Resolve, ResolveVersion};
pub use self::shell::{Shell, Verbosity};
-pub use self::source::{GitReference, QueryKind, Source, SourceId, SourceMap};
+pub use self::source_id::{GitReference, SourceId};
pub use self::summary::{FeatureMap, FeatureValue, Summary};
pub use self::workspace::{
find_workspace_root, resolve_relative_path, MaybePackage, Workspace, WorkspaceConfig,
@@ -27,6 +27,6 @@ pub mod profiles;
pub mod registry;
pub mod resolver;
pub mod shell;
-pub mod source;
+mod source_id;
pub mod summary;
mod workspace;
diff --git a/src/tools/cargo/src/cargo/core/package.rs b/src/tools/cargo/src/cargo/core/package.rs
index c84941462..76f6c405b 100644
--- a/src/tools/cargo/src/cargo/core/package.rs
+++ b/src/tools/cargo/src/cargo/core/package.rs
@@ -21,9 +21,9 @@ use crate::core::compiler::{CompileKind, RustcTargetData};
use crate::core::dependency::DepKind;
use crate::core::resolver::features::ForceAllTargets;
use crate::core::resolver::{HasDevUnits, Resolve};
-use crate::core::source::MaybePackage;
use crate::core::{Dependency, Manifest, PackageId, SourceId, Target};
-use crate::core::{SourceMap, Summary, Workspace};
+use crate::core::{Summary, Workspace};
+use crate::sources::source::{MaybePackage, SourceMap};
use crate::util::config::PackageCacheLock;
use crate::util::errors::{CargoResult, HttpNotSuccessful};
use crate::util::interning::InternedString;
@@ -31,6 +31,7 @@ use crate::util::network::http::http_handle_and_timeout;
use crate::util::network::http::HttpTimeout;
use crate::util::network::retry::{Retry, RetryResult};
use crate::util::network::sleep::SleepTracker;
+use crate::util::RustVersion;
use crate::util::{self, internal, Config, Progress, ProgressStyle};
pub const MANIFEST_PREAMBLE: &str = "\
@@ -103,7 +104,7 @@ pub struct SerializedPackage {
#[serde(skip_serializing_if = "Option::is_none")]
metabuild: Option<Vec<String>>,
default_run: Option<String>,
- rust_version: Option<String>,
+ rust_version: Option<RustVersion>,
}
impl Package {
@@ -177,7 +178,7 @@ impl Package {
self.targets().iter().any(|target| target.proc_macro())
}
/// Gets the package's minimum Rust version.
- pub fn rust_version(&self) -> Option<&str> {
+ pub fn rust_version(&self) -> Option<&RustVersion> {
self.manifest().rust_version()
}
@@ -262,7 +263,7 @@ impl Package {
metabuild: self.manifest().metabuild().cloned(),
publish: self.publish().as_ref().cloned(),
default_run: self.manifest().default_run().map(|s| s.to_owned()),
- rust_version: self.rust_version().map(|s| s.to_owned()),
+ rust_version: self.rust_version().cloned(),
}
}
}
@@ -337,7 +338,7 @@ pub struct Downloads<'a, 'cfg> {
/// Total bytes for all successfully downloaded packages.
downloaded_bytes: u64,
/// Size (in bytes) and package name of the largest downloaded package.
- largest: (u64, String),
+ largest: (u64, InternedString),
/// Time when downloading started.
start: Instant,
/// Indicates *all* downloads were successful.
@@ -458,7 +459,7 @@ impl<'cfg> PackageSet<'cfg> {
))),
downloads_finished: 0,
downloaded_bytes: 0,
- largest: (0, String::new()),
+ largest: (0, InternedString::new("")),
success: false,
updated_at: Cell::new(Instant::now()),
timeout,
@@ -711,7 +712,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
// happen during `wait_for_download`
let token = self.next;
self.next += 1;
- debug!("downloading {} as {}", id, token);
+ debug!(target: "network", "downloading {} as {}", id, token);
assert!(self.pending_ids.insert(id));
let (mut handle, _timeout) = http_handle_and_timeout(self.set.config)?;
@@ -730,7 +731,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
crate::try_old_curl_http2_pipewait!(self.set.multiplexing, handle);
handle.write_function(move |buf| {
- debug!("{} - {} bytes of data", token, buf.len());
+ debug!(target: "network", "{} - {} bytes of data", token, buf.len());
tls::with(|downloads| {
if let Some(downloads) = downloads {
downloads.pending[&token]
@@ -811,7 +812,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
let (dl, data) = loop {
assert_eq!(self.pending.len(), self.pending_ids.len());
let (token, result) = self.wait_for_curl()?;
- debug!("{} finished with {:?}", token, result);
+ debug!(target: "network", "{} finished with {:?}", token, result);
let (mut dl, handle) = self
.pending
@@ -872,7 +873,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
return Err(e.context(format!("failed to download from `{}`", dl.url)))
}
RetryResult::Retry(sleep) => {
- debug!("download retry {} for {sleep}ms", dl.url);
+ debug!(target: "network", "download retry {} for {sleep}ms", dl.url);
self.sleeping.push(sleep, (dl, handle));
}
}
@@ -890,7 +891,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
self.downloads_finished += 1;
self.downloaded_bytes += dl.total.get();
if dl.total.get() > self.largest.0 {
- self.largest = (dl.total.get(), dl.id.name().to_string());
+ self.largest = (dl.total.get(), dl.id.name());
}
// We're about to synchronously extract the crate below. While we're
@@ -968,7 +969,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
.perform()
.with_context(|| "failed to perform http requests")
})?;
- debug!("handles remaining: {}", n);
+ debug!(target: "network", "handles remaining: {}", n);
let results = &mut self.results;
let pending = &self.pending;
self.set.multi.messages(|msg| {
@@ -977,7 +978,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
if let Some(result) = msg.result_for(handle) {
results.push((token, result));
} else {
- debug!("message without a result (?)");
+ debug!(target: "network", "message without a result (?)");
}
});
@@ -987,7 +988,7 @@ impl<'a, 'cfg> Downloads<'a, 'cfg> {
assert_ne!(self.remaining(), 0);
if self.pending.is_empty() {
let delay = self.sleeping.time_to_next().unwrap();
- debug!("sleeping main thread for {delay:?}");
+ debug!(target: "network", "sleeping main thread for {delay:?}");
std::thread::sleep(delay);
} else {
let min_timeout = Duration::new(1, 0);
diff --git a/src/tools/cargo/src/cargo/core/package_id.rs b/src/tools/cargo/src/cargo/core/package_id.rs
index e17a73e68..ca126172c 100644
--- a/src/tools/cargo/src/cargo/core/package_id.rs
+++ b/src/tools/cargo/src/cargo/core/package_id.rs
@@ -10,7 +10,7 @@ use std::sync::OnceLock;
use serde::de;
use serde::ser;
-use crate::core::source::SourceId;
+use crate::core::SourceId;
use crate::util::interning::InternedString;
use crate::util::{CargoResult, ToSemver};
@@ -85,14 +85,12 @@ impl<'de> de::Deserialize<'de> for PackageId {
let mut s = string.splitn(3, ' ');
let name = s.next().unwrap();
let name = InternedString::new(name);
- let version = match s.next() {
- Some(s) => s,
- None => return Err(de::Error::custom("invalid serialized PackageId")),
+ let Some(version) = s.next() else {
+ return Err(de::Error::custom("invalid serialized PackageId"));
};
let version = version.to_semver().map_err(de::Error::custom)?;
- let url = match s.next() {
- Some(s) => s,
- None => return Err(de::Error::custom("invalid serialized PackageId")),
+ let Some(url) = s.next() else {
+ return Err(de::Error::custom("invalid serialized PackageId"));
};
let url = if url.starts_with('(') && url.ends_with(')') {
&url[1..url.len() - 1]
@@ -238,7 +236,7 @@ impl fmt::Debug for PackageId {
#[cfg(test)]
mod tests {
use super::PackageId;
- use crate::core::source::SourceId;
+ use crate::core::SourceId;
use crate::sources::CRATES_IO_INDEX;
use crate::util::IntoUrl;
@@ -254,43 +252,6 @@ mod tests {
}
#[test]
- fn debug() {
- let loc = CRATES_IO_INDEX.into_url().unwrap();
- let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
- assert_eq!(
- r#"PackageId { name: "foo", version: "1.0.0", source: "registry `crates-io`" }"#,
- format!("{:?}", pkg_id)
- );
-
- let expected = r#"
-PackageId {
- name: "foo",
- version: "1.0.0",
- source: "registry `crates-io`",
-}
-"#
- .trim();
-
- // Can be removed once trailing commas in Debug have reached the stable
- // channel.
- let expected_without_trailing_comma = r#"
-PackageId {
- name: "foo",
- version: "1.0.0",
- source: "registry `crates-io`"
-}
-"#
- .trim();
-
- let actual = format!("{:#?}", pkg_id);
- if actual.ends_with(",\n}") {
- assert_eq!(actual, expected);
- } else {
- assert_eq!(actual, expected_without_trailing_comma);
- }
- }
-
- #[test]
fn display() {
let loc = CRATES_IO_INDEX.into_url().unwrap();
let pkg_id = PackageId::new("foo", "1.0.0", SourceId::for_registry(&loc).unwrap()).unwrap();
diff --git a/src/tools/cargo/src/cargo/core/package_id_spec.rs b/src/tools/cargo/src/cargo/core/package_id_spec.rs
index 267ea3ffd..53d99b84b 100644
--- a/src/tools/cargo/src/cargo/core/package_id_spec.rs
+++ b/src/tools/cargo/src/cargo/core/package_id_spec.rs
@@ -10,7 +10,8 @@ use crate::core::PackageId;
use crate::util::edit_distance;
use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
-use crate::util::{validate_package_name, IntoUrl, ToSemver};
+use crate::util::PartialVersion;
+use crate::util::{validate_package_name, IntoUrl};
/// Some or all of the data required to identify a package:
///
@@ -24,7 +25,7 @@ use crate::util::{validate_package_name, IntoUrl, ToSemver};
#[derive(Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
pub struct PackageIdSpec {
name: InternedString,
- version: Option<Version>,
+ version: Option<PartialVersion>,
url: Option<Url>,
}
@@ -70,7 +71,7 @@ impl PackageIdSpec {
let mut parts = spec.splitn(2, [':', '@']);
let name = parts.next().unwrap();
let version = match parts.next() {
- Some(version) => Some(version.to_semver()?),
+ Some(version) => Some(version.parse::<PartialVersion>()?),
None => None,
};
validate_package_name(name, "pkgid", "")?;
@@ -94,12 +95,12 @@ impl PackageIdSpec {
spec.query(i)
}
- /// Convert a `PackageId` to a `PackageIdSpec`, which will have both the `Version` and `Url`
+ /// Convert a `PackageId` to a `PackageIdSpec`, which will have both the `PartialVersion` and `Url`
/// fields filled in.
pub fn from_package_id(package_id: PackageId) -> PackageIdSpec {
PackageIdSpec {
name: package_id.name(),
- version: Some(package_id.version().clone()),
+ version: Some(package_id.version().clone().into()),
url: Some(package_id.source_id().url().clone()),
}
}
@@ -123,24 +124,20 @@ impl PackageIdSpec {
)
})?;
match frag {
- Some(fragment) => {
- let mut parts = fragment.splitn(2, [':', '@']);
- let name_or_version = parts.next().unwrap();
- match parts.next() {
- Some(part) => {
- let version = part.to_semver()?;
- (InternedString::new(name_or_version), Some(version))
- }
- None => {
- if name_or_version.chars().next().unwrap().is_alphabetic() {
- (InternedString::new(name_or_version), None)
- } else {
- let version = name_or_version.to_semver()?;
- (InternedString::new(path_name), Some(version))
- }
+ Some(fragment) => match fragment.split_once([':', '@']) {
+ Some((name, part)) => {
+ let version = part.parse::<PartialVersion>()?;
+ (InternedString::new(name), Some(version))
+ }
+ None => {
+ if fragment.chars().next().unwrap().is_alphabetic() {
+ (InternedString::new(&fragment), None)
+ } else {
+ let version = fragment.parse::<PartialVersion>()?;
+ (InternedString::new(path_name), Some(version))
}
}
- }
+ },
None => (InternedString::new(path_name), None),
}
};
@@ -155,7 +152,12 @@ impl PackageIdSpec {
self.name
}
- pub fn version(&self) -> Option<&Version> {
+ /// Full `semver::Version`, if present
+ pub fn version(&self) -> Option<Version> {
+ self.version.as_ref().and_then(|v| v.version())
+ }
+
+ pub fn partial_version(&self) -> Option<&PartialVersion> {
self.version.as_ref()
}
@@ -174,7 +176,7 @@ impl PackageIdSpec {
}
if let Some(ref v) = self.version {
- if v != package_id.version() {
+ if !v.matches(package_id.version()) {
return false;
}
}
@@ -193,55 +195,52 @@ impl PackageIdSpec {
{
let all_ids: Vec<_> = i.into_iter().collect();
let mut ids = all_ids.iter().copied().filter(|&id| self.matches(id));
- let ret = match ids.next() {
- Some(id) => id,
- None => {
- let mut suggestion = String::new();
- let try_spec = |spec: PackageIdSpec, suggestion: &mut String| {
- let try_matches: Vec<_> = all_ids
- .iter()
- .copied()
- .filter(|&id| spec.matches(id))
- .collect();
- if !try_matches.is_empty() {
- suggestion.push_str("\nDid you mean one of these?\n");
- minimize(suggestion, &try_matches, self);
- }
- };
- if self.url.is_some() {
- try_spec(
- PackageIdSpec {
- name: self.name,
- version: self.version.clone(),
- url: None,
- },
- &mut suggestion,
- );
- }
- if suggestion.is_empty() && self.version.is_some() {
- try_spec(
- PackageIdSpec {
- name: self.name,
- version: None,
- url: None,
- },
- &mut suggestion,
- );
+ let Some(ret) = ids.next() else {
+ let mut suggestion = String::new();
+ let try_spec = |spec: PackageIdSpec, suggestion: &mut String| {
+ let try_matches: Vec<_> = all_ids
+ .iter()
+ .copied()
+ .filter(|&id| spec.matches(id))
+ .collect();
+ if !try_matches.is_empty() {
+ suggestion.push_str("\nDid you mean one of these?\n");
+ minimize(suggestion, &try_matches, self);
}
- if suggestion.is_empty() {
- suggestion.push_str(&edit_distance::closest_msg(
- &self.name,
- all_ids.iter(),
- |id| id.name().as_str(),
- ));
- }
-
- bail!(
- "package ID specification `{}` did not match any packages{}",
- self,
- suggestion
+ };
+ if self.url.is_some() {
+ try_spec(
+ PackageIdSpec {
+ name: self.name,
+ version: self.version.clone(),
+ url: None,
+ },
+ &mut suggestion,
+ );
+ }
+ if suggestion.is_empty() && self.version.is_some() {
+ try_spec(
+ PackageIdSpec {
+ name: self.name,
+ version: None,
+ url: None,
+ },
+ &mut suggestion,
);
}
+ if suggestion.is_empty() {
+ suggestion.push_str(&edit_distance::closest_msg(
+ &self.name,
+ all_ids.iter(),
+ |id| id.name().as_str(),
+ ));
+ }
+
+ bail!(
+ "package ID specification `{}` did not match any packages{}",
+ self,
+ suggestion
+ );
};
return match ids.next() {
Some(other) => {
@@ -250,8 +249,8 @@ impl PackageIdSpec {
your project, and the specification \
`{}` is ambiguous.\n\
Please re-run this command \
- with `-p <spec>` where `<spec>` is one \
- of the following:",
+ with one of the following \
+ specifications:",
self.name(),
self
);
@@ -326,7 +325,6 @@ mod tests {
use super::PackageIdSpec;
use crate::core::{PackageId, SourceId};
use crate::util::interning::InternedString;
- use crate::util::ToSemver;
use url::Url;
#[test]
@@ -351,16 +349,25 @@ mod tests {
"https://crates.io/foo#1.2.3",
PackageIdSpec {
name: InternedString::new("foo"),
- version: Some("1.2.3".to_semver().unwrap()),
+ version: Some("1.2.3".parse().unwrap()),
url: Some(Url::parse("https://crates.io/foo").unwrap()),
},
"https://crates.io/foo#1.2.3",
);
ok(
+ "https://crates.io/foo#1.2",
+ PackageIdSpec {
+ name: InternedString::new("foo"),
+ version: Some("1.2".parse().unwrap()),
+ url: Some(Url::parse("https://crates.io/foo").unwrap()),
+ },
+ "https://crates.io/foo#1.2",
+ );
+ ok(
"https://crates.io/foo#bar:1.2.3",
PackageIdSpec {
name: InternedString::new("bar"),
- version: Some("1.2.3".to_semver().unwrap()),
+ version: Some("1.2.3".parse().unwrap()),
url: Some(Url::parse("https://crates.io/foo").unwrap()),
},
"https://crates.io/foo#bar@1.2.3",
@@ -369,12 +376,21 @@ mod tests {
"https://crates.io/foo#bar@1.2.3",
PackageIdSpec {
name: InternedString::new("bar"),
- version: Some("1.2.3".to_semver().unwrap()),
+ version: Some("1.2.3".parse().unwrap()),
url: Some(Url::parse("https://crates.io/foo").unwrap()),
},
"https://crates.io/foo#bar@1.2.3",
);
ok(
+ "https://crates.io/foo#bar@1.2",
+ PackageIdSpec {
+ name: InternedString::new("bar"),
+ version: Some("1.2".parse().unwrap()),
+ url: Some(Url::parse("https://crates.io/foo").unwrap()),
+ },
+ "https://crates.io/foo#bar@1.2",
+ );
+ ok(
"foo",
PackageIdSpec {
name: InternedString::new("foo"),
@@ -387,7 +403,7 @@ mod tests {
"foo:1.2.3",
PackageIdSpec {
name: InternedString::new("foo"),
- version: Some("1.2.3".to_semver().unwrap()),
+ version: Some("1.2.3".parse().unwrap()),
url: None,
},
"foo@1.2.3",
@@ -396,21 +412,29 @@ mod tests {
"foo@1.2.3",
PackageIdSpec {
name: InternedString::new("foo"),
- version: Some("1.2.3".to_semver().unwrap()),
+ version: Some("1.2.3".parse().unwrap()),
url: None,
},
"foo@1.2.3",
);
+ ok(
+ "foo@1.2",
+ PackageIdSpec {
+ name: InternedString::new("foo"),
+ version: Some("1.2".parse().unwrap()),
+ url: None,
+ },
+ "foo@1.2",
+ );
}
#[test]
fn bad_parsing() {
assert!(PackageIdSpec::parse("baz:").is_err());
assert!(PackageIdSpec::parse("baz:*").is_err());
- assert!(PackageIdSpec::parse("baz:1.0").is_err());
assert!(PackageIdSpec::parse("baz@").is_err());
assert!(PackageIdSpec::parse("baz@*").is_err());
- assert!(PackageIdSpec::parse("baz@1.0").is_err());
+ assert!(PackageIdSpec::parse("baz@^1.0").is_err());
assert!(PackageIdSpec::parse("https://baz:1.0").is_err());
assert!(PackageIdSpec::parse("https://#baz:1.0").is_err());
}
@@ -419,14 +443,50 @@ mod tests {
fn matching() {
let url = Url::parse("https://example.com").unwrap();
let sid = SourceId::for_registry(&url).unwrap();
- let foo = PackageId::new("foo", "1.2.3", sid).unwrap();
- let bar = PackageId::new("bar", "1.2.3", sid).unwrap();
+ let foo = PackageId::new("foo", "1.2.3", sid).unwrap();
assert!(PackageIdSpec::parse("foo").unwrap().matches(foo));
- assert!(!PackageIdSpec::parse("foo").unwrap().matches(bar));
+ assert!(!PackageIdSpec::parse("bar").unwrap().matches(foo));
assert!(PackageIdSpec::parse("foo:1.2.3").unwrap().matches(foo));
assert!(!PackageIdSpec::parse("foo:1.2.2").unwrap().matches(foo));
assert!(PackageIdSpec::parse("foo@1.2.3").unwrap().matches(foo));
assert!(!PackageIdSpec::parse("foo@1.2.2").unwrap().matches(foo));
+ assert!(PackageIdSpec::parse("foo@1.2").unwrap().matches(foo));
+
+ let meta = PackageId::new("meta", "1.2.3+hello", sid).unwrap();
+ assert!(PackageIdSpec::parse("meta").unwrap().matches(meta));
+ assert!(PackageIdSpec::parse("meta@1").unwrap().matches(meta));
+ assert!(PackageIdSpec::parse("meta@1.2").unwrap().matches(meta));
+ assert!(PackageIdSpec::parse("meta@1.2.3").unwrap().matches(meta));
+ assert!(!PackageIdSpec::parse("meta@1.2.3-alpha.0")
+ .unwrap()
+ .matches(meta));
+ assert!(PackageIdSpec::parse("meta@1.2.3+hello")
+ .unwrap()
+ .matches(meta));
+ assert!(!PackageIdSpec::parse("meta@1.2.3+bye")
+ .unwrap()
+ .matches(meta));
+
+ let pre = PackageId::new("pre", "1.2.3-alpha.0", sid).unwrap();
+ assert!(PackageIdSpec::parse("pre").unwrap().matches(pre));
+ assert!(!PackageIdSpec::parse("pre@1").unwrap().matches(pre));
+ assert!(!PackageIdSpec::parse("pre@1.2").unwrap().matches(pre));
+ assert!(!PackageIdSpec::parse("pre@1.2.3").unwrap().matches(pre));
+ assert!(PackageIdSpec::parse("pre@1.2.3-alpha.0")
+ .unwrap()
+ .matches(pre));
+ assert!(!PackageIdSpec::parse("pre@1.2.3-alpha.1")
+ .unwrap()
+ .matches(pre));
+ assert!(!PackageIdSpec::parse("pre@1.2.3-beta.0")
+ .unwrap()
+ .matches(pre));
+ assert!(!PackageIdSpec::parse("pre@1.2.3+hello")
+ .unwrap()
+ .matches(pre));
+ assert!(!PackageIdSpec::parse("pre@1.2.3-alpha.0+hello")
+ .unwrap()
+ .matches(pre));
}
}
diff --git a/src/tools/cargo/src/cargo/core/profiles.rs b/src/tools/cargo/src/cargo/core/profiles.rs
index 5c7d3e248..1ad9ed5f7 100644
--- a/src/tools/cargo/src/cargo/core/profiles.rs
+++ b/src/tools/cargo/src/cargo/core/profiles.rs
@@ -1205,9 +1205,8 @@ fn merge_config_profiles(
fn get_config_profile(ws: &Workspace<'_>, name: &str) -> CargoResult<Option<TomlProfile>> {
let profile: Option<config::Value<TomlProfile>> =
ws.config().get(&format!("profile.{}", name))?;
- let profile = match profile {
- Some(profile) => profile,
- None => return Ok(None),
+ let Some(profile) = profile else {
+ return Ok(None);
};
let mut warnings = Vec::new();
profile
@@ -1239,13 +1238,11 @@ fn validate_packages_unique(
name: &str,
toml: &Option<TomlProfile>,
) -> CargoResult<HashSet<PackageIdSpec>> {
- let toml = match toml {
- Some(ref toml) => toml,
- None => return Ok(HashSet::new()),
+ let Some(toml) = toml else {
+ return Ok(HashSet::new());
};
- let overrides = match toml.package.as_ref() {
- Some(overrides) => overrides,
- None => return Ok(HashSet::new()),
+ let Some(overrides) = toml.package.as_ref() else {
+ return Ok(HashSet::new());
};
// Verify that a package doesn't match multiple spec overrides.
let mut found = HashSet::new();
@@ -1297,9 +1294,8 @@ fn validate_packages_unmatched(
toml: &TomlProfile,
found: &HashSet<PackageIdSpec>,
) -> CargoResult<()> {
- let overrides = match toml.package.as_ref() {
- Some(overrides) => overrides,
- None => return Ok(()),
+ let Some(overrides) = toml.package.as_ref() else {
+ return Ok(());
};
// Verify every override matches at least one package.
diff --git a/src/tools/cargo/src/cargo/core/registry.rs b/src/tools/cargo/src/cargo/core/registry.rs
index da3d612d0..9a6a5a035 100644
--- a/src/tools/cargo/src/cargo/core/registry.rs
+++ b/src/tools/cargo/src/cargo/core/registry.rs
@@ -2,8 +2,11 @@ use std::collections::{HashMap, HashSet};
use std::task::{ready, Poll};
use crate::core::PackageSet;
-use crate::core::{Dependency, PackageId, QueryKind, Source, SourceId, SourceMap, Summary};
+use crate::core::{Dependency, PackageId, SourceId, Summary};
use crate::sources::config::SourceConfigMap;
+use crate::sources::source::QueryKind;
+use crate::sources::source::Source;
+use crate::sources::source::SourceMap;
use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
use crate::util::{CanonicalUrl, Config};
@@ -396,7 +399,7 @@ impl<'cfg> PackageRegistry<'cfg> {
// Note that this is somewhat subtle where the list of `ids` for a
// canonical URL is extend with possibly two ids per summary. This is done
// to handle the transition from the v2->v3 lock file format where in
- // v2 DefeaultBranch was either DefaultBranch or Branch("master") for
+ // v2 DefaultBranch was either DefaultBranch or Branch("master") for
// git dependencies. In this case if `summary.package_id()` is
// Branch("master") then alt_package_id will be DefaultBranch. This
// signifies that there's a patch available for either of those
diff --git a/src/tools/cargo/src/cargo/core/resolver/dep_cache.rs b/src/tools/cargo/src/cargo/core/resolver/dep_cache.rs
index 997533014..9041c5b0f 100644
--- a/src/tools/cargo/src/cargo/core/resolver/dep_cache.rs
+++ b/src/tools/cargo/src/cargo/core/resolver/dep_cache.rs
@@ -16,11 +16,11 @@ use crate::core::resolver::{
ActivateError, ActivateResult, CliFeatures, RequestedFeatures, ResolveOpts, VersionOrdering,
VersionPreferences,
};
-use crate::core::{
- Dependency, FeatureValue, PackageId, PackageIdSpec, QueryKind, Registry, Summary,
-};
+use crate::core::{Dependency, FeatureValue, PackageId, PackageIdSpec, Registry, Summary};
+use crate::sources::source::QueryKind;
use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
+use crate::util::RustVersion;
use anyhow::Context as _;
use std::collections::{BTreeSet, HashMap, HashSet};
@@ -36,6 +36,7 @@ pub struct RegistryQueryer<'a> {
/// versions first. That allows `cargo update -Z minimal-versions` which will
/// specify minimum dependency versions to be used.
minimal_versions: bool,
+ max_rust_version: Option<RustVersion>,
/// a cache of `Candidate`s that fulfil a `Dependency` (and whether `first_minimal_version`)
registry_cache: HashMap<(Dependency, bool), Poll<Rc<Vec<Summary>>>>,
/// a cache of `Dependency`s that are required for a `Summary`
@@ -57,12 +58,14 @@ impl<'a> RegistryQueryer<'a> {
replacements: &'a [(PackageIdSpec, Dependency)],
version_prefs: &'a VersionPreferences,
minimal_versions: bool,
+ max_rust_version: Option<&RustVersion>,
) -> Self {
RegistryQueryer {
registry,
replacements,
version_prefs,
minimal_versions,
+ max_rust_version: max_rust_version.cloned(),
registry_cache: HashMap::new(),
summary_cache: HashMap::new(),
used_replacements: HashMap::new(),
@@ -112,7 +115,10 @@ impl<'a> RegistryQueryer<'a> {
let mut ret = Vec::new();
let ready = self.registry.query(dep, QueryKind::Exact, &mut |s| {
- ret.push(s);
+ if self.max_rust_version.is_none() || s.rust_version() <= self.max_rust_version.as_ref()
+ {
+ ret.push(s);
+ }
})?;
if ready.is_pending() {
self.registry_cache
@@ -123,11 +129,10 @@ impl<'a> RegistryQueryer<'a> {
let mut potential_matches = self
.replacements
.iter()
- .filter(|&&(ref spec, _)| spec.matches(summary.package_id()));
+ .filter(|(spec, _)| spec.matches(summary.package_id()));
- let &(ref spec, ref dep) = match potential_matches.next() {
- None => continue,
- Some(replacement) => replacement,
+ let Some((spec, dep)) = potential_matches.next() else {
+ continue;
};
debug!(
"found an override for {} {}",
@@ -168,11 +173,20 @@ impl<'a> RegistryQueryer<'a> {
)));
}
- // The dependency should be hard-coded to have the same name and an
- // exact version requirement, so both of these assertions should
- // never fail.
- assert_eq!(s.version(), summary.version());
- assert_eq!(s.name(), summary.name());
+ assert_eq!(
+ s.name(),
+ summary.name(),
+ "dependency should be hard coded to have the same name"
+ );
+ if s.version() != summary.version() {
+ return Poll::Ready(Err(anyhow::anyhow!(
+ "replacement specification `{}` matched {} and tried to override it with {}\n\
+ avoid matching unrelated packages by being more specific",
+ spec,
+ summary.version(),
+ s.version(),
+ )));
+ }
let replace = if s.source_id() == summary.source_id() {
debug!("Preventing\n{:?}\nfrom replacing\n{:?}", summary, s);
@@ -183,7 +197,7 @@ impl<'a> RegistryQueryer<'a> {
let matched_spec = spec.clone();
// Make sure no duplicates
- if let Some(&(ref spec, _)) = potential_matches.next() {
+ if let Some((spec, _)) = potential_matches.next() {
return Poll::Ready(Err(anyhow::anyhow!(
"overlapping replacement specifications found:\n\n \
* {}\n * {}\n\nboth specifications match: {}",
@@ -273,7 +287,7 @@ impl<'a> RegistryQueryer<'a> {
// dependencies with more candidates. This way if the dependency with
// only one candidate can't be resolved we don't have to do a bunch of
// work before we figure that out.
- deps.sort_by_key(|&(_, ref a, _)| a.len());
+ deps.sort_by_key(|(_, a, _)| a.len());
let out = Rc::new((used_features, Rc::new(deps)));
@@ -476,9 +490,8 @@ impl Requirements<'_> {
return Ok(());
}
- let fvs = match self.summary.features().get(&feat) {
- Some(fvs) => fvs,
- None => return Err(RequirementError::MissingFeature(feat)),
+ let Some(fvs) = self.summary.features().get(&feat) else {
+ return Err(RequirementError::MissingFeature(feat));
};
for fv in fvs {
@@ -525,10 +538,9 @@ impl RequirementError {
summary.package_id(),
feat
)),
- Some(p) => ActivateError::Conflict(
- p,
- ConflictReason::MissingFeatures(feat.to_string()),
- ),
+ Some(p) => {
+ ActivateError::Conflict(p, ConflictReason::MissingFeatures(feat))
+ }
};
}
if deps.iter().any(|dep| dep.is_optional()) {
@@ -569,10 +581,9 @@ impl RequirementError {
)),
// This code path currently isn't used, since `foo/bar`
// and `dep:` syntax is not allowed in a dependency.
- Some(p) => ActivateError::Conflict(
- p,
- ConflictReason::MissingFeatures(dep_name.to_string()),
- ),
+ Some(p) => {
+ ActivateError::Conflict(p, ConflictReason::MissingFeatures(dep_name))
+ }
}
}
RequirementError::Cycle(feat) => ActivateError::Fatal(anyhow::format_err!(
diff --git a/src/tools/cargo/src/cargo/core/resolver/encode.rs b/src/tools/cargo/src/cargo/core/resolver/encode.rs
index 1ee0d23f4..7835c2219 100644
--- a/src/tools/cargo/src/cargo/core/resolver/encode.rs
+++ b/src/tools/cargo/src/cargo/core/resolver/encode.rs
@@ -299,14 +299,13 @@ impl EncodableResolve {
let mut g = Graph::new();
- for &(ref id, _) in live_pkgs.values() {
+ for (id, _) in live_pkgs.values() {
g.add(*id);
}
for &(ref id, pkg) in live_pkgs.values() {
- let deps = match pkg.dependencies {
- Some(ref deps) => deps,
- None => continue,
+ let Some(ref deps) = pkg.dependencies else {
+ continue;
};
for edge in deps.iter() {
@@ -338,13 +337,12 @@ impl EncodableResolve {
let mut to_remove = Vec::new();
for (k, v) in metadata.iter().filter(|p| p.0.starts_with(prefix)) {
to_remove.push(k.to_string());
- let k = &k[prefix.len()..];
+ let k = k.strip_prefix(prefix).unwrap();
let enc_id: EncodablePackageId = k
.parse()
.with_context(|| internal("invalid encoding of checksum in lockfile"))?;
- let id = match lookup_id(&enc_id) {
- Some(id) => id,
- _ => continue,
+ let Some(id) = lookup_id(&enc_id) else {
+ continue;
};
let v = if v == "<none>" {
@@ -437,7 +435,7 @@ fn build_path_deps(ws: &Workspace<'_>) -> CargoResult<HashMap<String, SourceId>>
build_dep(dep, ws, &mut ret, &mut visited);
}
}
- for &(_, ref dep) in ws.root_replace() {
+ for (_, dep) in ws.root_replace() {
build_dep(dep, ws, &mut ret, &mut visited);
}
@@ -468,10 +466,7 @@ fn build_path_deps(ws: &Workspace<'_>) -> CargoResult<HashMap<String, SourceId>>
Ok(p) => p.join("Cargo.toml"),
Err(_) => return,
};
- let pkg = match ws.load(&path) {
- Ok(p) => p,
- Err(_) => return,
- };
+ let Ok(pkg) = ws.load(&path) else { return };
ret.insert(pkg.name().to_string(), pkg.package_id().source_id());
visited.insert(pkg.package_id().source_id());
build_pkg(&pkg, ws, ret, visited);
@@ -601,8 +596,8 @@ impl FromStr for EncodablePackageId {
let version = s.next();
let source_id = match s.next() {
Some(s) => {
- if s.starts_with('(') && s.ends_with(')') {
- Some(SourceId::from_url(&s[1..s.len() - 1])?)
+ if let Some(s) = s.strip_prefix('(').and_then(|s| s.strip_suffix(')')) {
+ Some(SourceId::from_url(s)?)
} else {
anyhow::bail!("invalid serialized PackageId")
}
diff --git a/src/tools/cargo/src/cargo/core/resolver/errors.rs b/src/tools/cargo/src/cargo/core/resolver/errors.rs
index ca5c833f4..b57a7c3eb 100644
--- a/src/tools/cargo/src/cargo/core/resolver/errors.rs
+++ b/src/tools/cargo/src/cargo/core/resolver/errors.rs
@@ -1,9 +1,10 @@
use std::fmt;
use std::task::Poll;
-use crate::core::{Dependency, PackageId, QueryKind, Registry, Summary};
+use crate::core::{Dependency, PackageId, Registry, Summary};
+use crate::sources::source::QueryKind;
use crate::util::edit_distance::edit_distance;
-use crate::util::{Config, VersionExt};
+use crate::util::{Config, OptVersionReq, VersionExt};
use anyhow::Error;
use super::context::Context;
@@ -223,9 +224,8 @@ pub(super) fn activation_error(
// Maybe the user mistyped the ver_req? Like `dep="2"` when `dep="0.2"`
// was meant. So we re-query the registry with `dep="*"` so we can
// list a few versions that were actually found.
- let all_req = semver::VersionReq::parse("*").unwrap();
let mut new_dep = dep.clone();
- new_dep.set_version_req(all_req);
+ new_dep.set_version_req(OptVersionReq::Any);
let mut candidates = loop {
match registry.query_vec(&new_dep, QueryKind::Exact) {
@@ -240,127 +240,122 @@ pub(super) fn activation_error(
candidates.sort_unstable_by(|a, b| b.version().cmp(a.version()));
- let mut msg =
- if !candidates.is_empty() {
- let versions = {
- let mut versions = candidates
- .iter()
- .take(3)
- .map(|cand| cand.version().to_string())
- .collect::<Vec<_>>();
-
- if candidates.len() > 3 {
- versions.push("...".into());
- }
+ let mut msg = if !candidates.is_empty() {
+ let versions = {
+ let mut versions = candidates
+ .iter()
+ .take(3)
+ .map(|cand| cand.version().to_string())
+ .collect::<Vec<_>>();
- versions.join(", ")
- };
+ if candidates.len() > 3 {
+ versions.push("...".into());
+ }
- let locked_version = dep
- .version_req()
- .locked_version()
- .map(|v| format!(" (locked to {})", v))
- .unwrap_or_default();
+ versions.join(", ")
+ };
+
+ let locked_version = dep
+ .version_req()
+ .locked_version()
+ .map(|v| format!(" (locked to {})", v))
+ .unwrap_or_default();
+
+ let mut msg = format!(
+ "failed to select a version for the requirement `{} = \"{}\"`{}\n\
+ candidate versions found which didn't match: {}\n\
+ location searched: {}\n",
+ dep.package_name(),
+ dep.version_req(),
+ locked_version,
+ versions,
+ registry.describe_source(dep.source_id()),
+ );
+ msg.push_str("required by ");
+ msg.push_str(&describe_path_in_context(cx, &parent.package_id()));
- let mut msg = format!(
- "failed to select a version for the requirement `{} = \"{}\"`{}\n\
- candidate versions found which didn't match: {}\n\
- location searched: {}\n",
- dep.package_name(),
- dep.version_req(),
- locked_version,
- versions,
- registry.describe_source(dep.source_id()),
+ // If we have a pre-release candidate, then that may be what our user is looking for
+ if let Some(pre) = candidates.iter().find(|c| c.version().is_prerelease()) {
+ msg.push_str("\nif you are looking for the prerelease package it needs to be specified explicitly");
+ msg.push_str(&format!(
+ "\n {} = {{ version = \"{}\" }}",
+ pre.name(),
+ pre.version()
+ ));
+ }
+
+ // If we have a path dependency with a locked version, then this may
+ // indicate that we updated a sub-package and forgot to run `cargo
+ // update`. In this case try to print a helpful error!
+ if dep.source_id().is_path() && dep.version_req().is_locked() {
+ msg.push_str(
+ "\nconsider running `cargo update` to update \
+ a path dependency's locked version",
);
- msg.push_str("required by ");
- msg.push_str(&describe_path_in_context(cx, &parent.package_id()));
-
- // If we have a path dependency with a locked version, then this may
- // indicate that we updated a sub-package and forgot to run `cargo
- // update`. In this case try to print a helpful error!
- if dep.source_id().is_path() && dep.version_req().is_locked() {
- msg.push_str(
- "\nconsider running `cargo update` to update \
- a path dependency's locked version",
- );
- }
+ }
+
+ if registry.is_replaced(dep.source_id()) {
+ msg.push_str("\nperhaps a crate was updated and forgotten to be re-vendored?");
+ }
- if registry.is_replaced(dep.source_id()) {
- msg.push_str("\nperhaps a crate was updated and forgotten to be re-vendored?");
+ msg
+ } else {
+ // Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
+ // was meant. So we try asking the registry for a `fuzzy` search for suggestions.
+ let mut candidates = loop {
+ match registry.query_vec(&new_dep, QueryKind::Fuzzy) {
+ Poll::Ready(Ok(candidates)) => break candidates,
+ Poll::Ready(Err(e)) => return to_resolve_err(e),
+ Poll::Pending => match registry.block_until_ready() {
+ Ok(()) => continue,
+ Err(e) => return to_resolve_err(e),
+ },
}
+ };
- msg
+ candidates.sort_unstable_by_key(|a| a.name());
+ candidates.dedup_by(|a, b| a.name() == b.name());
+ let mut candidates: Vec<_> = candidates
+ .iter()
+ .filter_map(|n| Some((edit_distance(&*new_dep.package_name(), &*n.name(), 3)?, n)))
+ .collect();
+ candidates.sort_by_key(|o| o.0);
+ let mut msg: String;
+ if candidates.is_empty() {
+ msg = format!("no matching package named `{}` found\n", dep.package_name());
} else {
- // Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
- // was meant. So we try asking the registry for a `fuzzy` search for suggestions.
- let mut candidates = loop {
- match registry.query_vec(&new_dep, QueryKind::Fuzzy) {
- Poll::Ready(Ok(candidates)) => break candidates,
- Poll::Ready(Err(e)) => return to_resolve_err(e),
- Poll::Pending => match registry.block_until_ready() {
- Ok(()) => continue,
- Err(e) => return to_resolve_err(e),
- },
- }
- };
-
- candidates.sort_unstable_by_key(|a| a.name());
- candidates.dedup_by(|a, b| a.name() == b.name());
- let mut candidates: Vec<_> = candidates
+ msg = format!(
+ "no matching package found\nsearched package name: `{}`\n",
+ dep.package_name()
+ );
+ let mut names = candidates
.iter()
- .filter_map(|n| Some((edit_distance(&*new_dep.package_name(), &*n.name(), 3)?, n)))
- .collect();
- candidates.sort_by_key(|o| o.0);
- let mut msg: String;
- if candidates.is_empty() {
- msg = format!("no matching package named `{}` found\n", dep.package_name());
- } else {
- msg = format!(
- "no matching package found\nsearched package name: `{}`\n",
- dep.package_name()
- );
-
- // If dependency package name is equal to the name of the candidate here
- // it may be a prerelease package which hasn't been specified correctly
- if dep.package_name() == candidates[0].1.name()
- && candidates[0].1.package_id().version().is_prerelease()
- {
- msg.push_str("prerelease package needs to be specified explicitly\n");
- msg.push_str(&format!(
- "{name} = {{ version = \"{version}\" }}",
- name = candidates[0].1.name(),
- version = candidates[0].1.package_id().version()
- ));
- } else {
- let mut names = candidates
- .iter()
- .take(3)
- .map(|c| c.1.name().as_str())
- .collect::<Vec<_>>();
-
- if candidates.len() > 3 {
- names.push("...");
- }
- // Vertically align first suggestion with missing crate name
- // so a typo jumps out at you.
- msg.push_str("perhaps you meant: ");
- msg.push_str(&names.iter().enumerate().fold(
- String::default(),
- |acc, (i, el)| match i {
- 0 => acc + el,
- i if names.len() - 1 == i && candidates.len() <= 3 => acc + " or " + el,
- _ => acc + ", " + el,
- },
- ));
- }
- msg.push('\n');
+ .take(3)
+ .map(|c| c.1.name().as_str())
+ .collect::<Vec<_>>();
+
+ if candidates.len() > 3 {
+ names.push("...");
}
- msg.push_str(&format!("location searched: {}\n", dep.source_id()));
- msg.push_str("required by ");
- msg.push_str(&describe_path_in_context(cx, &parent.package_id()));
+ // Vertically align first suggestion with missing crate name
+ // so a typo jumps out at you.
+ msg.push_str("perhaps you meant: ");
+ msg.push_str(&names.iter().enumerate().fold(
+ String::default(),
+ |acc, (i, el)| match i {
+ 0 => acc + el,
+ i if names.len() - 1 == i && candidates.len() <= 3 => acc + " or " + el,
+ _ => acc + ", " + el,
+ },
+ ));
+ msg.push('\n');
+ }
+ msg.push_str(&format!("location searched: {}\n", dep.source_id()));
+ msg.push_str("required by ");
+ msg.push_str(&describe_path_in_context(cx, &parent.package_id()));
- msg
- };
+ msg
+ };
if let Some(config) = config {
if config.offline() {
diff --git a/src/tools/cargo/src/cargo/core/resolver/features.rs b/src/tools/cargo/src/cargo/core/resolver/features.rs
index 4518f9fe7..f1c2aebcc 100644
--- a/src/tools/cargo/src/cargo/core/resolver/features.rs
+++ b/src/tools/cargo/src/cargo/core/resolver/features.rs
@@ -45,7 +45,8 @@ use crate::core::resolver::{Resolve, ResolveBehavior};
use crate::core::{FeatureValue, PackageId, PackageIdSpec, PackageSet, Workspace};
use crate::util::interning::InternedString;
use crate::util::CargoResult;
-use anyhow::bail;
+use anyhow::{bail, Context};
+use itertools::Itertools;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::rc::Rc;
@@ -408,7 +409,7 @@ pub type DiffMap = BTreeMap<PackageFeaturesKey, BTreeSet<InternedString>>;
/// [module-level documentation]: crate::core::resolver::features
pub struct FeatureResolver<'a, 'cfg> {
ws: &'a Workspace<'cfg>,
- target_data: &'a RustcTargetData<'cfg>,
+ target_data: &'a mut RustcTargetData<'cfg>,
/// The platforms to build for, requested by the user.
requested_targets: &'a [CompileKind],
resolve: &'a Resolve,
@@ -445,7 +446,7 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
/// with the result.
pub fn resolve(
ws: &Workspace<'cfg>,
- target_data: &RustcTargetData<'cfg>,
+ target_data: &'a mut RustcTargetData<'cfg>,
resolve: &Resolve,
package_set: &'a PackageSet<'cfg>,
cli_features: &CliFeatures,
@@ -544,7 +545,7 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
// features that enable other features.
return Ok(());
}
- for (dep_pkg_id, deps) in self.deps(pkg_id, fk) {
+ for (dep_pkg_id, deps) in self.deps(pkg_id, fk)? {
for (dep, dep_fk) in deps {
if dep.is_optional() {
// Optional dependencies are enabled in `activate_fv` when
@@ -609,19 +610,16 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
}
let summary = self.resolve.summary(pkg_id);
let feature_map = summary.features();
- let fvs = match feature_map.get(&feature_to_enable) {
- Some(fvs) => fvs,
- None => {
- // TODO: this should only happen for optional dependencies.
- // Other cases should be validated by Summary's `build_feature_map`.
- // Figure out some way to validate this assumption.
- tracing::debug!(
- "pkg {:?} does not define feature {}",
- pkg_id,
- feature_to_enable
- );
- return Ok(());
- }
+ let Some(fvs) = feature_map.get(&feature_to_enable) else {
+ // TODO: this should only happen for optional dependencies.
+ // Other cases should be validated by Summary's `build_feature_map`.
+ // Figure out some way to validate this assumption.
+ tracing::debug!(
+ "pkg {:?} does not define feature {}",
+ pkg_id,
+ feature_to_enable
+ );
+ return Ok(());
};
for fv in fvs {
self.activate_fv(pkg_id, fk, fv)?;
@@ -647,7 +645,7 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
.deferred_weak_dependencies
.remove(&(pkg_id, fk, dep_name));
// Activate the optional dep.
- for (dep_pkg_id, deps) in self.deps(pkg_id, fk) {
+ for (dep_pkg_id, deps) in self.deps(pkg_id, fk)? {
for (dep, dep_fk) in deps {
if dep.name_in_toml() != dep_name {
continue;
@@ -681,7 +679,7 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
dep_feature: InternedString,
weak: bool,
) -> CargoResult<()> {
- for (dep_pkg_id, deps) in self.deps(pkg_id, fk) {
+ for (dep_pkg_id, deps) in self.deps(pkg_id, fk)? {
for (dep, dep_fk) in deps {
if dep.name_in_toml() != dep_name {
continue;
@@ -777,12 +775,17 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
/// Returns the dependencies for a package, filtering out inactive targets.
fn deps(
- &self,
+ &mut self,
pkg_id: PackageId,
fk: FeaturesFor,
- ) -> Vec<(PackageId, Vec<(&'a Dependency, FeaturesFor)>)> {
+ ) -> CargoResult<Vec<(PackageId, Vec<(&'a Dependency, FeaturesFor)>)>> {
// Helper for determining if a platform is activated.
- let platform_activated = |dep: &Dependency| -> bool {
+ fn platform_activated(
+ dep: &Dependency,
+ fk: FeaturesFor,
+ target_data: &RustcTargetData<'_>,
+ requested_targets: &[CompileKind],
+ ) -> bool {
// We always count platforms as activated if the target stems from an artifact
// dependency's target specification. This triggers in conjunction with
// `[target.'cfg(…)'.dependencies]` manifest sections.
@@ -791,18 +794,17 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
// We always care about build-dependencies, and they are always
// Host. If we are computing dependencies "for a build script",
// even normal dependencies are host-only.
- self.target_data
- .dep_platform_activated(dep, CompileKind::Host)
+ target_data.dep_platform_activated(dep, CompileKind::Host)
}
- (_, FeaturesFor::NormalOrDev) => self
- .requested_targets
+ (_, FeaturesFor::NormalOrDev) => requested_targets
.iter()
- .any(|kind| self.target_data.dep_platform_activated(dep, *kind)),
- (_, FeaturesFor::ArtifactDep(target)) => self
- .target_data
- .dep_platform_activated(dep, CompileKind::Target(target)),
+ .any(|kind| target_data.dep_platform_activated(dep, *kind)),
+ (_, FeaturesFor::ArtifactDep(target)) => {
+ target_data.dep_platform_activated(dep, CompileKind::Target(target))
+ }
}
- };
+ }
+
self.resolve
.deps(pkg_id)
.map(|(dep_id, deps)| {
@@ -811,7 +813,12 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
.filter(|dep| {
if dep.platform().is_some()
&& self.opts.ignore_inactive_targets
- && !platform_activated(dep)
+ && !platform_activated(
+ dep,
+ fk,
+ self.target_data,
+ self.requested_targets,
+ )
{
return false;
}
@@ -820,7 +827,9 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
}
true
})
- .flat_map(|dep| {
+ .collect_vec() // collect because the next closure mutably borrows `self.target_data`
+ .into_iter()
+ .map(|dep| {
// Each `dep`endency can be built for multiple targets. For one, it
// may be a library target which is built as initially configured
// by `fk`. If it appears as build dependency, it must be built
@@ -852,28 +861,52 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
};
// `artifact_target_keys` are produced to fulfil the needs of artifacts that have a target specification.
- let artifact_target_keys = dep.artifact().map(|artifact| {
- (
- artifact.is_lib(),
- artifact.target().map(|target| match target {
- ArtifactTarget::Force(target) => {
- vec![FeaturesFor::ArtifactDep(target)]
- }
- ArtifactTarget::BuildDependencyAssumeTarget => self
- .requested_targets
- .iter()
- .map(|kind| match kind {
- CompileKind::Host => {
- let host_triple = self.target_data.rustc.host;
- CompileTarget::new(&host_triple).unwrap()
- }
- CompileKind::Target(target) => *target,
+ let artifact_target_keys = dep
+ .artifact()
+ .map(|artifact| {
+ let host_triple = self.target_data.rustc.host;
+ // not all targets may be queried before resolution since artifact dependencies
+ // and per-pkg-targets are not immediately known.
+ let mut activate_target = |target| {
+ let name = dep.name_in_toml();
+ self.target_data
+ .merge_compile_kind(CompileKind::Target(target))
+ .with_context(|| format!("failed to determine target information for target `{target}`.\n \
+ Artifact dependency `{name}` in package `{pkg_id}` requires building for `{target}`", target = target.rustc_target()))
+ };
+ CargoResult::Ok((
+ artifact.is_lib(),
+ artifact
+ .target()
+ .map(|target| {
+ CargoResult::Ok(match target {
+ ArtifactTarget::Force(target) => {
+ activate_target(target)?;
+ vec![FeaturesFor::ArtifactDep(target)]
+ }
+ // FIXME: this needs to interact with the `default-target` and `forced-target` values
+ // of the dependency
+ ArtifactTarget::BuildDependencyAssumeTarget => self
+ .requested_targets
+ .iter()
+ .map(|kind| match kind {
+ CompileKind::Host => {
+ CompileTarget::new(&host_triple)
+ .unwrap()
+ }
+ CompileKind::Target(target) => *target,
+ })
+ .map(|target| {
+ activate_target(target)?;
+ Ok(FeaturesFor::ArtifactDep(target))
+ })
+ .collect::<CargoResult<_>>()?,
+ })
})
- .map(FeaturesFor::ArtifactDep)
- .collect(),
- }),
- )
- });
+ .transpose()?,
+ ))
+ })
+ .transpose()?;
let dep_fks = match artifact_target_keys {
// The artifact is also a library and does specify custom
@@ -893,12 +926,13 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
// Use the standard feature key without any alteration.
Some((_, None)) | None => vec![lib_fk],
};
- dep_fks.into_iter().map(move |dep_fk| (dep, dep_fk))
+ Ok(dep_fks.into_iter().map(move |dep_fk| (dep, dep_fk)))
})
- .collect::<Vec<_>>();
- (dep_id, deps)
+ .flatten_ok()
+ .collect::<CargoResult<Vec<_>>>()?;
+ Ok((dep_id, deps))
})
- .filter(|(_id, deps)| !deps.is_empty())
+ .filter(|res| res.as_ref().map_or(true, |(_id, deps)| !deps.is_empty()))
.collect()
}
diff --git a/src/tools/cargo/src/cargo/core/resolver/mod.rs b/src/tools/cargo/src/cargo/core/resolver/mod.rs
index e3da6fe5a..7d8e8acd4 100644
--- a/src/tools/cargo/src/cargo/core/resolver/mod.rs
+++ b/src/tools/cargo/src/cargo/core/resolver/mod.rs
@@ -71,6 +71,7 @@ use crate::util::config::Config;
use crate::util::errors::CargoResult;
use crate::util::network::PollExt;
use crate::util::profile;
+use crate::util::RustVersion;
use self::context::Context;
use self::dep_cache::RegistryQueryer;
@@ -138,6 +139,7 @@ pub fn resolve(
version_prefs: &VersionPreferences,
config: Option<&Config>,
check_public_visible_dependencies: bool,
+ mut max_rust_version: Option<&RustVersion>,
) -> CargoResult<Resolve> {
let _p = profile::start("resolving");
let minimal_versions = match config {
@@ -148,8 +150,19 @@ pub fn resolve(
Some(config) => config.cli_unstable().direct_minimal_versions,
None => false,
};
- let mut registry =
- RegistryQueryer::new(registry, replacements, version_prefs, minimal_versions);
+ if !config
+ .map(|c| c.cli_unstable().msrv_policy)
+ .unwrap_or(false)
+ {
+ max_rust_version = None;
+ }
+ let mut registry = RegistryQueryer::new(
+ registry,
+ replacements,
+ version_prefs,
+ minimal_versions,
+ max_rust_version,
+ );
let cx = loop {
let cx = Context::new(check_public_visible_dependencies);
let cx = activate_deps_loop(
@@ -221,7 +234,7 @@ fn activate_deps_loop(
let mut past_conflicting_activations = conflict_cache::ConflictCache::new();
// Activate all the initial summaries to kick off some work.
- for &(ref summary, ref opts) in summaries {
+ for (summary, opts) in summaries {
debug!("initial activation: {}", summary.package_id());
let res = activate(
&mut cx,
@@ -501,9 +514,7 @@ fn activate_deps_loop(
if let Some((other_parent, conflict)) = remaining_deps
.iter()
// for deps related to us
- .filter(|&(_, ref other_dep)| {
- known_related_bad_deps.contains(other_dep)
- })
+ .filter(|(_, other_dep)| known_related_bad_deps.contains(other_dep))
.filter_map(|(other_parent, other_dep)| {
past_conflicting_activations
.find_conflicting(&cx, &other_dep, Some(pid))
@@ -1018,9 +1029,8 @@ fn find_candidate(
&frame.dep,
frame.parent.package_id(),
);
- let (candidate, has_another) = match next {
- Some(pair) => pair,
- None => continue,
+ let Some((candidate, has_another)) = next else {
+ continue;
};
// If all members of `conflicting_activations` are still
diff --git a/src/tools/cargo/src/cargo/core/resolver/types.rs b/src/tools/cargo/src/cargo/core/resolver/types.rs
index 40bdb6c21..9ef78090e 100644
--- a/src/tools/cargo/src/cargo/core/resolver/types.rs
+++ b/src/tools/cargo/src/cargo/core/resolver/types.rs
@@ -285,7 +285,7 @@ pub enum ConflictReason {
/// A dependency listed features that weren't actually available on the
/// candidate. For example we tried to activate feature `foo` but the
/// candidate we're activating didn't actually have the feature `foo`.
- MissingFeatures(String),
+ MissingFeatures(InternedString),
/// A dependency listed a feature that ended up being a required dependency.
/// For example we tried to activate feature `foo` but the
diff --git a/src/tools/cargo/src/cargo/core/resolver/version_prefs.rs b/src/tools/cargo/src/cargo/core/resolver/version_prefs.rs
index bf26d0498..28de77f11 100644
--- a/src/tools/cargo/src/cargo/core/resolver/version_prefs.rs
+++ b/src/tools/cargo/src/cargo/core/resolver/version_prefs.rs
@@ -81,6 +81,7 @@ impl VersionPreferences {
mod test {
use super::*;
use crate::core::SourceId;
+ use crate::util::RustVersion;
use std::collections::BTreeMap;
fn pkgid(name: &str, version: &str) -> PackageId {
@@ -103,7 +104,7 @@ mod test {
Vec::new(),
&features,
None::<&String>,
- None::<&String>,
+ None::<RustVersion>,
)
.unwrap()
}
diff --git a/src/tools/cargo/src/cargo/core/shell.rs b/src/tools/cargo/src/cargo/core/shell.rs
index 4d45e6098..a9b9e84af 100644
--- a/src/tools/cargo/src/cargo/core/shell.rs
+++ b/src/tools/cargo/src/cargo/core/shell.rs
@@ -2,10 +2,11 @@ use std::fmt;
use std::io::prelude::*;
use std::io::IsTerminal;
-use termcolor::Color::{Cyan, Green, Red, Yellow};
-use termcolor::{self, Color, ColorSpec, StandardStream, WriteColor};
+use anstream::AutoStream;
+use anstyle::Style;
use crate::util::errors::CargoResult;
+use crate::util::style::*;
pub enum TtyWidth {
NoTty,
@@ -77,11 +78,11 @@ impl fmt::Debug for Shell {
/// A `Write`able object, either with or without color support
enum ShellOut {
/// A plain write object without color support
- Write(Box<dyn Write>),
+ Write(AutoStream<Box<dyn Write>>),
/// Color-enabled stdio, with information on whether color should be used
Stream {
- stdout: StandardStream,
- stderr: StandardStream,
+ stdout: AutoStream<std::io::Stdout>,
+ stderr: AutoStream<std::io::Stderr>,
stderr_tty: bool,
color_choice: ColorChoice,
},
@@ -103,11 +104,13 @@ impl Shell {
/// output.
pub fn new() -> Shell {
let auto_clr = ColorChoice::CargoAuto;
+ let stdout_choice = auto_clr.to_anstream_color_choice();
+ let stderr_choice = auto_clr.to_anstream_color_choice();
Shell {
output: ShellOut::Stream {
- stdout: StandardStream::stdout(auto_clr.to_termcolor_color_choice(Stream::Stdout)),
- stderr: StandardStream::stderr(auto_clr.to_termcolor_color_choice(Stream::Stderr)),
- color_choice: ColorChoice::CargoAuto,
+ stdout: AutoStream::new(std::io::stdout(), stdout_choice),
+ stderr: AutoStream::new(std::io::stderr(), stderr_choice),
+ color_choice: auto_clr,
stderr_tty: std::io::stderr().is_terminal(),
},
verbosity: Verbosity::Verbose,
@@ -118,7 +121,7 @@ impl Shell {
/// Creates a shell from a plain writable object, with no color, and max verbosity.
pub fn from_write(out: Box<dyn Write>) -> Shell {
Shell {
- output: ShellOut::Write(out),
+ output: ShellOut::Write(AutoStream::never(out)), // strip all formatting on write
verbosity: Verbosity::Verbose,
needs_clear: false,
}
@@ -130,7 +133,7 @@ impl Shell {
&mut self,
status: &dyn fmt::Display,
message: Option<&dyn fmt::Display>,
- color: Color,
+ color: &Style,
justified: bool,
) -> CargoResult<()> {
match self.verbosity {
@@ -203,14 +206,14 @@ impl Shell {
T: fmt::Display,
U: fmt::Display,
{
- self.print(&status, Some(&message), Green, true)
+ self.print(&status, Some(&message), &HEADER, true)
}
pub fn status_header<T>(&mut self, status: T) -> CargoResult<()>
where
T: fmt::Display,
{
- self.print(&status, None, Cyan, true)
+ self.print(&status, None, &NOTE, true)
}
/// Shortcut to right-align a status message.
@@ -218,7 +221,7 @@ impl Shell {
&mut self,
status: T,
message: U,
- color: Color,
+ color: &Style,
) -> CargoResult<()>
where
T: fmt::Display,
@@ -255,20 +258,20 @@ impl Shell {
self.err_erase_line();
}
self.output
- .message_stderr(&"error", Some(&message), Red, false)
+ .message_stderr(&"error", Some(&message), &ERROR, false)
}
/// Prints an amber 'warning' message.
pub fn warn<T: fmt::Display>(&mut self, message: T) -> CargoResult<()> {
match self.verbosity {
Verbosity::Quiet => Ok(()),
- _ => self.print(&"warning", Some(&message), Yellow, false),
+ _ => self.print(&"warning", Some(&message), &WARN, false),
}
}
/// Prints a cyan 'note' message.
pub fn note<T: fmt::Display>(&mut self, message: T) -> CargoResult<()> {
- self.print(&"note", Some(&message), Cyan, false)
+ self.print(&"note", Some(&message), &NOTE, false)
}
/// Updates the verbosity of the shell.
@@ -303,8 +306,10 @@ impl Shell {
),
};
*color_choice = cfg;
- *stdout = StandardStream::stdout(cfg.to_termcolor_color_choice(Stream::Stdout));
- *stderr = StandardStream::stderr(cfg.to_termcolor_color_choice(Stream::Stderr));
+ let stdout_choice = cfg.to_anstream_color_choice();
+ let stderr_choice = cfg.to_anstream_color_choice();
+ *stdout = AutoStream::new(std::io::stdout(), stdout_choice);
+ *stderr = AutoStream::new(std::io::stderr(), stderr_choice);
}
Ok(())
}
@@ -324,36 +329,28 @@ impl Shell {
pub fn err_supports_color(&self) -> bool {
match &self.output {
ShellOut::Write(_) => false,
- ShellOut::Stream { stderr, .. } => stderr.supports_color(),
+ ShellOut::Stream { stderr, .. } => supports_color(stderr.current_choice()),
}
}
pub fn out_supports_color(&self) -> bool {
match &self.output {
ShellOut::Write(_) => false,
- ShellOut::Stream { stdout, .. } => stdout.supports_color(),
+ ShellOut::Stream { stdout, .. } => supports_color(stdout.current_choice()),
}
}
/// Write a styled fragment
///
/// Caller is responsible for deciding whether [`Shell::verbosity`] is affects output.
- pub fn write_stdout(
- &mut self,
- fragment: impl fmt::Display,
- color: &ColorSpec,
- ) -> CargoResult<()> {
+ pub fn write_stdout(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
self.output.write_stdout(fragment, color)
}
/// Write a styled fragment
///
/// Caller is responsible for deciding whether [`Shell::verbosity`] is affects output.
- pub fn write_stderr(
- &mut self,
- fragment: impl fmt::Display,
- color: &ColorSpec,
- ) -> CargoResult<()> {
+ pub fn write_stderr(&mut self, fragment: impl fmt::Display, color: &Style) -> CargoResult<()> {
self.output.write_stderr(fragment, color)
}
@@ -362,13 +359,6 @@ impl Shell {
if self.needs_clear {
self.err_erase_line();
}
- #[cfg(windows)]
- {
- if let ShellOut::Stream { stderr, .. } = &mut self.output {
- ::fwdansi::write_ansi(stderr, message)?;
- return Ok(());
- }
- }
self.err().write_all(message)?;
Ok(())
}
@@ -378,13 +368,6 @@ impl Shell {
if self.needs_clear {
self.err_erase_line();
}
- #[cfg(windows)]
- {
- if let ShellOut::Stream { stdout, .. } = &mut self.output {
- ::fwdansi::write_ansi(stdout, message)?;
- return Ok(());
- }
- }
self.out().write_all(message)?;
Ok(())
}
@@ -412,70 +395,46 @@ impl ShellOut {
&mut self,
status: &dyn fmt::Display,
message: Option<&dyn fmt::Display>,
- color: Color,
+ style: &Style,
justified: bool,
) -> CargoResult<()> {
- match *self {
- ShellOut::Stream { ref mut stderr, .. } => {
- stderr.reset()?;
- stderr.set_color(ColorSpec::new().set_bold(true).set_fg(Some(color)))?;
- if justified {
- write!(stderr, "{:>12}", status)?;
- } else {
- write!(stderr, "{}", status)?;
- stderr.set_color(ColorSpec::new().set_bold(true))?;
- write!(stderr, ":")?;
- }
- stderr.reset()?;
- match message {
- Some(message) => writeln!(stderr, " {}", message)?,
- None => write!(stderr, " ")?,
- }
- }
- ShellOut::Write(ref mut w) => {
- if justified {
- write!(w, "{:>12}", status)?;
- } else {
- write!(w, "{}:", status)?;
- }
- match message {
- Some(message) => writeln!(w, " {}", message)?,
- None => write!(w, " ")?,
- }
- }
+ let style = style.render();
+ let bold = (anstyle::Style::new() | anstyle::Effects::BOLD).render();
+ let reset = anstyle::Reset.render();
+
+ let mut buffer = Vec::new();
+ if justified {
+ write!(&mut buffer, "{style}{status:>12}{reset}")?;
+ } else {
+ write!(&mut buffer, "{style}{status}{reset}{bold}:{reset}")?;
}
+ match message {
+ Some(message) => writeln!(buffer, " {message}")?,
+ None => write!(buffer, " ")?,
+ }
+ self.stderr().write_all(&buffer)?;
Ok(())
}
/// Write a styled fragment
- fn write_stdout(&mut self, fragment: impl fmt::Display, color: &ColorSpec) -> CargoResult<()> {
- match *self {
- ShellOut::Stream { ref mut stdout, .. } => {
- stdout.reset()?;
- stdout.set_color(&color)?;
- write!(stdout, "{}", fragment)?;
- stdout.reset()?;
- }
- ShellOut::Write(ref mut w) => {
- write!(w, "{}", fragment)?;
- }
- }
+ fn write_stdout(&mut self, fragment: impl fmt::Display, style: &Style) -> CargoResult<()> {
+ let style = style.render();
+ let reset = anstyle::Reset.render();
+
+ let mut buffer = Vec::new();
+ write!(buffer, "{style}{}{reset}", fragment)?;
+ self.stdout().write_all(&buffer)?;
Ok(())
}
/// Write a styled fragment
- fn write_stderr(&mut self, fragment: impl fmt::Display, color: &ColorSpec) -> CargoResult<()> {
- match *self {
- ShellOut::Stream { ref mut stderr, .. } => {
- stderr.reset()?;
- stderr.set_color(&color)?;
- write!(stderr, "{}", fragment)?;
- stderr.reset()?;
- }
- ShellOut::Write(ref mut w) => {
- write!(w, "{}", fragment)?;
- }
- }
+ fn write_stderr(&mut self, fragment: impl fmt::Display, style: &Style) -> CargoResult<()> {
+ let style = style.render();
+ let reset = anstyle::Reset.render();
+
+ let mut buffer = Vec::new();
+ write!(buffer, "{style}{}{reset}", fragment)?;
+ self.stderr().write_all(&buffer)?;
Ok(())
}
@@ -497,33 +456,22 @@ impl ShellOut {
}
impl ColorChoice {
- /// Converts our color choice to termcolor's version.
- fn to_termcolor_color_choice(self, stream: Stream) -> termcolor::ColorChoice {
+ /// Converts our color choice to anstream's version.
+ fn to_anstream_color_choice(self) -> anstream::ColorChoice {
match self {
- ColorChoice::Always => termcolor::ColorChoice::Always,
- ColorChoice::Never => termcolor::ColorChoice::Never,
- ColorChoice::CargoAuto => {
- if stream.is_terminal() {
- termcolor::ColorChoice::Auto
- } else {
- termcolor::ColorChoice::Never
- }
- }
+ ColorChoice::Always => anstream::ColorChoice::Always,
+ ColorChoice::Never => anstream::ColorChoice::Never,
+ ColorChoice::CargoAuto => anstream::ColorChoice::Auto,
}
}
}
-enum Stream {
- Stdout,
- Stderr,
-}
-
-impl Stream {
- fn is_terminal(self) -> bool {
- match self {
- Self::Stdout => std::io::stdout().is_terminal(),
- Self::Stderr => std::io::stderr().is_terminal(),
- }
+fn supports_color(choice: anstream::ColorChoice) -> bool {
+ match choice {
+ anstream::ColorChoice::Always
+ | anstream::ColorChoice::AlwaysAnsi
+ | anstream::ColorChoice::Auto => true,
+ anstream::ColorChoice::Never => false,
}
}
diff --git a/src/tools/cargo/src/cargo/core/source/source_id.rs b/src/tools/cargo/src/cargo/core/source_id.rs
index 6bbc07a5d..d688b8739 100644
--- a/src/tools/cargo/src/cargo/core/source/source_id.rs
+++ b/src/tools/cargo/src/cargo/core/source_id.rs
@@ -1,8 +1,10 @@
use crate::core::PackageId;
use crate::sources::registry::CRATES_IO_HTTP_INDEX;
+use crate::sources::source::Source;
use crate::sources::{DirectorySource, CRATES_IO_DOMAIN, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
use crate::sources::{GitSource, PathSource, RegistrySource};
-use crate::util::{config, CanonicalUrl, CargoResult, Config, IntoUrl};
+use crate::util::{config, CanonicalUrl, CargoResult, Config, IntoUrl, ToSemver};
+use anyhow::Context;
use serde::de;
use serde::ser;
use std::cmp::{self, Ordering};
@@ -28,9 +30,9 @@ static SOURCE_ID_CACHE: OnceLock<Mutex<HashSet<&'static SourceIdInner>>> = OnceL
/// `SourceId` is usually associated with an instance of [`Source`], which is
/// supposed to provide a `SourceId` via [`Source::source_id`] method.
///
-/// [`Source`]: super::Source
-/// [`Source::source_id`]: super::Source::source_id
-/// [`PackageId`]: super::super::PackageId
+/// [`Source`]: crate::sources::source::Source
+/// [`Source::source_id`]: crate::sources::source::Source::source_id
+/// [`PackageId`]: super::PackageId
#[derive(Clone, Copy, Eq, Debug)]
pub struct SourceId {
inner: &'static SourceIdInner,
@@ -49,14 +51,11 @@ struct SourceIdInner {
kind: SourceKind,
/// For example, the exact Git revision of the specified branch for a Git Source.
precise: Option<String>,
- /// Name of the registry source for alternative registries
- /// WARNING: this is not always set for alt-registries when the name is
- /// not known.
- name: Option<String>,
- /// Name of the alt registry in the `[registries]` table.
- /// WARNING: this is not always set for alt-registries when the name is
- /// not known.
- alt_registry_key: Option<String>,
+ /// Name of the remote registry.
+ ///
+ /// WARNING: this is not always set when the name is not known,
+ /// e.g. registry coming from `--index` or Cargo.lock
+ registry_key: Option<KeyOf>,
}
/// The possible kinds of code source.
@@ -91,11 +90,22 @@ pub enum GitReference {
DefaultBranch,
}
+/// Where the remote source key is defined.
+///
+/// The purpose of this is to provide better diagnostics for different sources of keys.
+#[derive(Debug, Clone, PartialEq, Eq)]
+enum KeyOf {
+ /// Defined in the `[registries]` table or the built-in `crates-io` key.
+ Registry(String),
+ /// Defined in the `[source]` replacement table.
+ Source(String),
+}
+
impl SourceId {
/// Creates a `SourceId` object from the kind and URL.
///
/// The canonical url will be calculated, but the precise field will not
- fn new(kind: SourceKind, url: Url, name: Option<&str>) -> CargoResult<SourceId> {
+ fn new(kind: SourceKind, url: Url, key: Option<KeyOf>) -> CargoResult<SourceId> {
if kind == SourceKind::SparseRegistry {
// Sparse URLs are different because they store the kind prefix (sparse+)
// in the URL. This is because the prefix is necessary to differentiate
@@ -109,8 +119,7 @@ impl SourceId {
canonical_url: CanonicalUrl::new(&url)?,
url,
precise: None,
- name: name.map(|n| n.into()),
- alt_registry_key: None,
+ registry_key: key,
});
Ok(source_id)
}
@@ -148,10 +157,8 @@ impl SourceId {
/// 656c58fb7c5ef5f12bc747f");
/// ```
pub fn from_url(string: &str) -> CargoResult<SourceId> {
- let mut parts = string.splitn(2, '+');
- let kind = parts.next().unwrap();
- let url = parts
- .next()
+ let (kind, url) = string
+ .split_once('+')
.ok_or_else(|| anyhow::format_err!("invalid source `{}`", string))?;
match kind {
@@ -230,10 +237,18 @@ impl SourceId {
SourceId::new(kind, url.to_owned(), None)
}
- /// Creates a `SourceId` from a remote registry URL with given name.
- pub fn for_alt_registry(url: &Url, name: &str) -> CargoResult<SourceId> {
+ /// Creates a `SourceId` for a remote registry from the `[registries]` table or crates.io.
+ pub fn for_alt_registry(url: &Url, key: &str) -> CargoResult<SourceId> {
let kind = Self::remote_source_kind(url);
- SourceId::new(kind, url.to_owned(), Some(name))
+ let key = KeyOf::Registry(key.into());
+ SourceId::new(kind, url.to_owned(), Some(key))
+ }
+
+ /// Creates a `SourceId` for a remote registry from the `[source]` replacement table.
+ pub fn for_source_replacement_registry(url: &Url, key: &str) -> CargoResult<SourceId> {
+ let kind = Self::remote_source_kind(url);
+ let key = KeyOf::Source(key.into());
+ SourceId::new(kind, url.to_owned(), Some(key))
}
/// Creates a `SourceId` from a local registry path.
@@ -253,11 +268,7 @@ impl SourceId {
/// This is the main cargo registry by default, but it can be overridden in
/// a `.cargo/config.toml`.
pub fn crates_io(config: &Config) -> CargoResult<SourceId> {
- config.crates_io_source_id(|| {
- config.check_registry_index_not_set()?;
- let url = CRATES_IO_INDEX.into_url().unwrap();
- SourceId::new(SourceKind::Registry, url, Some(CRATES_IO_REGISTRY))
- })
+ config.crates_io_source_id()
}
/// Returns the `SourceId` corresponding to the main repository, using the
@@ -266,7 +277,8 @@ impl SourceId {
if Self::crates_io_is_sparse(config)? {
config.check_registry_index_not_set()?;
let url = CRATES_IO_HTTP_INDEX.into_url().unwrap();
- SourceId::new(SourceKind::SparseRegistry, url, Some(CRATES_IO_REGISTRY))
+ let key = KeyOf::Registry(CRATES_IO_REGISTRY.into());
+ SourceId::new(SourceKind::SparseRegistry, url, Some(key))
} else {
Self::crates_io(config)
}
@@ -293,15 +305,7 @@ impl SourceId {
return Self::crates_io(config);
}
let url = config.get_registry_index(key)?;
- let kind = Self::remote_source_kind(&url);
- Ok(SourceId::wrap(SourceIdInner {
- kind,
- canonical_url: CanonicalUrl::new(&url)?,
- url,
- precise: None,
- name: Some(key.to_string()),
- alt_registry_key: Some(key.to_string()),
- }))
+ Self::for_alt_registry(&url, key)
}
/// Gets this source URL.
@@ -326,10 +330,8 @@ impl SourceId {
/// Displays the name of a registry if it has one. Otherwise just the URL.
pub fn display_registry_name(self) -> String {
- if self.is_crates_io() {
- CRATES_IO_REGISTRY.to_string()
- } else if let Some(name) = &self.inner.name {
- name.clone()
+ if let Some(key) = self.inner.registry_key.as_ref().map(|k| k.key()) {
+ key.into()
} else if self.precise().is_some() {
// We remove `precise` here to retrieve an permissive version of
// `SourceIdInner`, which may contain the registry name.
@@ -339,11 +341,10 @@ impl SourceId {
}
}
- /// Gets the name of the remote registry as defined in the `[registries]` table.
- /// WARNING: alt registries that come from Cargo.lock, or --index will
- /// not have a name.
+ /// Gets the name of the remote registry as defined in the `[registries]` table,
+ /// or the built-in `crates-io` key.
pub fn alt_registry_key(&self) -> Option<&str> {
- self.inner.alt_registry_key.as_deref()
+ self.inner.registry_key.as_ref()?.alternative_registry()
}
/// Returns `true` if this source is from a filesystem path.
@@ -396,25 +397,27 @@ impl SourceId {
self,
config: &'a Config,
yanked_whitelist: &HashSet<PackageId>,
- ) -> CargoResult<Box<dyn super::Source + 'a>> {
+ ) -> CargoResult<Box<dyn Source + 'a>> {
trace!("loading SourceId; {}", self);
match self.inner.kind {
SourceKind::Git(..) => Ok(Box::new(GitSource::new(self, config)?)),
SourceKind::Path => {
- let path = match self.inner.url.to_file_path() {
- Ok(p) => p,
- Err(()) => panic!("path sources cannot be remote"),
- };
+ let path = self
+ .inner
+ .url
+ .to_file_path()
+ .expect("path sources cannot be remote");
Ok(Box::new(PathSource::new(&path, self, config)))
}
SourceKind::Registry | SourceKind::SparseRegistry => Ok(Box::new(
RegistrySource::remote(self, yanked_whitelist, config)?,
)),
SourceKind::LocalRegistry => {
- let path = match self.inner.url.to_file_path() {
- Ok(p) => p,
- Err(()) => panic!("path sources cannot be remote"),
- };
+ let path = self
+ .inner
+ .url
+ .to_file_path()
+ .expect("path sources cannot be remote");
Ok(Box::new(RegistrySource::local(
self,
&path,
@@ -423,20 +426,16 @@ impl SourceId {
)))
}
SourceKind::Directory => {
- let path = match self.inner.url.to_file_path() {
- Ok(p) => p,
- Err(()) => panic!("path sources cannot be remote"),
- };
+ let path = self
+ .inner
+ .url
+ .to_file_path()
+ .expect("path sources cannot be remote");
Ok(Box::new(DirectorySource::new(&path, self, config)))
}
}
}
- /// Gets the value of the precise field.
- pub fn precise(self) -> Option<&'static str> {
- self.inner.precise.as_deref()
- }
-
/// Gets the Git reference if this is a git source, otherwise `None`.
pub fn git_reference(self) -> Option<&'static GitReference> {
match self.inner.kind {
@@ -445,6 +444,33 @@ impl SourceId {
}
}
+ /// Gets the value of the precise field.
+ pub fn precise(self) -> Option<&'static str> {
+ self.inner.precise.as_deref()
+ }
+
+ /// Check if the precise data field stores information for this `name`
+ /// from a call to [SourceId::with_precise_registry_version].
+ ///
+ /// If so return the version currently in the lock file and the version to be updated to.
+ /// If specified, our own source will have a precise version listed of the form
+ // `<pkg>=<p_req>-><f_req>` where `<pkg>` is the name of a crate on
+ // this source, `<p_req>` is the version installed and `<f_req>` is the
+ // version requested (argument to `--precise`).
+ pub fn precise_registry_version(
+ self,
+ name: &str,
+ ) -> Option<(semver::Version, semver::Version)> {
+ self.inner
+ .precise
+ .as_deref()
+ .and_then(|p| p.strip_prefix(name)?.strip_prefix('='))
+ .map(|p| {
+ let (current, requested) = p.split_once("->").unwrap();
+ (current.to_semver().unwrap(), requested.to_semver().unwrap())
+ })
+ }
+
/// Creates a new `SourceId` from this source with the given `precise`.
pub fn with_precise(self, v: Option<String>) -> SourceId {
SourceId::wrap(SourceIdInner {
@@ -453,6 +479,23 @@ impl SourceId {
})
}
+ /// When updating a lock file on a version using `cargo update --precise`
+ /// the requested version is stored in the precise field.
+ /// On a registry dependency we also need to keep track of the package that
+ /// should be updated and even which of the versions should be updated.
+ /// All of this gets encoded in the precise field using this method.
+ /// The data can be read with [SourceId::precise_registry_version]
+ pub fn with_precise_registry_version(
+ self,
+ name: impl fmt::Display,
+ version: &semver::Version,
+ precise: &str,
+ ) -> CargoResult<SourceId> {
+ semver::Version::parse(precise)
+ .with_context(|| format!("invalid version format for precise version `{precise}`"))?;
+ Ok(self.with_precise(Some(format!("{}={}->{}", name, version, precise))))
+ }
+
/// Returns `true` if the remote registry is the standard <https://crates.io>.
pub fn is_crates_io(self) -> bool {
match self.inner.kind {
@@ -614,10 +657,9 @@ impl Hash for SourceId {
/// The hash of `SourceIdInner` is used to retrieve its interned value from
/// `SOURCE_ID_CACHE`. We only care about fields that make `SourceIdInner`
/// unique. Optional fields not affecting the uniqueness must be excluded,
-/// such as [`name`] and [`alt_registry_key`]. That's why this is not derived.
+/// such as [`registry_key`]. That's why this is not derived.
///
-/// [`name`]: SourceIdInner::name
-/// [`alt_registry_key`]: SourceIdInner::alt_registry_key
+/// [`registry_key`]: SourceIdInner::registry_key
impl Hash for SourceIdInner {
fn hash<S: hash::Hasher>(&self, into: &mut S) {
self.kind.hash(into);
@@ -830,6 +872,23 @@ impl<'a> fmt::Display for PrettyRef<'a> {
}
}
+impl KeyOf {
+ /// Gets the underlying key.
+ fn key(&self) -> &str {
+ match self {
+ KeyOf::Registry(k) | KeyOf::Source(k) => k,
+ }
+ }
+
+ /// Gets the key if it's from an alternative registry.
+ fn alternative_registry(&self) -> Option<&str> {
+ match self {
+ KeyOf::Registry(k) => Some(k),
+ _ => None,
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
use super::{GitReference, SourceId, SourceKind};
diff --git a/src/tools/cargo/src/cargo/core/summary.rs b/src/tools/cargo/src/cargo/core/summary.rs
index 1883df33b..128c0db9c 100644
--- a/src/tools/cargo/src/cargo/core/summary.rs
+++ b/src/tools/cargo/src/cargo/core/summary.rs
@@ -1,6 +1,7 @@
use crate::core::{Dependency, PackageId, SourceId};
use crate::util::interning::InternedString;
use crate::util::CargoResult;
+use crate::util::RustVersion;
use anyhow::bail;
use semver::Version;
use std::collections::{BTreeMap, HashMap, HashSet};
@@ -25,7 +26,7 @@ struct Inner {
features: Rc<FeatureMap>,
checksum: Option<String>,
links: Option<InternedString>,
- rust_version: Option<InternedString>,
+ rust_version: Option<RustVersion>,
}
impl Summary {
@@ -34,7 +35,7 @@ impl Summary {
dependencies: Vec<Dependency>,
features: &BTreeMap<InternedString, Vec<InternedString>>,
links: Option<impl Into<InternedString>>,
- rust_version: Option<impl Into<InternedString>>,
+ rust_version: Option<RustVersion>,
) -> CargoResult<Summary> {
// ****CAUTION**** If you change anything here that may raise a new
// error, be sure to coordinate that change with either the index
@@ -56,7 +57,7 @@ impl Summary {
features: Rc::new(feature_map),
checksum: None,
links: links.map(|l| l.into()),
- rust_version: rust_version.map(|l| l.into()),
+ rust_version,
}),
})
}
@@ -87,8 +88,8 @@ impl Summary {
self.inner.links
}
- pub fn rust_version(&self) -> Option<InternedString> {
- self.inner.rust_version
+ pub fn rust_version(&self) -> Option<&RustVersion> {
+ self.inner.rust_version.as_ref()
}
pub fn override_id(mut self, id: PackageId) -> Summary {
diff --git a/src/tools/cargo/src/cargo/core/workspace.rs b/src/tools/cargo/src/cargo/core/workspace.rs
index 9ee0cbe04..db379d780 100644
--- a/src/tools/cargo/src/cargo/core/workspace.rs
+++ b/src/tools/cargo/src/cargo/core/workspace.rs
@@ -23,6 +23,7 @@ use crate::util::edit_distance;
use crate::util::errors::{CargoResult, ManifestError};
use crate::util::interning::InternedString;
use crate::util::toml::{read_manifest, InheritableFields, TomlDependency, TomlProfiles};
+use crate::util::RustVersion;
use crate::util::{config::ConfigRelativePath, Config, Filesystem, IntoUrl};
use cargo_util::paths;
use cargo_util::paths::normalize_path;
@@ -509,7 +510,7 @@ impl<'cfg> Workspace<'cfg> {
self.members
.iter()
.filter_map(move |path| match packages.get(path) {
- &MaybePackage::Package(ref p) => Some(p),
+ MaybePackage::Package(p) => Some(p),
_ => None,
})
}
@@ -540,7 +541,7 @@ impl<'cfg> Workspace<'cfg> {
self.default_members
.iter()
.filter_map(move |path| match packages.get(path) {
- &MaybePackage::Package(ref p) => Some(p),
+ MaybePackage::Package(p) => Some(p),
_ => None,
})
}
@@ -595,6 +596,12 @@ impl<'cfg> Workspace<'cfg> {
self
}
+ /// Get the lowest-common denominator `package.rust-version` within the workspace, if specified
+ /// anywhere
+ pub fn rust_version(&self) -> Option<&RustVersion> {
+ self.members().filter_map(|pkg| pkg.rust_version()).min()
+ }
+
pub fn custom_metadata(&self) -> Option<&toml::Value> {
self.custom_metadata.as_ref()
}
@@ -656,18 +663,15 @@ impl<'cfg> Workspace<'cfg> {
/// will transitively follow all `path` dependencies looking for members of
/// the workspace.
fn find_members(&mut self) -> CargoResult<()> {
- let workspace_config = match self.load_workspace_config()? {
- Some(workspace_config) => workspace_config,
- None => {
- debug!("find_members - only me as a member");
- self.members.push(self.current_manifest.clone());
- self.default_members.push(self.current_manifest.clone());
- if let Ok(pkg) = self.current() {
- let id = pkg.package_id();
- self.member_ids.insert(id);
- }
- return Ok(());
+ let Some(workspace_config) = self.load_workspace_config()? else {
+ debug!("find_members - only me as a member");
+ self.members.push(self.current_manifest.clone());
+ self.default_members.push(self.current_manifest.clone());
+ if let Ok(pkg) = self.current() {
+ let id = pkg.package_id();
+ self.member_ids.insert(id);
}
+ return Ok(());
};
// self.root_manifest must be Some to have retrieved workspace_config
@@ -1021,11 +1025,18 @@ impl<'cfg> Workspace<'cfg> {
.max()
{
let resolver = edition.default_resolve_behavior().to_manifest();
- self.config.shell().warn(format_args!("some crates are on edition {edition} which defaults to `resolver = \"{resolver}\"`, but virtual workspaces default to `resolver = \"1\"`"))?;
+ self.config.shell().warn(format_args!(
+ "virtual workspace defaulting to `resolver = \"1\"` despite one or more workspace members being on edition {edition} which implies `resolver = \"{resolver}\"`"
+ ))?;
self.config.shell().note(
"to keep the current resolver, specify `workspace.resolver = \"1\"` in the workspace root's manifest",
)?;
- self.config.shell().note(format_args!("to use the edition {edition} resolver, specify `workspace.resolver = \"{resolver}\"` in the workspace root's manifest"))?;
+ self.config.shell().note(format_args!(
+ "to use the edition {edition} resolver, specify `workspace.resolver = \"{resolver}\"` in the workspace root's manifest"
+ ))?;
+ self.config.shell().note(
+ "for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions",
+ )?;
}
}
}
@@ -1035,7 +1046,7 @@ impl<'cfg> Workspace<'cfg> {
pub fn load(&self, manifest_path: &Path) -> CargoResult<Package> {
match self.packages.maybe_get(manifest_path) {
- Some(&MaybePackage::Package(ref p)) => return Ok(p.clone()),
+ Some(MaybePackage::Package(p)) => return Ok(p.clone()),
Some(&MaybePackage::Virtual(_)) => bail!("cannot load workspace root"),
None => {}
}
@@ -1679,9 +1690,8 @@ impl WorkspaceRootConfig {
}
fn expand_member_path(path: &Path) -> CargoResult<Vec<PathBuf>> {
- let path = match path.to_str() {
- Some(p) => p,
- None => return Ok(Vec::new()),
+ let Some(path) = path.to_str() else {
+ return Ok(Vec::new());
};
let res = glob(path).with_context(|| format!("could not parse pattern `{}`", &path))?;
let res = res
diff --git a/src/tools/cargo/src/cargo/lib.rs b/src/tools/cargo/src/cargo/lib.rs
index 9f6edf80d..908ff4ecc 100644
--- a/src/tools/cargo/src/cargo/lib.rs
+++ b/src/tools/cargo/src/cargo/lib.rs
@@ -1,16 +1,3 @@
-// For various reasons, some idioms are still allow'ed, but we would like to
-// test and enforce them.
-#![warn(rust_2018_idioms)]
-// Due to some of the default clippy lints being somewhat subjective and not
-// necessarily an improvement, we prefer to not use them at this time.
-#![allow(clippy::all)]
-#![warn(clippy::disallowed_methods)]
-#![warn(clippy::self_named_module_files)]
-#![warn(clippy::print_stdout)]
-#![warn(clippy::print_stderr)]
-#![warn(clippy::dbg_macro)]
-#![allow(rustdoc::private_intra_doc_links)]
-
//! # Cargo as a library
//!
//! There are two places you can find API documentation of cargo-the-library,
@@ -20,7 +7,7 @@
//! - <https://doc.rust-lang.org/nightly/nightly-rustc/cargo>: targeted at cargo contributors
//! - Updated on each update of the `cargo` submodule in `rust-lang/rust`
//!
-//! **WARNING:** Using Cargo as a library has drawbacks, particulary the API is unstable,
+//! **WARNING:** Using Cargo as a library has drawbacks, particularly the API is unstable,
//! and there is no clear path to stabilize it soon at the time of writing. See [The Cargo Book:
//! External tools] for more on this topic.
//!
@@ -51,8 +38,8 @@
//! - [`core::compiler::fingerprint`]:
//! The `fingerprint` module contains all the code that handles detecting
//! if a crate needs to be recompiled.
-//! - [`core::source`]:
-//! The [`core::Source`] trait is an abstraction over different sources of packages.
+//! - [`sources::source`]:
+//! The [`sources::source::Source`] trait is an abstraction over different sources of packages.
//! Sources are uniquely identified by a [`core::SourceId`]. Sources are implemented in the [`sources`]
//! directory.
//! - [`util`]:
@@ -91,9 +78,7 @@
//! This is the `#[cargo_test]` proc-macro used by the test suite to define tests.
//! - [`credential`](https://github.com/rust-lang/cargo/tree/master/credential)
//! This subdirectory contains several packages for implementing the
-//! experimental
-//! [credential-process](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#credential-process)
-//! feature.
+//! [credential providers](https://doc.rust-lang.org/nightly/cargo/reference/registry-authentication.html).
//! - [`mdman`](https://github.com/rust-lang/cargo/tree/master/crates/mdman)
//! ([nightly docs](https://doc.rust-lang.org/nightly/nightly-rustc/mdman/index.html)):
//! This is a utility for generating cargo's man pages. See [Building the man
@@ -144,6 +129,20 @@
//! [The Cargo Book]: https://doc.rust-lang.org/cargo/
//! [Cargo Contributor Guide]: https://doc.crates.io/contrib/
+// TODO: consider removing these lint attributes when `-Zlints` hits stable.
+// For various reasons, some idioms are still allow'ed, but we would like to
+// test and enforce them.
+#![warn(rust_2018_idioms)]
+// Due to some of the default clippy lints being somewhat subjective and not
+// necessarily an improvement, we prefer to not use them at this time.
+#![allow(clippy::all)]
+#![warn(clippy::disallowed_methods)]
+#![warn(clippy::self_named_module_files)]
+#![warn(clippy::print_stdout)]
+#![warn(clippy::print_stderr)]
+#![warn(clippy::dbg_macro)]
+#![allow(rustdoc::private_intra_doc_links)]
+
use crate::core::shell::Verbosity::Verbose;
use crate::core::Shell;
use anyhow::Error;
diff --git a/src/tools/cargo/src/cargo/ops/cargo_add/mod.rs b/src/tools/cargo/src/cargo/ops/cargo_add/mod.rs
index 11ca282ee..968d6068f 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_add/mod.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_add/mod.rs
@@ -12,20 +12,18 @@ use anyhow::Context as _;
use cargo_util::paths;
use indexmap::IndexSet;
use itertools::Itertools;
-use termcolor::Color::Green;
-use termcolor::Color::Red;
-use termcolor::ColorSpec;
use toml_edit::Item as TomlItem;
use crate::core::dependency::DepKind;
use crate::core::registry::PackageRegistry;
use crate::core::FeatureValue;
use crate::core::Package;
-use crate::core::QueryKind;
use crate::core::Registry;
use crate::core::Shell;
use crate::core::Summary;
use crate::core::Workspace;
+use crate::sources::source::QueryKind;
+use crate::util::style;
use crate::util::toml_mut::dependency::Dependency;
use crate::util::toml_mut::dependency::GitSource;
use crate::util::toml_mut::dependency::MaybeWorkspace;
@@ -34,6 +32,7 @@ use crate::util::toml_mut::dependency::Source;
use crate::util::toml_mut::dependency::WorkspaceSource;
use crate::util::toml_mut::manifest::DepTable;
use crate::util::toml_mut::manifest::LocalManifest;
+use crate::util::RustVersion;
use crate::CargoResult;
use crate::Config;
use crate_spec::CrateSpec;
@@ -503,9 +502,7 @@ fn get_existing_dependency(
})
.collect();
possible.sort_by_key(|(key, _)| *key);
- let (key, dep) = if let Some(item) = possible.pop() {
- item
- } else {
+ let Some((key, dep)) = possible.pop() else {
return Ok(None);
};
let mut dep = dep?;
@@ -567,16 +564,7 @@ fn get_latest_dependency(
})?;
if config.cli_unstable().msrv_policy && honor_rust_version {
- fn parse_msrv(rust_version: impl AsRef<str>) -> (u64, u64, u64) {
- // HACK: `rust-version` is a subset of the `VersionReq` syntax that only ever
- // has one comparator with a required minor and optional patch, and uses no
- // other features. If in the future this syntax is expanded, this code will need
- // to be updated.
- let version_req = semver::VersionReq::parse(rust_version.as_ref()).unwrap();
- assert!(version_req.comparators.len() == 1);
- let comp = &version_req.comparators[0];
- assert_eq!(comp.op, semver::Op::Caret);
- assert_eq!(comp.pre, semver::Prerelease::EMPTY);
+ fn parse_msrv(comp: &RustVersion) -> (u64, u64, u64) {
(comp.major, comp.minor.unwrap_or(0), comp.patch.unwrap_or(0))
}
@@ -636,7 +624,7 @@ fn get_latest_dependency(
fn rust_version_incompat_error(
dep: &str,
- rust_version: &str,
+ rust_version: &RustVersion,
lowest_rust_version: Option<&Summary>,
) -> anyhow::Error {
let mut error_msg = format!(
@@ -955,51 +943,73 @@ fn print_dep_table_msg(shell: &mut Shell, dep: &DependencyUI) -> CargoResult<()>
if matches!(shell.verbosity(), crate::core::shell::Verbosity::Quiet) {
return Ok(());
}
+
let (activated, deactivated) = dep.features();
if !activated.is_empty() || !deactivated.is_empty() {
let prefix = format!("{:>13}", " ");
- let suffix = if let Some(version) = &dep.available_version {
- let mut version = version.clone();
- version.build = Default::default();
- let version = version.to_string();
- // Avoid displaying the version if it will visually look like the version req that we
- // showed earlier
- let version_req = dep
- .version()
- .and_then(|v| semver::VersionReq::parse(v).ok())
- .and_then(|v| precise_version(&v));
- if version_req.as_deref() != Some(version.as_str()) {
- format!(" as of v{version}")
- } else {
- "".to_owned()
+ let suffix = format_features_version_suffix(&dep);
+
+ shell.write_stderr(format_args!("{prefix}Features{suffix}:\n"), &style::NOP)?;
+
+ const MAX_FEATURE_PRINTS: usize = 30;
+ let total_activated = activated.len();
+ let total_deactivated = deactivated.len();
+
+ if total_activated <= MAX_FEATURE_PRINTS {
+ for feat in activated {
+ shell.write_stderr(&prefix, &style::NOP)?;
+ shell.write_stderr('+', &style::GOOD)?;
+ shell.write_stderr(format_args!(" {feat}\n"), &style::NOP)?;
}
} else {
- "".to_owned()
- };
- shell.write_stderr(
- format_args!("{}Features{}:\n", prefix, suffix),
- &ColorSpec::new(),
- )?;
- for feat in activated {
- shell.write_stderr(&prefix, &ColorSpec::new())?;
- shell.write_stderr('+', &ColorSpec::new().set_bold(true).set_fg(Some(Green)))?;
- shell.write_stderr(format_args!(" {}\n", feat), &ColorSpec::new())?;
+ shell.write_stderr(
+ format_args!("{prefix}{total_activated} activated features\n"),
+ &style::NOP,
+ )?;
}
- for feat in deactivated {
- shell.write_stderr(&prefix, &ColorSpec::new())?;
- shell.write_stderr('-', &ColorSpec::new().set_bold(true).set_fg(Some(Red)))?;
- shell.write_stderr(format_args!(" {}\n", feat), &ColorSpec::new())?;
+
+ if total_activated + total_deactivated <= MAX_FEATURE_PRINTS {
+ for feat in deactivated {
+ shell.write_stderr(&prefix, &style::NOP)?;
+ shell.write_stderr('-', &style::ERROR)?;
+ shell.write_stderr(format_args!(" {feat}\n"), &style::NOP)?;
+ }
+ } else {
+ shell.write_stderr(
+ format_args!("{prefix}{total_deactivated} deactivated features\n"),
+ &style::NOP,
+ )?;
}
}
Ok(())
}
+fn format_features_version_suffix(dep: &DependencyUI) -> String {
+ if let Some(version) = &dep.available_version {
+ let mut version = version.clone();
+ version.build = Default::default();
+ let version = version.to_string();
+ // Avoid displaying the version if it will visually look like the version req that we
+ // showed earlier
+ let version_req = dep
+ .version()
+ .and_then(|v| semver::VersionReq::parse(v).ok())
+ .and_then(|v| precise_version(&v));
+ if version_req.as_deref() != Some(version.as_str()) {
+ format!(" as of v{version}")
+ } else {
+ "".to_owned()
+ }
+ } else {
+ "".to_owned()
+ }
+}
+
// Based on Iterator::is_sorted from nightly std; remove in favor of that when stabilized.
fn is_sorted(mut it: impl Iterator<Item = impl PartialOrd>) -> bool {
- let mut last = match it.next() {
- Some(e) => e,
- None => return true,
+ let Some(mut last) = it.next() else {
+ return true;
};
for curr in it {
diff --git a/src/tools/cargo/src/cargo/ops/cargo_clean.rs b/src/tools/cargo/src/cargo/ops/cargo_clean.rs
index b9b33690e..6f58b8bdc 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_clean.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_clean.rs
@@ -5,15 +5,14 @@ use crate::ops;
use crate::util::edit_distance;
use crate::util::errors::CargoResult;
use crate::util::interning::InternedString;
-use crate::util::{Config, Progress, ProgressStyle};
-
-use anyhow::Context as _;
+use crate::util::{human_readable_bytes, Config, Progress, ProgressStyle};
+use anyhow::bail;
use cargo_util::paths;
use std::fs;
-use std::path::Path;
+use std::path::{Path, PathBuf};
-pub struct CleanOptions<'a> {
- pub config: &'a Config,
+pub struct CleanOptions<'cfg> {
+ pub config: &'cfg Config,
/// A list of packages to clean. If empty, everything is cleaned.
pub spec: Vec<String>,
/// The target arch triple to clean, or None for the host arch
@@ -24,40 +23,75 @@ pub struct CleanOptions<'a> {
pub requested_profile: InternedString,
/// Whether to just clean the doc directory
pub doc: bool,
+ /// If set, doesn't delete anything.
+ pub dry_run: bool,
+}
+
+pub struct CleanContext<'cfg> {
+ pub config: &'cfg Config,
+ progress: Box<dyn CleaningProgressBar + 'cfg>,
+ pub dry_run: bool,
+ num_files_removed: u64,
+ num_dirs_removed: u64,
+ total_bytes_removed: u64,
}
-/// Cleans the package's build artifacts.
+/// Cleans various caches.
pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
let mut target_dir = ws.target_dir();
- let config = ws.config();
+ let config = opts.config;
+ let mut ctx = CleanContext::new(config);
+ ctx.dry_run = opts.dry_run;
- // If the doc option is set, we just want to delete the doc directory.
if opts.doc {
+ if !opts.spec.is_empty() {
+ // FIXME: https://github.com/rust-lang/cargo/issues/8790
+ // This should support the ability to clean specific packages
+ // within the doc directory. It's a little tricky since it
+ // needs to find all documentable targets, but also consider
+ // the fact that target names might overlap with dependency
+ // names and such.
+ bail!("--doc cannot be used with -p");
+ }
+ // If the doc option is set, we just want to delete the doc directory.
target_dir = target_dir.join("doc");
- return clean_entire_folder(&target_dir.into_path_unlocked(), config);
- }
-
- let profiles = Profiles::new(ws, opts.requested_profile)?;
+ ctx.remove_paths(&[target_dir.into_path_unlocked()])?;
+ } else {
+ let profiles = Profiles::new(&ws, opts.requested_profile)?;
+
+ if opts.profile_specified {
+ // After parsing profiles we know the dir-name of the profile, if a profile
+ // was passed from the command line. If so, delete only the directory of
+ // that profile.
+ let dir_name = profiles.get_dir_name();
+ target_dir = target_dir.join(dir_name);
+ }
- if opts.profile_specified {
- // After parsing profiles we know the dir-name of the profile, if a profile
- // was passed from the command line. If so, delete only the directory of
- // that profile.
- let dir_name = profiles.get_dir_name();
- target_dir = target_dir.join(dir_name);
+ // If we have a spec, then we need to delete some packages, otherwise, just
+ // remove the whole target directory and be done with it!
+ //
+ // Note that we don't bother grabbing a lock here as we're just going to
+ // blow it all away anyway.
+ if opts.spec.is_empty() {
+ ctx.remove_paths(&[target_dir.into_path_unlocked()])?;
+ } else {
+ clean_specs(&mut ctx, &ws, &profiles, &opts.targets, &opts.spec)?;
+ }
}
- // If we have a spec, then we need to delete some packages, otherwise, just
- // remove the whole target directory and be done with it!
- //
- // Note that we don't bother grabbing a lock here as we're just going to
- // blow it all away anyway.
- if opts.spec.is_empty() {
- return clean_entire_folder(&target_dir.into_path_unlocked(), config);
- }
+ ctx.display_summary()?;
+ Ok(())
+}
+fn clean_specs(
+ ctx: &mut CleanContext<'_>,
+ ws: &Workspace<'_>,
+ profiles: &Profiles,
+ targets: &[String],
+ spec: &[String],
+) -> CargoResult<()> {
// Clean specific packages.
- let requested_kinds = CompileKind::from_requested_targets(config, &opts.targets)?;
+ let requested_kinds = CompileKind::from_requested_targets(ctx.config, targets)?;
let target_data = RustcTargetData::new(ws, &requested_kinds)?;
let (pkg_set, resolve) = ops::resolve_ws(ws)?;
let prof_dir_name = profiles.get_dir_name();
@@ -75,7 +109,7 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
.collect::<CargoResult<_>>()?;
// A Vec of layouts. This is a little convoluted because there can only be
// one host_layout.
- let layouts = if opts.targets.is_empty() {
+ let layouts = if targets.is_empty() {
vec![(CompileKind::Host, &host_layout)]
} else {
target_layouts
@@ -96,11 +130,11 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
// Get Packages for the specified specs.
let mut pkg_ids = Vec::new();
- for spec_str in opts.spec.iter() {
+ for spec_str in spec.iter() {
// Translate the spec to a Package.
let spec = PackageIdSpec::parse(spec_str)?;
- if spec.version().is_some() {
- config.shell().warn(&format!(
+ if spec.partial_version().is_some() {
+ ctx.config.shell().warn(&format!(
"version qualifier in `-p {}` is ignored, \
cleaning all versions of `{}` found",
spec_str,
@@ -108,7 +142,7 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
))?;
}
if spec.url().is_some() {
- config.shell().warn(&format!(
+ ctx.config.shell().warn(&format!(
"url qualifier in `-p {}` ignored, \
cleaning all versions of `{}` found",
spec_str,
@@ -133,20 +167,16 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
}
let packages = pkg_set.get_many(pkg_ids)?;
- let mut progress = CleaningPackagesBar::new(config, packages.len());
+ ctx.progress = Box::new(CleaningPackagesBar::new(ctx.config, packages.len()));
+
for pkg in packages {
let pkg_dir = format!("{}-*", pkg.name());
- progress.on_cleaning_package(&pkg.name())?;
+ ctx.progress.on_cleaning_package(&pkg.name())?;
// Clean fingerprints.
for (_, layout) in &layouts_with_host {
let dir = escape_glob_path(layout.fingerprint())?;
- rm_rf_package_glob_containing_hash(
- &pkg.name(),
- &Path::new(&dir).join(&pkg_dir),
- config,
- &mut progress,
- )?;
+ ctx.rm_rf_package_glob_containing_hash(&pkg.name(), &Path::new(&dir).join(&pkg_dir))?;
}
for target in pkg.targets() {
@@ -154,11 +184,9 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
// Get both the build_script_build and the output directory.
for (_, layout) in &layouts_with_host {
let dir = escape_glob_path(layout.build())?;
- rm_rf_package_glob_containing_hash(
+ ctx.rm_rf_package_glob_containing_hash(
&pkg.name(),
&Path::new(&dir).join(&pkg_dir),
- config,
- &mut progress,
)?;
}
continue;
@@ -190,35 +218,35 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
let dir_glob = escape_glob_path(dir)?;
let dir_glob = Path::new(&dir_glob);
- rm_rf_glob(&dir_glob.join(&hashed_name), config, &mut progress)?;
- rm_rf(&dir.join(&unhashed_name), config, &mut progress)?;
+ ctx.rm_rf_glob(&dir_glob.join(&hashed_name))?;
+ ctx.rm_rf(&dir.join(&unhashed_name))?;
// Remove dep-info file generated by rustc. It is not tracked in
// file_types. It does not have a prefix.
let hashed_dep_info = dir_glob.join(format!("{}-*.d", crate_name));
- rm_rf_glob(&hashed_dep_info, config, &mut progress)?;
+ ctx.rm_rf_glob(&hashed_dep_info)?;
let unhashed_dep_info = dir.join(format!("{}.d", crate_name));
- rm_rf(&unhashed_dep_info, config, &mut progress)?;
+ ctx.rm_rf(&unhashed_dep_info)?;
// Remove split-debuginfo files generated by rustc.
let split_debuginfo_obj = dir_glob.join(format!("{}.*.o", crate_name));
- rm_rf_glob(&split_debuginfo_obj, config, &mut progress)?;
+ ctx.rm_rf_glob(&split_debuginfo_obj)?;
let split_debuginfo_dwo = dir_glob.join(format!("{}.*.dwo", crate_name));
- rm_rf_glob(&split_debuginfo_dwo, config, &mut progress)?;
+ ctx.rm_rf_glob(&split_debuginfo_dwo)?;
let split_debuginfo_dwp = dir_glob.join(format!("{}.*.dwp", crate_name));
- rm_rf_glob(&split_debuginfo_dwp, config, &mut progress)?;
+ ctx.rm_rf_glob(&split_debuginfo_dwp)?;
// Remove the uplifted copy.
if let Some(uplift_dir) = uplift_dir {
let uplifted_path = uplift_dir.join(file_type.uplift_filename(target));
- rm_rf(&uplifted_path, config, &mut progress)?;
+ ctx.rm_rf(&uplifted_path)?;
// Dep-info generated by Cargo itself.
let dep_info = uplifted_path.with_extension("d");
- rm_rf(&dep_info, config, &mut progress)?;
+ ctx.rm_rf(&dep_info)?;
}
}
// TODO: what to do about build_script_build?
let dir = escape_glob_path(layout.incremental())?;
let incremental = Path::new(&dir).join(format!("{}-*", crate_name));
- rm_rf_glob(&incremental, config, &mut progress)?;
+ ctx.rm_rf_glob(&incremental)?;
}
}
}
@@ -234,92 +262,193 @@ fn escape_glob_path(pattern: &Path) -> CargoResult<String> {
Ok(glob::Pattern::escape(pattern))
}
-/// Glob remove artifacts for the provided `package`
-///
-/// Make sure the artifact is for `package` and not another crate that is prefixed by
-/// `package` by getting the original name stripped of the trailing hash and possible
-/// extension
-fn rm_rf_package_glob_containing_hash(
- package: &str,
- pattern: &Path,
- config: &Config,
- progress: &mut dyn CleaningProgressBar,
-) -> CargoResult<()> {
- // TODO: Display utf8 warning to user? Or switch to globset?
- let pattern = pattern
- .to_str()
- .ok_or_else(|| anyhow::anyhow!("expected utf-8 path"))?;
- for path in glob::glob(pattern)? {
- let path = path?;
-
- let pkg_name = path
- .file_name()
- .and_then(std::ffi::OsStr::to_str)
- .and_then(|artifact| artifact.rsplit_once('-'))
- .ok_or_else(|| anyhow::anyhow!("expected utf-8 path"))?
- .0;
-
- if pkg_name != package {
- continue;
+impl<'cfg> CleanContext<'cfg> {
+ pub fn new(config: &'cfg Config) -> Self {
+ // This progress bar will get replaced, this is just here to avoid needing
+ // an Option until the actual bar is created.
+ let progress = CleaningFolderBar::new(config, 0);
+ CleanContext {
+ config,
+ progress: Box::new(progress),
+ dry_run: false,
+ num_files_removed: 0,
+ num_dirs_removed: 0,
+ total_bytes_removed: 0,
}
+ }
- rm_rf(&path, config, progress)?;
+ /// Glob remove artifacts for the provided `package`
+ ///
+ /// Make sure the artifact is for `package` and not another crate that is prefixed by
+ /// `package` by getting the original name stripped of the trailing hash and possible
+ /// extension
+ fn rm_rf_package_glob_containing_hash(
+ &mut self,
+ package: &str,
+ pattern: &Path,
+ ) -> CargoResult<()> {
+ // TODO: Display utf8 warning to user? Or switch to globset?
+ let pattern = pattern
+ .to_str()
+ .ok_or_else(|| anyhow::anyhow!("expected utf-8 path"))?;
+ for path in glob::glob(pattern)? {
+ let path = path?;
+
+ let pkg_name = path
+ .file_name()
+ .and_then(std::ffi::OsStr::to_str)
+ .and_then(|artifact| artifact.rsplit_once('-'))
+ .ok_or_else(|| anyhow::anyhow!("expected utf-8 path"))?
+ .0;
+
+ if pkg_name != package {
+ continue;
+ }
+
+ self.rm_rf(&path)?;
+ }
+ Ok(())
}
- Ok(())
-}
-fn rm_rf_glob(
- pattern: &Path,
- config: &Config,
- progress: &mut dyn CleaningProgressBar,
-) -> CargoResult<()> {
- // TODO: Display utf8 warning to user? Or switch to globset?
- let pattern = pattern
- .to_str()
- .ok_or_else(|| anyhow::anyhow!("expected utf-8 path"))?;
- for path in glob::glob(pattern)? {
- rm_rf(&path?, config, progress)?;
+ fn rm_rf_glob(&mut self, pattern: &Path) -> CargoResult<()> {
+ // TODO: Display utf8 warning to user? Or switch to globset?
+ let pattern = pattern
+ .to_str()
+ .ok_or_else(|| anyhow::anyhow!("expected utf-8 path"))?;
+ for path in glob::glob(pattern)? {
+ self.rm_rf(&path?)?;
+ }
+ Ok(())
}
- Ok(())
-}
-fn rm_rf(path: &Path, config: &Config, progress: &mut dyn CleaningProgressBar) -> CargoResult<()> {
- if fs::symlink_metadata(path).is_err() {
- return Ok(());
+ pub fn rm_rf(&mut self, path: &Path) -> CargoResult<()> {
+ let meta = match fs::symlink_metadata(path) {
+ Ok(meta) => meta,
+ Err(e) => {
+ if e.kind() != std::io::ErrorKind::NotFound {
+ self.config
+ .shell()
+ .warn(&format!("cannot access {}: {e}", path.display()))?;
+ }
+ return Ok(());
+ }
+ };
+
+ // dry-run displays paths while walking, so don't print here.
+ if !self.dry_run {
+ self.config
+ .shell()
+ .verbose(|shell| shell.status("Removing", path.display()))?;
+ }
+ self.progress.display_now()?;
+
+ let mut rm_file = |path: &Path, meta: Result<std::fs::Metadata, _>| {
+ if let Ok(meta) = meta {
+ // Note: This can over-count bytes removed for hard-linked
+ // files. It also under-counts since it only counts the exact
+ // byte sizes and not the block sizes.
+ self.total_bytes_removed += meta.len();
+ }
+ self.num_files_removed += 1;
+ if !self.dry_run {
+ paths::remove_file(path)?;
+ }
+ Ok(())
+ };
+
+ if !meta.is_dir() {
+ return rm_file(path, Ok(meta));
+ }
+
+ for entry in walkdir::WalkDir::new(path).contents_first(true) {
+ let entry = entry?;
+ self.progress.on_clean()?;
+ if self.dry_run {
+ // This prints the path without the "Removing" status since I feel
+ // like it can be surprising or even frightening if cargo says it
+ // is removing something without actually removing it. And I can't
+ // come up with a different verb to use as the status.
+ self.config
+ .shell()
+ .verbose(|shell| Ok(writeln!(shell.out(), "{}", entry.path().display())?))?;
+ }
+ if entry.file_type().is_dir() {
+ self.num_dirs_removed += 1;
+ // The contents should have been removed by now, but sometimes a race condition is hit
+ // where other files have been added by the OS. `paths::remove_dir_all` also falls back
+ // to `std::fs::remove_dir_all`, which may be more reliable than a simple walk in
+ // platform-specific edge cases.
+ if !self.dry_run {
+ paths::remove_dir_all(entry.path())?;
+ }
+ } else {
+ rm_file(entry.path(), entry.metadata())?;
+ }
+ }
+
+ Ok(())
}
- config
- .shell()
- .verbose(|shell| shell.status("Removing", path.display()))?;
- progress.display_now()?;
-
- for entry in walkdir::WalkDir::new(path).contents_first(true) {
- let entry = entry?;
- progress.on_clean()?;
- if entry.file_type().is_dir() {
- // The contents should have been removed by now, but sometimes a race condition is hit
- // where other files have been added by the OS. `paths::remove_dir_all` also falls back
- // to `std::fs::remove_dir_all`, which may be more reliable than a simple walk in
- // platform-specific edge cases.
- paths::remove_dir_all(entry.path())
- .with_context(|| "could not remove build directory")?;
+ fn display_summary(&self) -> CargoResult<()> {
+ let status = if self.dry_run { "Summary" } else { "Removed" };
+ let byte_count = if self.total_bytes_removed == 0 {
+ String::new()
} else {
- paths::remove_file(entry.path()).with_context(|| "failed to remove build artifact")?;
+ // Don't show a fractional number of bytes.
+ if self.total_bytes_removed < 1024 {
+ format!(", {}B total", self.total_bytes_removed)
+ } else {
+ let (bytes, unit) = human_readable_bytes(self.total_bytes_removed);
+ format!(", {bytes:.1}{unit} total")
+ }
+ };
+ // I think displaying the number of directories removed isn't
+ // particularly interesting to the user. However, if there are 0
+ // files, and a nonzero number of directories, cargo should indicate
+ // that it did *something*, so directory counts are only shown in that
+ // case.
+ let file_count = match (self.num_files_removed, self.num_dirs_removed) {
+ (0, 0) => format!("0 files"),
+ (0, 1) => format!("1 directory"),
+ (0, 2..) => format!("{} directories", self.num_dirs_removed),
+ (1, _) => format!("1 file"),
+ (2.., _) => format!("{} files", self.num_files_removed),
+ };
+ self.config
+ .shell()
+ .status(status, format!("{file_count}{byte_count}"))?;
+ if self.dry_run {
+ self.config
+ .shell()
+ .warn("no files deleted due to --dry-run")?;
}
+ Ok(())
}
- Ok(())
-}
-
-fn clean_entire_folder(path: &Path, config: &Config) -> CargoResult<()> {
- let num_paths = walkdir::WalkDir::new(path).into_iter().count();
- let mut progress = CleaningFolderBar::new(config, num_paths);
- rm_rf(path, config, &mut progress)
+ /// Deletes all of the given paths, showing a progress bar as it proceeds.
+ ///
+ /// If any path does not exist, or is not accessible, this will not
+ /// generate an error. This only generates an error for other issues, like
+ /// not being able to write to the console.
+ pub fn remove_paths(&mut self, paths: &[PathBuf]) -> CargoResult<()> {
+ let num_paths = paths
+ .iter()
+ .map(|path| walkdir::WalkDir::new(path).into_iter().count())
+ .sum();
+ self.progress = Box::new(CleaningFolderBar::new(self.config, num_paths));
+ for path in paths {
+ self.rm_rf(path)?;
+ }
+ Ok(())
+ }
}
trait CleaningProgressBar {
fn display_now(&mut self) -> CargoResult<()>;
fn on_clean(&mut self) -> CargoResult<()>;
+ fn on_cleaning_package(&mut self, _package: &str) -> CargoResult<()> {
+ Ok(())
+ }
}
struct CleaningFolderBar<'cfg> {
@@ -372,13 +501,6 @@ impl<'cfg> CleaningPackagesBar<'cfg> {
}
}
- fn on_cleaning_package(&mut self, package: &str) -> CargoResult<()> {
- self.cur += 1;
- self.package_being_cleaned = String::from(package);
- self.bar
- .tick(self.cur_progress(), self.max, &self.format_message())
- }
-
fn cur_progress(&self) -> usize {
std::cmp::min(self.cur, self.max)
}
@@ -403,4 +525,11 @@ impl<'cfg> CleaningProgressBar for CleaningPackagesBar<'cfg> {
self.num_files_folders_cleaned += 1;
Ok(())
}
+
+ fn on_cleaning_package(&mut self, package: &str) -> CargoResult<()> {
+ self.cur += 1;
+ self.package_being_cleaned = String::from(package);
+ self.bar
+ .tick(self.cur_progress(), self.max, &self.format_message())
+ }
}
diff --git a/src/tools/cargo/src/cargo/ops/cargo_compile/mod.rs b/src/tools/cargo/src/cargo/ops/cargo_compile/mod.rs
index 1247ceda7..9cf8599c4 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_compile/mod.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_compile/mod.rs
@@ -184,7 +184,7 @@ pub fn print<'a>(
process.args(args);
}
if let CompileKind::Target(t) = kind {
- process.arg("--target").arg(t.short_name());
+ process.arg("--target").arg(t.rustc_target());
}
process.arg("--print").arg(print_opt_value);
process.exec()?;
@@ -237,7 +237,7 @@ pub fn create_bcx<'a, 'cfg>(
}
config.validate_term_config()?;
- let target_data = RustcTargetData::new(ws, &build_config.requested_kinds)?;
+ let mut target_data = RustcTargetData::new(ws, &build_config.requested_kinds)?;
let specs = spec.to_package_id_specs(ws)?;
let has_dev_units = {
@@ -261,14 +261,16 @@ pub fn create_bcx<'a, 'cfg>(
HasDevUnits::No
}
};
+ let max_rust_version = ws.rust_version();
let resolve = ops::resolve_ws_with_opts(
ws,
- &target_data,
+ &mut target_data,
&build_config.requested_kinds,
cli_features,
&specs,
has_dev_units,
crate::core::resolver::features::ForceAllTargets::No,
+ max_rust_version,
)?;
let WorkspaceResolve {
mut pkg_set,
@@ -279,7 +281,7 @@ pub fn create_bcx<'a, 'cfg>(
let std_resolve_features = if let Some(crates) = &config.cli_unstable().build_std {
let (std_package_set, std_resolve, std_features) =
- standard_lib::resolve_std(ws, &target_data, &build_config, crates)?;
+ standard_lib::resolve_std(ws, &mut target_data, &build_config, crates)?;
pkg_set.add_set(std_package_set);
Some((std_resolve, std_features))
} else {
@@ -316,8 +318,8 @@ pub fn create_bcx<'a, 'cfg>(
}
let (extra_args, extra_args_name) = match (target_rustc_args, target_rustdoc_args) {
- (&Some(ref args), _) => (Some(args.clone()), "rustc"),
- (_, &Some(ref args)) => (Some(args.clone()), "rustdoc"),
+ (Some(args), _) => (Some(args.clone()), "rustc"),
+ (_, Some(args)) => (Some(args.clone()), "rustdoc"),
_ => (None, ""),
};
@@ -487,12 +489,11 @@ pub fn create_bcx<'a, 'cfg>(
);
for unit in unit_graph.keys() {
- let version = match unit.pkg.rust_version() {
- Some(v) => v,
- None => continue,
+ let Some(version) = unit.pkg.rust_version() else {
+ continue;
};
- let req = semver::VersionReq::parse(version).unwrap();
+ let req = version.caret_req();
if req.matches(&untagged_version) {
continue;
}
@@ -506,7 +507,7 @@ pub fn create_bcx<'a, 'cfg>(
} else if !unit.is_local() {
format!(
"Either upgrade to rustc {} or newer, or use\n\
- cargo update -p {}@{} --precise ver\n\
+ cargo update {}@{} --precise ver\n\
where `ver` is the latest version of `{}` supporting rustc {}",
version,
unit.pkg.name(),
diff --git a/src/tools/cargo/src/cargo/ops/cargo_fetch.rs b/src/tools/cargo/src/cargo/ops/cargo_fetch.rs
index 273bce284..6acdbddef 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_fetch.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_fetch.rs
@@ -31,7 +31,7 @@ pub fn fetch<'a>(
&options.targets,
CompileMode::Build,
)?;
- let data = RustcTargetData::new(ws, &build_config.requested_kinds)?;
+ let mut data = RustcTargetData::new(ws, &build_config.requested_kinds)?;
let mut fetched_packages = HashSet::new();
let mut deps_to_fetch = ws.members().map(|p| p.package_id()).collect::<Vec<_>>();
let mut to_download = Vec::new();
@@ -70,7 +70,8 @@ pub fn fetch<'a>(
// If -Zbuild-std was passed, download dependencies for the standard library.
// We don't know ahead of time what jobs we'll be running, so tell `std_crates` that.
if let Some(crates) = standard_lib::std_crates(config, None) {
- let (std_package_set, _, _) = standard_lib::resolve_std(ws, &data, &build_config, &crates)?;
+ let (std_package_set, _, _) =
+ standard_lib::resolve_std(ws, &mut data, &build_config, &crates)?;
packages.add_set(std_package_set);
}
diff --git a/src/tools/cargo/src/cargo/ops/cargo_generate_lockfile.rs b/src/tools/cargo/src/cargo/ops/cargo_generate_lockfile.rs
index fddf83f19..a83a92ccc 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_generate_lockfile.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_generate_lockfile.rs
@@ -4,23 +4,24 @@ use crate::core::{PackageId, PackageIdSpec};
use crate::core::{Resolve, SourceId, Workspace};
use crate::ops;
use crate::util::config::Config;
+use crate::util::style;
use crate::util::CargoResult;
-use anyhow::Context;
+use anstyle::Style;
use std::collections::{BTreeMap, HashSet};
-use termcolor::Color::{self, Cyan, Green, Red, Yellow};
use tracing::debug;
pub struct UpdateOptions<'a> {
pub config: &'a Config,
pub to_update: Vec<String>,
pub precise: Option<&'a str>,
- pub aggressive: bool,
+ pub recursive: bool,
pub dry_run: bool,
pub workspace: bool,
}
pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> {
let mut registry = PackageRegistry::new(ws.config())?;
+ let max_rust_version = ws.rust_version();
let mut resolve = ops::resolve_with_previous(
&mut registry,
ws,
@@ -30,14 +31,15 @@ pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> {
None,
&[],
true,
+ max_rust_version,
)?;
ops::write_pkg_lockfile(ws, &mut resolve)?;
Ok(())
}
pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoResult<()> {
- if opts.aggressive && opts.precise.is_some() {
- anyhow::bail!("cannot specify both aggressive and precise simultaneously")
+ if opts.recursive && opts.precise.is_some() {
+ anyhow::bail!("cannot specify both recursive and precise simultaneously")
}
if ws.members().count() == 0 {
@@ -48,6 +50,8 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
// that we're synchronized against other Cargos.
let _lock = ws.config().acquire_package_cache_lock()?;
+ let max_rust_version = ws.rust_version();
+
let previous_resolve = match ops::load_pkg_lockfile(ws)? {
Some(resolve) => resolve,
None => {
@@ -67,6 +71,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
None,
&[],
true,
+ max_rust_version,
)?
}
}
@@ -83,27 +88,27 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
} else {
let mut sources = Vec::new();
for name in opts.to_update.iter() {
- let dep = previous_resolve.query(name)?;
- if opts.aggressive {
- fill_with_deps(&previous_resolve, dep, &mut to_avoid, &mut HashSet::new());
+ let pid = previous_resolve.query(name)?;
+ if opts.recursive {
+ fill_with_deps(&previous_resolve, pid, &mut to_avoid, &mut HashSet::new());
} else {
- to_avoid.insert(dep);
+ to_avoid.insert(pid);
sources.push(match opts.precise {
Some(precise) => {
// TODO: see comment in `resolve.rs` as well, but this
// seems like a pretty hokey reason to single out
// the registry as well.
- let precise = if dep.source_id().is_registry() {
- semver::Version::parse(precise).with_context(|| {
- format!("invalid version format for precise version `{}`", precise)
- })?;
- format!("{}={}->{}", dep.name(), dep.version(), precise)
+ if pid.source_id().is_registry() {
+ pid.source_id().with_precise_registry_version(
+ pid.name(),
+ pid.version(),
+ precise,
+ )?
} else {
- precise.to_string()
- };
- dep.source_id().with_precise(Some(precise))
+ pid.source_id().with_precise(Some(precise.to_string()))
+ }
}
- None => dep.source_id().with_precise(None),
+ None => pid.source_id().with_precise(None),
});
}
if let Ok(unused_id) =
@@ -125,10 +130,11 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
Some(&to_avoid),
&[],
true,
+ max_rust_version,
)?;
// Summarize what is changing for the user.
- let print_change = |status: &str, msg: String, color: Color| {
+ let print_change = |status: &str, msg: String, color: &Style| {
opts.config.shell().status_with_color(status, msg, color)
};
for (removed, added) in compare_dependency_graphs(&previous_resolve, &resolve) {
@@ -144,16 +150,16 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
};
if removed[0].version() > added[0].version() {
- print_change("Downgrading", msg, Yellow)?;
+ print_change("Downgrading", msg, &style::WARN)?;
} else {
- print_change("Updating", msg, Green)?;
+ print_change("Updating", msg, &style::GOOD)?;
}
} else {
for package in removed.iter() {
- print_change("Removing", format!("{}", package), Red)?;
+ print_change("Removing", format!("{}", package), &style::ERROR)?;
}
for package in added.iter() {
- print_change("Adding", format!("{}", package), Cyan)?;
+ print_change("Adding", format!("{}", package), &style::NOTE)?;
}
}
}
@@ -198,9 +204,8 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
.filter(|a| {
// If this package ID is not found in `b`, then it's definitely
// in the subtracted set.
- let i = match b.binary_search(a) {
- Ok(i) => i,
- Err(..) => return true,
+ let Ok(i) = b.binary_search(a) else {
+ return true;
};
// If we've found `a` in `b`, then we iterate over all instances
diff --git a/src/tools/cargo/src/cargo/ops/cargo_install.rs b/src/tools/cargo/src/cargo/ops/cargo_install.rs
index 8ddfa4fab..957ab43e6 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_install.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_install.rs
@@ -5,16 +5,17 @@ use std::{env, fs};
use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, UnitOutput};
use crate::core::{
- Dependency, Edition, Package, PackageId, PackageIdSpec, Source, SourceId, Target, Workspace,
+ Dependency, Edition, Package, PackageId, PackageIdSpec, SourceId, Target, Workspace,
};
use crate::ops::{common_for_install_and_uninstall::*, FilterRule};
use crate::ops::{CompileFilter, Packages};
+use crate::sources::source::Source;
use crate::sources::{GitSource, PathSource, SourceConfigMap};
use crate::util::errors::CargoResult;
-use crate::util::{Config, Filesystem, Rustc, ToSemver, VersionReqExt};
+use crate::util::{Config, Filesystem, Rustc};
use crate::{drop_println, ops};
-use anyhow::{bail, format_err, Context as _};
+use anyhow::{bail, Context as _};
use cargo_util::paths;
use itertools::Itertools;
use semver::VersionReq;
@@ -38,12 +39,12 @@ impl Drop for Transaction {
}
}
-struct InstallablePackage<'cfg, 'a> {
+struct InstallablePackage<'cfg> {
config: &'cfg Config,
opts: ops::CompileOptions,
root: Filesystem,
source_id: SourceId,
- vers: Option<&'a str>,
+ vers: Option<VersionReq>,
force: bool,
no_track: bool,
@@ -53,7 +54,7 @@ struct InstallablePackage<'cfg, 'a> {
target: String,
}
-impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
+impl<'cfg> InstallablePackage<'cfg> {
// Returns pkg to install. None if pkg is already installed
pub fn new(
config: &'cfg Config,
@@ -62,12 +63,12 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
krate: Option<&str>,
source_id: SourceId,
from_cwd: bool,
- vers: Option<&'a str>,
- original_opts: &'a ops::CompileOptions,
+ vers: Option<&VersionReq>,
+ original_opts: &ops::CompileOptions,
force: bool,
no_track: bool,
needs_update_if_source_is_index: bool,
- ) -> CargoResult<Option<InstallablePackage<'cfg, 'a>>> {
+ ) -> CargoResult<Option<Self>> {
if let Some(name) = krate {
if name == "." {
bail!(
@@ -82,8 +83,8 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
let pkg = {
let dep = {
if let Some(krate) = krate {
- let vers = if let Some(vers_flag) = vers {
- Some(parse_semver_flag(vers_flag)?.to_string())
+ let vers = if let Some(vers) = vers {
+ Some(vers.to_string())
} else if source_id.is_registry() {
// Avoid pre-release versions from crate.io
// unless explicitly asked for
@@ -234,7 +235,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
opts,
root,
source_id,
- vers,
+ vers: vers.cloned(),
force,
no_track,
@@ -604,7 +605,7 @@ Consider enabling some of the needed features by passing, e.g., `--features=\"{e
pub fn install(
config: &Config,
root: Option<&str>,
- krates: Vec<(&str, Option<&str>)>,
+ krates: Vec<(String, Option<VersionReq>)>,
source_id: SourceId,
from_cwd: bool,
opts: &ops::CompileOptions,
@@ -617,9 +618,9 @@ pub fn install(
let (installed_anything, scheduled_error) = if krates.len() <= 1 {
let (krate, vers) = krates
- .into_iter()
+ .iter()
.next()
- .map(|(k, v)| (Some(k), v))
+ .map(|(k, v)| (Some(k.as_str()), v.as_ref()))
.unwrap_or((None, None));
let installable_pkg = InstallablePackage::new(
config, root, map, krate, source_id, from_cwd, vers, opts, force, no_track, true,
@@ -637,7 +638,7 @@ pub fn install(
let mut did_update = false;
let pkgs_to_install: Vec<_> = krates
- .into_iter()
+ .iter()
.filter_map(|(krate, vers)| {
let root = root.clone();
let map = map.clone();
@@ -645,10 +646,10 @@ pub fn install(
config,
root,
map,
- Some(krate),
+ Some(krate.as_str()),
source_id,
from_cwd,
- vers,
+ vers.as_ref(),
opts,
force,
no_track,
@@ -660,12 +661,12 @@ pub fn install(
}
Ok(None) => {
// Already installed
- succeeded.push(krate);
+ succeeded.push(krate.as_str());
None
}
Err(e) => {
crate::display_error(&e, &mut config.shell());
- failed.push(krate);
+ failed.push(krate.as_str());
// We assume an update was performed if we got an error.
did_update = true;
None
@@ -805,54 +806,6 @@ fn make_ws_rustc_target<'cfg>(
Ok((ws, rustc, target))
}
-/// Parses x.y.z as if it were =x.y.z, and gives CLI-specific error messages in the case of invalid
-/// values.
-fn parse_semver_flag(v: &str) -> CargoResult<VersionReq> {
- // If the version begins with character <, >, =, ^, ~ parse it as a
- // version range, otherwise parse it as a specific version
- let first = v
- .chars()
- .next()
- .ok_or_else(|| format_err!("no version provided for the `--version` flag"))?;
-
- let is_req = "<>=^~".contains(first) || v.contains('*');
- if is_req {
- match v.parse::<VersionReq>() {
- Ok(v) => Ok(v),
- Err(_) => bail!(
- "the `--version` provided, `{}`, is \
- not a valid semver version requirement\n\n\
- Please have a look at \
- https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html \
- for the correct format",
- v
- ),
- }
- } else {
- match v.to_semver() {
- Ok(v) => Ok(VersionReq::exact(&v)),
- Err(e) => {
- let mut msg = format!(
- "the `--version` provided, `{}`, is \
- not a valid semver version: {}\n",
- v, e
- );
-
- // If it is not a valid version but it is a valid version
- // requirement, add a note to the warning
- if v.parse::<VersionReq>().is_ok() {
- msg.push_str(&format!(
- "\nif you want to specify semver range, \
- add an explicit qualifier, like ^{}",
- v
- ));
- }
- bail!(msg);
- }
- }
- }
-}
-
/// Display a list of installed binaries.
pub fn install_list(dst: Option<&str>, config: &Config) -> CargoResult<()> {
let root = resolve_root(dst, config)?;
diff --git a/src/tools/cargo/src/cargo/ops/cargo_new.rs b/src/tools/cargo/src/cargo/ops/cargo_new.rs
index 0809cefc3..78b3cc4f6 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_new.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_new.rs
@@ -93,7 +93,6 @@ struct MkOptions<'a> {
path: &'a Path,
name: &'a str,
source_files: Vec<SourceFileInformation>,
- bin: bool,
edition: Option<&'a str>,
registry: Option<&'a str>,
}
@@ -448,7 +447,6 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
path,
name,
source_files: vec![plan_new_source_file(opts.kind.is_bin(), name.to_string())],
- bin: is_bin,
edition: opts.edition.as_deref(),
registry: opts.registry.as_deref(),
};
@@ -553,7 +551,6 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<NewProjectKind> {
version_control,
path,
name,
- bin: has_bin,
source_files: src_paths_types,
edition: opts.edition.as_deref(),
registry: opts.registry.as_deref(),
@@ -745,9 +742,6 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
// for all mutually-incompatible VCS in terms of syntax are in sync.
let mut ignore = IgnoreList::new();
ignore.push("/target", "^target$", "target");
- if !opts.bin {
- ignore.push("/Cargo.lock", "^Cargo.lock$", "Cargo.lock");
- }
let vcs = opts.version_control.unwrap_or_else(|| {
let in_existing_vcs = existing_vcs_repo(path.parent().unwrap_or(path), config.cwd());
@@ -823,11 +817,10 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
}
// Try to inherit the workspace lints key if it exists.
- if config.cli_unstable().lints
- && workspace_document
- .get("workspace")
- .and_then(|workspace| workspace.get("lints"))
- .is_some()
+ if workspace_document
+ .get("workspace")
+ .and_then(|workspace| workspace.get("lints"))
+ .is_some()
{
let mut table = toml_edit::Table::new();
table["workspace"] = toml_edit::value(true);
diff --git a/src/tools/cargo/src/cargo/ops/cargo_output_metadata.rs b/src/tools/cargo/src/cargo/ops/cargo_output_metadata.rs
index c0a63aa75..83dae50ea 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_output_metadata.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_output_metadata.rs
@@ -126,7 +126,7 @@ fn build_resolve_graph(
// How should this work?
let requested_kinds =
CompileKind::from_requested_targets(ws.config(), &metadata_opts.filter_platforms)?;
- let target_data = RustcTargetData::new(ws, &requested_kinds)?;
+ let mut target_data = RustcTargetData::new(ws, &requested_kinds)?;
// Resolve entire workspace.
let specs = Packages::All.to_package_id_specs(ws)?;
let force_all = if metadata_opts.filter_platforms.is_empty() {
@@ -135,16 +135,19 @@ fn build_resolve_graph(
crate::core::resolver::features::ForceAllTargets::No
};
+ let max_rust_version = ws.rust_version();
+
// Note that even with --filter-platform we end up downloading host dependencies as well,
// as that is the behavior of download_accessible.
let ws_resolve = ops::resolve_ws_with_opts(
ws,
- &target_data,
+ &mut target_data,
&requested_kinds,
&metadata_opts.cli_features,
&specs,
HasDevUnits::Yes,
force_all,
+ max_rust_version,
)?;
let package_map: BTreeMap<PackageId, Package> = ws_resolve
@@ -313,7 +316,7 @@ fn build_resolve_graph_r(
dep_kinds,
},
// No lib or artifact dep exists.
- // Ususally this mean parent depending on non-lib bin crate.
+ // Usually this mean parent depending on non-lib bin crate.
(None, _) => continue,
};
diff --git a/src/tools/cargo/src/cargo/ops/cargo_package.rs b/src/tools/cargo/src/cargo/ops/cargo_package.rs
index 93469607b..b6423aa96 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_package.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_package.rs
@@ -237,7 +237,7 @@ fn build_ar_list(
let rel_str = rel_path.to_str().ok_or_else(|| {
anyhow::format_err!("non-utf8 path in source directory: {}", rel_path.display())
})?;
- match rel_str.as_ref() {
+ match rel_str {
"Cargo.lock" => continue,
VCS_INFO_FILE | ORIGINAL_MANIFEST_FILE => anyhow::bail!(
"invalid inclusion of reserved file name {} in package source",
@@ -423,6 +423,8 @@ fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult<String> {
TomlManifest::to_real_manifest(&toml_manifest, false, source_id, package_root, config)?;
let new_pkg = Package::new(manifest, orig_pkg.manifest_path());
+ let max_rust_version = new_pkg.rust_version().cloned();
+
// Regenerate Cargo.lock using the old one as a guide.
let tmp_ws = Workspace::ephemeral(new_pkg, ws.config(), None, true)?;
let mut tmp_reg = PackageRegistry::new(ws.config())?;
@@ -435,6 +437,7 @@ fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult<String> {
None,
&[],
true,
+ max_rust_version.as_ref(),
)?;
let pkg_set = ops::get_resolved_packages(&new_resolve, tmp_reg)?;
@@ -991,17 +994,15 @@ fn report_hash_difference(orig: &HashMap<PathBuf, u64>, after: &HashMap<PathBuf,
// To help out in situations like this, issue about weird filenames when
// packaging as a "heads up" that something may not work on other platforms.
fn check_filename(file: &Path, shell: &mut Shell) -> CargoResult<()> {
- let name = match file.file_name() {
- Some(name) => name,
- None => return Ok(()),
+ let Some(name) = file.file_name() else {
+ return Ok(());
};
- let name = match name.to_str() {
- Some(name) => name,
- None => anyhow::bail!(
+ let Some(name) = name.to_str() else {
+ anyhow::bail!(
"path does not have a unicode filename which may not unpack \
on all platforms: {}",
file.display()
- ),
+ )
};
let bad_chars = ['/', '\\', '<', '>', ':', '"', '|', '?', '*'];
if let Some(c) = bad_chars.iter().find(|c| name.contains(**c)) {
diff --git a/src/tools/cargo/src/cargo/ops/cargo_pkgid.rs b/src/tools/cargo/src/cargo/ops/cargo_pkgid.rs
index eeed6ac02..bbae154a7 100644
--- a/src/tools/cargo/src/cargo/ops/cargo_pkgid.rs
+++ b/src/tools/cargo/src/cargo/ops/cargo_pkgid.rs
@@ -3,9 +3,8 @@ use crate::ops;
use crate::util::CargoResult;
pub fn pkgid(ws: &Workspace<'_>, spec: Option<&str>) -> CargoResult<PackageIdSpec> {
- let resolve = match ops::load_pkg_lockfile(ws)? {
- Some(resolve) => resolve,
- None => anyhow::bail!("a Cargo.lock must exist for this command"),
+ let Some(resolve) = ops::load_pkg_lockfile(ws)? else {
+ anyhow::bail!("a Cargo.lock must exist for this command")
};
let pkgid = match spec {
diff --git a/src/tools/cargo/src/cargo/ops/common_for_install_and_uninstall.rs b/src/tools/cargo/src/cargo/ops/common_for_install_and_uninstall.rs
index f33847d57..0934cbd29 100644
--- a/src/tools/cargo/src/cargo/ops/common_for_install_and_uninstall.rs
+++ b/src/tools/cargo/src/cargo/ops/common_for_install_and_uninstall.rs
@@ -12,8 +12,10 @@ use serde::{Deserialize, Serialize};
use crate::core::compiler::{DirtyReason, Freshness};
use crate::core::Target;
-use crate::core::{Dependency, FeatureValue, Package, PackageId, QueryKind, Source, SourceId};
+use crate::core::{Dependency, FeatureValue, Package, PackageId, SourceId};
use crate::ops::{self, CompileFilter, CompileOptions};
+use crate::sources::source::QueryKind;
+use crate::sources::source::Source;
use crate::sources::PathSource;
use crate::util::errors::CargoResult;
use crate::util::Config;
diff --git a/src/tools/cargo/src/cargo/ops/fix.rs b/src/tools/cargo/src/cargo/ops/fix.rs
index 0e678d61c..9d6459294 100644
--- a/src/tools/cargo/src/cargo/ops/fix.rs
+++ b/src/tools/cargo/src/cargo/ops/fix.rs
@@ -243,22 +243,26 @@ fn check_resolver_change(ws: &Workspace<'_>, opts: &FixOptions) -> CargoResult<(
// 2018 without `resolver` set must be V1
assert_eq!(ws.resolve_behavior(), ResolveBehavior::V1);
let specs = opts.compile_opts.spec.to_package_id_specs(ws)?;
- let target_data = RustcTargetData::new(ws, &opts.compile_opts.build_config.requested_kinds)?;
- let resolve_differences = |has_dev_units| -> CargoResult<(WorkspaceResolve<'_>, DiffMap)> {
+ let mut target_data =
+ RustcTargetData::new(ws, &opts.compile_opts.build_config.requested_kinds)?;
+ let mut resolve_differences = |has_dev_units| -> CargoResult<(WorkspaceResolve<'_>, DiffMap)> {
+ let max_rust_version = ws.rust_version();
+
let ws_resolve = ops::resolve_ws_with_opts(
ws,
- &target_data,
+ &mut target_data,
&opts.compile_opts.build_config.requested_kinds,
&opts.compile_opts.cli_features,
&specs,
has_dev_units,
crate::core::resolver::features::ForceAllTargets::No,
+ max_rust_version,
)?;
let feature_opts = FeatureOpts::new_behavior(ResolveBehavior::V2, has_dev_units);
let v2_features = FeatureResolver::resolve(
ws,
- &target_data,
+ &mut target_data,
&ws_resolve.targeted_resolve,
&ws_resolve.pkg_set,
&opts.compile_opts.cli_features,
@@ -916,15 +920,12 @@ impl FixArgs {
/// Validates the edition, and sends a message indicating what is being
/// done. Returns a flag indicating whether this fix should be run.
fn can_run_rustfix(&self, config: &Config) -> CargoResult<bool> {
- let to_edition = match self.prepare_for_edition {
- Some(s) => s,
- None => {
- return Message::Fixing {
- file: self.file.display().to_string(),
- }
- .post(config)
- .and(Ok(true));
+ let Some(to_edition) = self.prepare_for_edition else {
+ return Message::Fixing {
+ file: self.file.display().to_string(),
}
+ .post(config)
+ .and(Ok(true));
};
// Unfortunately determining which cargo targets are being built
// isn't easy, and each target can be a different edition. The
diff --git a/src/tools/cargo/src/cargo/ops/lockfile.rs b/src/tools/cargo/src/cargo/ops/lockfile.rs
index b27a7e742..26456e560 100644
--- a/src/tools/cargo/src/cargo/ops/lockfile.rs
+++ b/src/tools/cargo/src/cargo/ops/lockfile.rs
@@ -2,7 +2,6 @@ use std::io::prelude::*;
use crate::core::{resolver, Resolve, ResolveVersion, Workspace};
use crate::util::errors::CargoResult;
-use crate::util::toml as cargo_toml;
use crate::util::Filesystem;
use anyhow::Context as _;
@@ -20,8 +19,7 @@ pub fn load_pkg_lockfile(ws: &Workspace<'_>) -> CargoResult<Option<Resolve>> {
.with_context(|| format!("failed to read file: {}", f.path().display()))?;
let resolve = (|| -> CargoResult<Option<Resolve>> {
- let resolve: toml::Table = cargo_toml::parse_document(&s, f.path(), ws.config())?;
- let v: resolver::EncodableResolve = resolve.try_into()?;
+ let v: resolver::EncodableResolve = toml::from_str(&s)?;
Ok(Some(v.into_resolve(&s, ws)?))
})()
.with_context(|| format!("failed to parse lock file at: {}", f.path().display()))?;
diff --git a/src/tools/cargo/src/cargo/ops/mod.rs b/src/tools/cargo/src/cargo/ops/mod.rs
index d4ec442dd..13613eaf6 100644
--- a/src/tools/cargo/src/cargo/ops/mod.rs
+++ b/src/tools/cargo/src/cargo/ops/mod.rs
@@ -30,6 +30,7 @@ pub use self::registry::yank;
pub use self::registry::OwnersOptions;
pub use self::registry::PublishOpts;
pub use self::registry::RegistryCredentialConfig;
+pub use self::registry::RegistryOrIndex;
pub use self::resolve::{
add_overrides, get_resolved_packages, resolve_with_previous, resolve_ws, resolve_ws_with_opts,
WorkspaceResolve,
diff --git a/src/tools/cargo/src/cargo/ops/registry/login.rs b/src/tools/cargo/src/cargo/ops/registry/login.rs
index e52373734..e21dfe023 100644
--- a/src/tools/cargo/src/cargo/ops/registry/login.rs
+++ b/src/tools/cargo/src/cargo/ops/registry/login.rs
@@ -16,16 +16,23 @@ use cargo_credential::Secret;
use super::get_source_id;
use super::registry;
+use super::RegistryOrIndex;
pub fn registry_login(
config: &Config,
token_from_cmdline: Option<Secret<&str>>,
- reg: Option<&str>,
+ reg_or_index: Option<&RegistryOrIndex>,
args: &[&str],
) -> CargoResult<()> {
- let source_ids = get_source_id(config, None, reg)?;
-
- let login_url = match registry(config, token_from_cmdline.clone(), None, reg, false, None) {
+ let source_ids = get_source_id(config, reg_or_index)?;
+
+ let login_url = match registry(
+ config,
+ token_from_cmdline.clone(),
+ reg_or_index,
+ false,
+ None,
+ ) {
Ok((registry, _)) => Some(format!("{}/me", registry.host())),
Err(e) if e.is::<AuthorizationError>() => e
.downcast::<AuthorizationError>()
diff --git a/src/tools/cargo/src/cargo/ops/registry/logout.rs b/src/tools/cargo/src/cargo/ops/registry/logout.rs
index d1f080bae..fa0cbc539 100644
--- a/src/tools/cargo/src/cargo/ops/registry/logout.rs
+++ b/src/tools/cargo/src/cargo/ops/registry/logout.rs
@@ -8,9 +8,10 @@ use crate::CargoResult;
use crate::Config;
use super::get_source_id;
+use super::RegistryOrIndex;
-pub fn registry_logout(config: &Config, reg: Option<&str>) -> CargoResult<()> {
- let source_ids = get_source_id(config, None, reg)?;
+pub fn registry_logout(config: &Config, reg_or_index: Option<RegistryOrIndex>) -> CargoResult<()> {
+ let source_ids = get_source_id(config, reg_or_index.as_ref())?;
auth::logout(config, &source_ids.original)?;
Ok(())
}
diff --git a/src/tools/cargo/src/cargo/ops/registry/mod.rs b/src/tools/cargo/src/cargo/ops/registry/mod.rs
index 94ef1ead2..c82230a16 100644
--- a/src/tools/cargo/src/cargo/ops/registry/mod.rs
+++ b/src/tools/cargo/src/cargo/ops/registry/mod.rs
@@ -16,15 +16,15 @@ use std::task::Poll;
use anyhow::{bail, format_err, Context as _};
use cargo_credential::{Operation, Secret};
use crates_io::{self, Registry};
+use url::Url;
-use crate::core::source::Source;
use crate::core::SourceId;
+use crate::sources::source::Source;
use crate::sources::{RegistrySource, SourceConfigMap};
use crate::util::auth;
use crate::util::config::{Config, PathAndArgs};
use crate::util::errors::CargoResult;
use crate::util::network::http::http_handle;
-use crate::util::IntoUrl;
pub use self::login::registry_login;
pub use self::logout::registry_logout;
@@ -35,6 +35,19 @@ pub use self::publish::PublishOpts;
pub use self::search::search;
pub use self::yank::yank;
+/// Represents either `--registry` or `--index` argument, which is mutually exclusive.
+#[derive(Debug, Clone)]
+pub enum RegistryOrIndex {
+ Registry(String),
+ Index(Url),
+}
+
+impl RegistryOrIndex {
+ fn is_index(&self) -> bool {
+ matches!(self, RegistryOrIndex::Index(..))
+ }
+}
+
/// Registry settings loaded from config files.
///
/// This is loaded based on the `--registry` flag and the config settings.
@@ -103,14 +116,14 @@ impl RegistryCredentialConfig {
fn registry(
config: &Config,
token_from_cmdline: Option<Secret<&str>>,
- index: Option<&str>,
- registry: Option<&str>,
+ reg_or_index: Option<&RegistryOrIndex>,
force_update: bool,
token_required: Option<Operation<'_>>,
) -> CargoResult<(Registry, RegistrySourceIds)> {
- let source_ids = get_source_id(config, index, registry)?;
+ let source_ids = get_source_id(config, reg_or_index)?;
- if token_required.is_some() && index.is_some() && token_from_cmdline.is_none() {
+ let is_index = reg_or_index.map(|v| v.is_index()).unwrap_or_default();
+ if is_index && token_required.is_some() && token_from_cmdline.is_none() {
bail!("command-line argument --index requires --token to be specified");
}
if let Some(token) = token_from_cmdline {
@@ -145,6 +158,7 @@ fn registry(
None,
operation,
vec![],
+ false,
)?)
} else {
None
@@ -171,13 +185,12 @@ fn registry(
/// crates.io (such as index.crates.io), while the second is always the original source.
fn get_source_id(
config: &Config,
- index: Option<&str>,
- reg: Option<&str>,
+ reg_or_index: Option<&RegistryOrIndex>,
) -> CargoResult<RegistrySourceIds> {
- let sid = match (reg, index) {
- (None, None) => SourceId::crates_io(config)?,
- (_, Some(i)) => SourceId::for_registry(&i.into_url()?)?,
- (Some(r), None) => SourceId::alt_registry(config, r)?,
+ let sid = match reg_or_index {
+ None => SourceId::crates_io(config)?,
+ Some(RegistryOrIndex::Index(url)) => SourceId::for_registry(url)?,
+ Some(RegistryOrIndex::Registry(r)) => SourceId::alt_registry(config, r)?,
};
// Load source replacements that are built-in to Cargo.
let builtin_replacement_sid = SourceConfigMap::empty(config)?
@@ -186,7 +199,7 @@ fn get_source_id(
let replacement_sid = SourceConfigMap::new(config)?
.load(sid, &HashSet::new())?
.replaced_source_id();
- if reg.is_none() && index.is_none() && replacement_sid != builtin_replacement_sid {
+ if reg_or_index.is_none() && replacement_sid != builtin_replacement_sid {
// Neither --registry nor --index was passed and the user has configured source-replacement.
if let Some(replacement_name) = replacement_sid.alt_registry_key() {
bail!("crates-io is replaced with remote registry {replacement_name};\ninclude `--registry {replacement_name}` or `--registry crates-io`");
diff --git a/src/tools/cargo/src/cargo/ops/registry/owner.rs b/src/tools/cargo/src/cargo/ops/registry/owner.rs
index e29c6400b..3f49bb5bb 100644
--- a/src/tools/cargo/src/cargo/ops/registry/owner.rs
+++ b/src/tools/cargo/src/cargo/ops/registry/owner.rs
@@ -13,14 +13,15 @@ use crate::util::important_paths::find_root_manifest_for_wd;
use crate::CargoResult;
use crate::Config;
+use super::RegistryOrIndex;
+
pub struct OwnersOptions {
pub krate: Option<String>,
pub token: Option<Secret<String>>,
- pub index: Option<String>,
+ pub reg_or_index: Option<RegistryOrIndex>,
pub to_add: Option<Vec<String>>,
pub to_remove: Option<Vec<String>>,
pub list: bool,
- pub registry: Option<String>,
}
pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
@@ -38,8 +39,7 @@ pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> {
let (mut registry, _) = super::registry(
config,
opts.token.as_ref().map(Secret::as_deref),
- opts.index.as_deref(),
- opts.registry.as_deref(),
+ opts.reg_or_index.as_ref(),
true,
Some(operation),
)?;
diff --git a/src/tools/cargo/src/cargo/ops/registry/publish.rs b/src/tools/cargo/src/cargo/ops/registry/publish.rs
index 40ca9fd16..a88a0a30f 100644
--- a/src/tools/cargo/src/cargo/ops/registry/publish.rs
+++ b/src/tools/cargo/src/cargo/ops/registry/publish.rs
@@ -21,12 +21,12 @@ use crate::core::manifest::ManifestMetadata;
use crate::core::resolver::CliFeatures;
use crate::core::Dependency;
use crate::core::Package;
-use crate::core::QueryKind;
use crate::core::SourceId;
use crate::core::Workspace;
use crate::ops;
use crate::ops::PackageOpts;
use crate::ops::Packages;
+use crate::sources::source::QueryKind;
use crate::sources::SourceConfigMap;
use crate::sources::CRATES_IO_REGISTRY;
use crate::util::auth;
@@ -37,11 +37,12 @@ use crate::CargoResult;
use crate::Config;
use super::super::check_dep_has_version;
+use super::RegistryOrIndex;
pub struct PublishOpts<'cfg> {
pub config: &'cfg Config,
pub token: Option<Secret<String>>,
- pub index: Option<String>,
+ pub reg_or_index: Option<RegistryOrIndex>,
pub verify: bool,
pub allow_dirty: bool,
pub jobs: Option<JobsConfig>,
@@ -49,7 +50,6 @@ pub struct PublishOpts<'cfg> {
pub to_publish: ops::Packages,
pub targets: Vec<String>,
pub dry_run: bool,
- pub registry: Option<String>,
pub cli_features: CliFeatures,
}
@@ -76,7 +76,10 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
let (pkg, cli_features) = pkgs.pop().unwrap();
- let mut publish_registry = opts.registry.clone();
+ let mut publish_registry = match opts.reg_or_index.as_ref() {
+ Some(RegistryOrIndex::Registry(registry)) => Some(registry.clone()),
+ _ => None,
+ };
if let Some(ref allowed_registries) = *pkg.publish() {
if publish_registry.is_none() && allowed_registries.len() == 1 {
// If there is only one allowed registry, push to that one directly,
@@ -116,11 +119,16 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
let ver = pkg.version().to_string();
let operation = Operation::Read;
+ let reg_or_index = match opts.reg_or_index.clone() {
+ Some(RegistryOrIndex::Registry(_)) | None => {
+ publish_registry.map(RegistryOrIndex::Registry)
+ }
+ val => val,
+ };
let (mut registry, reg_ids) = super::registry(
opts.config,
opts.token.as_ref().map(Secret::as_deref),
- opts.index.as_deref(),
- publish_registry.as_deref(),
+ reg_or_index.as_ref(),
true,
Some(operation).filter(|_| !opts.dry_run),
)?;
@@ -161,6 +169,7 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
None,
operation,
vec![],
+ false,
)?));
}
@@ -353,6 +362,17 @@ fn transmit(
.to_string(),
registry: dep_registry,
explicit_name_in_toml: dep.explicit_name_in_toml().map(|s| s.to_string()),
+ artifact: dep.artifact().map(|artifact| {
+ artifact
+ .kinds()
+ .iter()
+ .map(|x| x.as_str().into_owned())
+ .collect()
+ }),
+ bindep_target: dep.artifact().and_then(|artifact| {
+ artifact.target().map(|target| target.as_str().to_owned())
+ }),
+ lib: dep.artifact().map_or(false, |artifact| artifact.is_lib()),
})
})
.collect::<CargoResult<Vec<NewCrateDependency>>>()?;
@@ -372,6 +392,7 @@ fn transmit(
ref links,
ref rust_version,
} = *manifest.metadata();
+ let rust_version = rust_version.as_ref().map(ToString::to_string);
let readme_content = readme
.as_ref()
.map(|readme| {
@@ -424,7 +445,7 @@ fn transmit(
license_file: license_file.clone(),
badges: badges.clone(),
links: links.clone(),
- rust_version: rust_version.clone(),
+ rust_version,
},
tarball,
)
diff --git a/src/tools/cargo/src/cargo/ops/registry/search.rs b/src/tools/cargo/src/cargo/ops/registry/search.rs
index 5e01ea98f..10b4d600e 100644
--- a/src/tools/cargo/src/cargo/ops/registry/search.rs
+++ b/src/tools/cargo/src/cargo/ops/registry/search.rs
@@ -6,23 +6,23 @@ use std::cmp;
use std::iter::repeat;
use anyhow::Context as _;
-use termcolor::Color;
-use termcolor::ColorSpec;
use url::Url;
+use crate::util::style;
use crate::util::truncate_with_ellipsis;
use crate::CargoResult;
use crate::Config;
+use super::RegistryOrIndex;
+
pub fn search(
query: &str,
config: &Config,
- index: Option<String>,
+ reg_or_index: Option<RegistryOrIndex>,
limit: u32,
- reg: Option<String>,
) -> CargoResult<()> {
let (mut registry, source_ids) =
- super::registry(config, None, index.as_deref(), reg.as_deref(), false, None)?;
+ super::registry(config, None, reg_or_index.as_ref(), false, None)?;
let (crates, total_crates) = registry.search(query, limit).with_context(|| {
format!(
"failed to retrieve search results from the registry at {}",
@@ -58,15 +58,12 @@ pub fn search(
};
let mut fragments = line.split(query).peekable();
while let Some(fragment) = fragments.next() {
- let _ = config.shell().write_stdout(fragment, &ColorSpec::new());
+ let _ = config.shell().write_stdout(fragment, &style::NOP);
if fragments.peek().is_some() {
- let _ = config.shell().write_stdout(
- query,
- &ColorSpec::new().set_bold(true).set_fg(Some(Color::Green)),
- );
+ let _ = config.shell().write_stdout(query, &style::GOOD);
}
}
- let _ = config.shell().write_stdout("\n", &ColorSpec::new());
+ let _ = config.shell().write_stdout("\n", &style::NOP);
}
let search_max_limit = 100;
@@ -76,7 +73,7 @@ pub fn search(
"... and {} crates more (use --limit N to see more)\n",
total_crates - limit
),
- &ColorSpec::new(),
+ &style::NOP,
);
} else if total_crates > limit && limit >= search_max_limit {
let extra = if source_ids.original.is_crates_io() {
@@ -87,7 +84,7 @@ pub fn search(
};
let _ = config.shell().write_stdout(
format_args!("... and {} crates more{}\n", total_crates - limit, extra),
- &ColorSpec::new(),
+ &style::NOP,
);
}
diff --git a/src/tools/cargo/src/cargo/ops/registry/yank.rs b/src/tools/cargo/src/cargo/ops/registry/yank.rs
index 8a961b990..2a258ea81 100644
--- a/src/tools/cargo/src/cargo/ops/registry/yank.rs
+++ b/src/tools/cargo/src/cargo/ops/registry/yank.rs
@@ -13,14 +13,15 @@ use crate::util::config::Config;
use crate::util::errors::CargoResult;
use crate::util::important_paths::find_root_manifest_for_wd;
+use super::RegistryOrIndex;
+
pub fn yank(
config: &Config,
krate: Option<String>,
version: Option<String>,
token: Option<Secret<String>>,
- index: Option<String>,
+ reg_or_index: Option<RegistryOrIndex>,
undo: bool,
- reg: Option<String>,
) -> CargoResult<()> {
let name = match krate {
Some(name) => name,
@@ -30,9 +31,8 @@ pub fn yank(
ws.current()?.package_id().name().to_string()
}
};
- let version = match version {
- Some(v) => v,
- None => bail!("a version must be specified to yank"),
+ let Some(version) = version else {
+ bail!("a version must be specified to yank")
};
let message = if undo {
@@ -50,8 +50,7 @@ pub fn yank(
let (mut registry, _) = super::registry(
config,
token.as_ref().map(Secret::as_deref),
- index.as_deref(),
- reg.as_deref(),
+ reg_or_index.as_ref(),
true,
Some(message),
)?;
diff --git a/src/tools/cargo/src/cargo/ops/resolve.rs b/src/tools/cargo/src/cargo/ops/resolve.rs
index 6246311a5..053098d55 100644
--- a/src/tools/cargo/src/cargo/ops/resolve.rs
+++ b/src/tools/cargo/src/cargo/ops/resolve.rs
@@ -49,8 +49,8 @@
//! [`Package`]: crate::core::package
//! [`Target`]: crate::core::Target
//! [`Manifest`]: crate::core::Manifest
-//! [`Source`]: crate::core::Source
-//! [`SourceMap`]: crate::core::SourceMap
+//! [`Source`]: crate::sources::source::Source
+//! [`SourceMap`]: crate::sources::source::SourceMap
//! [`PackageRegistry`]: crate::core::registry::PackageRegistry
//! [source implementations]: crate::sources
//! [`Downloads`]: crate::core::package::Downloads
@@ -69,6 +69,7 @@ use crate::core::{GitReference, PackageId, PackageIdSpec, PackageSet, SourceId,
use crate::ops;
use crate::sources::PathSource;
use crate::util::errors::CargoResult;
+use crate::util::RustVersion;
use crate::util::{profile, CanonicalUrl};
use anyhow::Context as _;
use std::collections::{HashMap, HashSet};
@@ -106,8 +107,10 @@ version. This may also occur with an optional dependency that is not enabled.";
/// This is a simple interface used by commands like `clean`, `fetch`, and
/// `package`, which don't specify any options or features.
pub fn resolve_ws<'a>(ws: &Workspace<'a>) -> CargoResult<(PackageSet<'a>, Resolve)> {
+ let max_rust_version = ws.rust_version();
+
let mut registry = PackageRegistry::new(ws.config())?;
- let resolve = resolve_with_registry(ws, &mut registry)?;
+ let resolve = resolve_with_registry(ws, &mut registry, max_rust_version)?;
let packages = get_resolved_packages(&resolve, registry)?;
Ok((packages, resolve))
}
@@ -124,12 +127,13 @@ pub fn resolve_ws<'a>(ws: &Workspace<'a>) -> CargoResult<(PackageSet<'a>, Resolv
/// members. In this case, `opts.all_features` must be `true`.
pub fn resolve_ws_with_opts<'cfg>(
ws: &Workspace<'cfg>,
- target_data: &RustcTargetData<'cfg>,
+ target_data: &mut RustcTargetData<'cfg>,
requested_targets: &[CompileKind],
cli_features: &CliFeatures,
specs: &[PackageIdSpec],
has_dev_units: HasDevUnits,
force_all_targets: ForceAllTargets,
+ max_rust_version: Option<&RustVersion>,
) -> CargoResult<WorkspaceResolve<'cfg>> {
let mut registry = PackageRegistry::new(ws.config())?;
let mut add_patches = true;
@@ -138,7 +142,7 @@ pub fn resolve_ws_with_opts<'cfg>(
} else if ws.require_optional_deps() {
// First, resolve the root_package's *listed* dependencies, as well as
// downloading and updating all remotes and such.
- let resolve = resolve_with_registry(ws, &mut registry)?;
+ let resolve = resolve_with_registry(ws, &mut registry, max_rust_version)?;
// No need to add patches again, `resolve_with_registry` has done it.
add_patches = false;
@@ -149,7 +153,7 @@ pub fn resolve_ws_with_opts<'cfg>(
add_overrides(&mut registry, ws)?;
- for &(ref replace_spec, ref dep) in ws.root_replace() {
+ for (replace_spec, dep) in ws.root_replace() {
if !resolve
.iter()
.any(|r| replace_spec.matches(r) && !dep.matches_id(r))
@@ -184,6 +188,7 @@ pub fn resolve_ws_with_opts<'cfg>(
None,
specs,
add_patches,
+ max_rust_version,
)?;
let pkg_set = get_resolved_packages(&resolved_with_overrides, registry)?;
@@ -235,6 +240,7 @@ pub fn resolve_ws_with_opts<'cfg>(
fn resolve_with_registry<'cfg>(
ws: &Workspace<'cfg>,
registry: &mut PackageRegistry<'cfg>,
+ max_rust_version: Option<&RustVersion>,
) -> CargoResult<Resolve> {
let prev = ops::load_pkg_lockfile(ws)?;
let mut resolve = resolve_with_previous(
@@ -246,6 +252,7 @@ fn resolve_with_registry<'cfg>(
None,
&[],
true,
+ max_rust_version,
)?;
if !ws.is_ephemeral() && ws.require_optional_deps() {
@@ -278,6 +285,7 @@ pub fn resolve_with_previous<'cfg>(
to_avoid: Option<&HashSet<PackageId>>,
specs: &[PackageIdSpec],
register_patches: bool,
+ max_rust_version: Option<&RustVersion>,
) -> CargoResult<Resolve> {
// We only want one Cargo at a time resolving a crate graph since this can
// involve a lot of frobbing of the global caches.
@@ -321,15 +329,12 @@ pub fn resolve_with_previous<'cfg>(
for patch in patches {
version_prefs.prefer_dependency(patch.clone());
}
- let previous = match previous {
- Some(r) => r,
- None => {
- let patches: Vec<_> = patches.iter().map(|p| (p, None)).collect();
- let unlock_ids = registry.patch(url, &patches)?;
- // Since nothing is locked, this shouldn't possibly return anything.
- assert!(unlock_ids.is_empty());
- continue;
- }
+ let Some(previous) = previous else {
+ let patches: Vec<_> = patches.iter().map(|p| (p, None)).collect();
+ let unlock_ids = registry.patch(url, &patches)?;
+ // Since nothing is locked, this shouldn't possibly return anything.
+ assert!(unlock_ids.is_empty());
+ continue;
};
// This is a list of pairs where the first element of the pair is
@@ -481,7 +486,7 @@ pub fn resolve_with_previous<'cfg>(
let replace = match previous {
Some(r) => root_replace
.iter()
- .map(|&(ref spec, ref dep)| {
+ .map(|(spec, dep)| {
for (&key, &val) in r.replacements().iter() {
if spec.matches(key) && dep.matches_id(val) && keep(&val) {
let mut dep = dep.clone();
@@ -505,6 +510,7 @@ pub fn resolve_with_previous<'cfg>(
ws.unstable_features()
.require(Feature::public_dependency())
.is_ok(),
+ max_rust_version,
)?;
let patches: Vec<_> = registry
.patches()
@@ -530,9 +536,8 @@ pub fn add_overrides<'a>(
ws: &Workspace<'a>,
) -> CargoResult<()> {
let config = ws.config();
- let paths = match config.get_list("paths")? {
- Some(list) => list,
- None => return Ok(()),
+ let Some(paths) = config.get_list("paths")? else {
+ return Ok(());
};
let paths = paths.val.iter().map(|(s, def)| {
@@ -603,7 +608,7 @@ fn register_previous_locks(
// Ok so we've been passed in a `keep` function which basically says "if I
// return `true` then this package wasn't listed for an update on the command
- // line". That is, if we run `cargo update -p foo` then `keep(bar)` will return
+ // line". That is, if we run `cargo update foo` then `keep(bar)` will return
// `true`, whereas `keep(foo)` will return `false` (roughly speaking).
//
// This isn't actually quite what we want, however. Instead we want to
@@ -613,7 +618,7 @@ fn register_previous_locks(
// * There's a crate `log`.
// * There's a crate `serde` which depends on `log`.
//
- // Let's say we then run `cargo update -p serde`. This may *also* want to
+ // Let's say we then run `cargo update serde`. This may *also* want to
// update the `log` dependency as our newer version of `serde` may have a
// new minimum version required for `log`. Now this isn't always guaranteed
// to work. What'll happen here is we *won't* lock the `log` dependency nor
@@ -623,23 +628,11 @@ fn register_previous_locks(
// however, nothing else in the dependency graph depends on `log` and the
// newer version of `serde` requires a new version of `log` it'll get pulled
// in (as we didn't accidentally lock it to an old version).
- //
- // Additionally, here we process all path dependencies listed in the previous
- // resolve. They can not only have their dependencies change but also
- // the versions of the package change as well. If this ends up happening
- // then we want to make sure we don't lock a package ID node that doesn't
- // actually exist. Note that we don't do transitive visits of all the
- // package's dependencies here as that'll be covered below to poison those
- // if they changed.
let mut avoid_locking = HashSet::new();
registry.add_to_yanked_whitelist(resolve.iter().filter(keep));
for node in resolve.iter() {
if !keep(&node) {
add_deps(resolve, node, &mut avoid_locking);
- } else if let Some(pkg) = path_pkg(node.source_id()) {
- if pkg.package_id() != node {
- avoid_locking.insert(node);
- }
}
}
@@ -732,6 +725,24 @@ fn register_previous_locks(
}
}
+ // Additionally, here we process all path dependencies listed in the previous
+ // resolve. They can not only have their dependencies change but also
+ // the versions of the package change as well. If this ends up happening
+ // then we want to make sure we don't lock a package ID node that doesn't
+ // actually exist. Note that we don't do transitive visits of all the
+ // package's dependencies here as that'll be covered below to poison those
+ // if they changed.
+ //
+ // This must come after all other `add_deps` calls to ensure it recursively walks the tree when
+ // called.
+ for node in resolve.iter() {
+ if let Some(pkg) = path_pkg(node.source_id()) {
+ if pkg.package_id() != node {
+ avoid_locking.insert(node);
+ }
+ }
+ }
+
// Alright now that we've got our new, fresh, shiny, and refined `keep`
// function let's put it to action. Take a look at the previous lock file,
// filter everything by this callback, and then shove everything else into
diff --git a/src/tools/cargo/src/cargo/ops/tree/graph.rs b/src/tools/cargo/src/cargo/ops/tree/graph.rs
index f0dad4e5d..31276f104 100644
--- a/src/tools/cargo/src/cargo/ops/tree/graph.rs
+++ b/src/tools/cargo/src/cargo/ops/tree/graph.rs
@@ -598,9 +598,8 @@ fn add_feature_rec(
package_index: usize,
) {
let feature_map = resolve.summary(package_id).features();
- let fvs = match feature_map.get(&feature_name) {
- Some(fvs) => fvs,
- None => return,
+ let Some(fvs) = feature_map.get(&feature_name) else {
+ return;
};
for fv in fvs {
match fv {
diff --git a/src/tools/cargo/src/cargo/ops/tree/mod.rs b/src/tools/cargo/src/cargo/ops/tree/mod.rs
index f397b95af..ce3bae8cc 100644
--- a/src/tools/cargo/src/cargo/ops/tree/mod.rs
+++ b/src/tools/cargo/src/cargo/ops/tree/mod.rs
@@ -135,7 +135,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<()
// TODO: Target::All is broken with -Zfeatures=itarget. To handle that properly,
// `FeatureResolver` will need to be taught what "all" means.
let requested_kinds = CompileKind::from_requested_targets(ws.config(), &requested_targets)?;
- let target_data = RustcTargetData::new(ws, &requested_kinds)?;
+ let mut target_data = RustcTargetData::new(ws, &requested_kinds)?;
let specs = opts.packages.to_package_id_specs(ws)?;
let has_dev = if opts
.edge_kinds
@@ -150,14 +150,16 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<()
} else {
ForceAllTargets::No
};
+ let max_rust_version = ws.rust_version();
let ws_resolve = ops::resolve_ws_with_opts(
ws,
- &target_data,
+ &mut target_data,
&requested_kinds,
&opts.cli_features,
&specs,
has_dev,
force_all,
+ max_rust_version,
)?;
let package_map: HashMap<PackageId, &Package> = ws_resolve
diff --git a/src/tools/cargo/src/cargo/sources/config.rs b/src/tools/cargo/src/cargo/sources/config.rs
index c51c1f009..cc7aa9925 100644
--- a/src/tools/cargo/src/cargo/sources/config.rs
+++ b/src/tools/cargo/src/cargo/sources/config.rs
@@ -4,7 +4,8 @@
//! structure usable by Cargo itself. Currently this is primarily used to map
//! sources to one another via the `replace-with` key in `.cargo/config`.
-use crate::core::{GitReference, PackageId, Source, SourceId};
+use crate::core::{GitReference, PackageId, SourceId};
+use crate::sources::source::Source;
use crate::sources::{ReplacedSource, CRATES_IO_REGISTRY};
use crate::util::config::{self, ConfigRelativePath, OptValue};
use crate::util::errors::CargoResult;
@@ -134,30 +135,26 @@ impl<'cfg> SourceConfigMap<'cfg> {
) -> CargoResult<Box<dyn Source + 'cfg>> {
debug!("loading: {}", id);
- let mut name = match self.id2name.get(&id) {
- Some(name) => name,
- None => return id.load(self.config, yanked_whitelist),
+ let Some(mut name) = self.id2name.get(&id) else {
+ return id.load(self.config, yanked_whitelist);
};
let mut cfg_loc = "";
let orig_name = name;
let new_id = loop {
- let cfg = match self.cfgs.get(name) {
- Some(cfg) => cfg,
- None => {
- // Attempt to interpret the source name as an alt registry name
- if let Ok(alt_id) = SourceId::alt_registry(self.config, name) {
- debug!("following pointer to registry {}", name);
- break alt_id.with_precise(id.precise().map(str::to_string));
- }
- bail!(
- "could not find a configured source with the \
+ let Some(cfg) = self.cfgs.get(name) else {
+ // Attempt to interpret the source name as an alt registry name
+ if let Ok(alt_id) = SourceId::alt_registry(self.config, name) {
+ debug!("following pointer to registry {}", name);
+ break alt_id.with_precise(id.precise().map(str::to_string));
+ }
+ bail!(
+ "could not find a configured source with the \
name `{}` when attempting to lookup `{}` \
(configuration in `{}`)",
- name,
- orig_name,
- cfg_loc
- );
- }
+ name,
+ orig_name,
+ cfg_loc
+ );
};
match &cfg.replace_with {
Some((s, c)) => {
@@ -242,7 +239,7 @@ restore the source replacement configuration to continue the build
let mut srcs = Vec::new();
if let Some(registry) = def.registry {
let url = url(&registry, &format!("source.{}.registry", name))?;
- srcs.push(SourceId::for_alt_registry(&url, &name)?);
+ srcs.push(SourceId::for_source_replacement_registry(&url, &name)?);
}
if let Some(local_registry) = def.local_registry {
let path = local_registry.resolve_path(self.config);
diff --git a/src/tools/cargo/src/cargo/sources/directory.rs b/src/tools/cargo/src/cargo/sources/directory.rs
index a527c6dd7..7195fd72d 100644
--- a/src/tools/cargo/src/cargo/sources/directory.rs
+++ b/src/tools/cargo/src/cargo/sources/directory.rs
@@ -3,8 +3,10 @@ use std::fmt::{self, Debug, Formatter};
use std::path::{Path, PathBuf};
use std::task::Poll;
-use crate::core::source::MaybePackage;
-use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary};
+use crate::core::{Dependency, Package, PackageId, SourceId, Summary};
+use crate::sources::source::MaybePackage;
+use crate::sources::source::QueryKind;
+use crate::sources::source::Source;
use crate::sources::PathSource;
use crate::util::errors::CargoResult;
use crate::util::Config;
@@ -221,9 +223,8 @@ impl<'cfg> Source for DirectorySource<'cfg> {
}
fn verify(&self, id: PackageId) -> CargoResult<()> {
- let (pkg, cksum) = match self.packages.get(&id) {
- Some(&(ref pkg, ref cksum)) => (pkg, cksum),
- None => anyhow::bail!("failed to find entry for `{}` in directory source", id),
+ let Some((pkg, cksum)) = self.packages.get(&id) else {
+ anyhow::bail!("failed to find entry for `{}` in directory source", id);
};
for (file, cksum) in cksum.files.iter() {
diff --git a/src/tools/cargo/src/cargo/sources/git/mod.rs b/src/tools/cargo/src/cargo/sources/git/mod.rs
index 5d9d2886e..4c01016c2 100644
--- a/src/tools/cargo/src/cargo/sources/git/mod.rs
+++ b/src/tools/cargo/src/cargo/sources/git/mod.rs
@@ -2,7 +2,7 @@
//!
//! Apparently, the most important type in this module is [`GitSource`].
//! [`utils`] provides libgit2 utilities like fetch and checkout, whereas
-//! [`oxide`] is the couterpart for gitoxide integration. [`known_hosts`]
+//! [`oxide`] is the counterpart for gitoxide integration. [`known_hosts`]
//! is the mitigation of [CVE-2022-46176].
//!
//! [CVE-2022-46176]: https://blog.rust-lang.org/2023/01/10/cve-2022-46176.html
diff --git a/src/tools/cargo/src/cargo/sources/git/oxide.rs b/src/tools/cargo/src/cargo/sources/git/oxide.rs
index ec4fcecdd..5fccdd0c6 100644
--- a/src/tools/cargo/src/cargo/sources/git/oxide.rs
+++ b/src/tools/cargo/src/cargo/sources/git/oxide.rs
@@ -353,7 +353,7 @@ pub fn cargo_config_to_gitoxide_overrides(config: &Config) -> CargoResult<Vec<BS
Ok(values)
}
-/// Reinitializes a given Git repository. This is useful when a Git repoistory
+/// Reinitializes a given Git repository. This is useful when a Git repository
/// seems corrupted and we want to start over.
pub fn reinitialize(git_dir: &Path) -> CargoResult<()> {
fn init(path: &Path, bare: bool) -> CargoResult<()> {
diff --git a/src/tools/cargo/src/cargo/sources/git/source.rs b/src/tools/cargo/src/cargo/sources/git/source.rs
index 10796562d..7af342f45 100644
--- a/src/tools/cargo/src/cargo/sources/git/source.rs
+++ b/src/tools/cargo/src/cargo/sources/git/source.rs
@@ -1,9 +1,12 @@
//! See [GitSource].
-use crate::core::source::{MaybePackage, QueryKind, Source, SourceId};
use crate::core::GitReference;
+use crate::core::SourceId;
use crate::core::{Dependency, Package, PackageId, Summary};
use crate::sources::git::utils::GitRemote;
+use crate::sources::source::MaybePackage;
+use crate::sources::source::QueryKind;
+use crate::sources::source::Source;
use crate::sources::PathSource;
use crate::util::errors::CargoResult;
use crate::util::hex::short_hash;
@@ -70,7 +73,7 @@ pub struct GitSource<'cfg> {
source_id: SourceId,
/// The underlying path source to discover packages inside the Git repository.
path_source: Option<PathSource<'cfg>>,
- /// The identifer of this source for Cargo's Git cache directory.
+ /// The identifier of this source for Cargo's Git cache directory.
/// See [`ident`] for more.
ident: String,
config: &'cfg Config,
@@ -120,7 +123,7 @@ impl<'cfg> GitSource<'cfg> {
}
/// Returns the packages discovered by this source. It may fetch the Git
- /// repository as well as walk the filesystem if package informations
+ /// repository as well as walk the filesystem if package information
/// haven't yet updated.
pub fn read_packages(&mut self) -> CargoResult<Vec<Package>> {
if self.path_source.is_none() {
diff --git a/src/tools/cargo/src/cargo/sources/git/utils.rs b/src/tools/cargo/src/cargo/sources/git/utils.rs
index 093631091..74690d30c 100644
--- a/src/tools/cargo/src/cargo/sources/git/utils.rs
+++ b/src/tools/cargo/src/cargo/sources/git/utils.rs
@@ -264,7 +264,7 @@ impl<'a> GitCheckout<'a> {
/// is done. Use [`GitCheckout::is_fresh`] to check.
///
/// * The `database` is where this checkout is from.
- /// * The `repo` will be the checked out Git repoistory.
+ /// * The `repo` will be the checked out Git repository.
fn new(
database: &'a GitDatabase,
revision: git2::Oid,
@@ -394,7 +394,7 @@ impl<'a> GitCheckout<'a> {
fn update_submodules(&self, cargo_config: &Config) -> CargoResult<()> {
return update_submodules(&self.repo, cargo_config, self.remote_url().as_str());
- /// Recusive helper for [`GitCheckout::update_submodules`].
+ /// Recursive helper for [`GitCheckout::update_submodules`].
fn update_submodules(
repo: &git2::Repository,
cargo_config: &Config,
@@ -444,9 +444,8 @@ impl<'a> GitCheckout<'a> {
// A submodule which is listed in .gitmodules but not actually
// checked out will not have a head id, so we should ignore it.
- let head = match child.head_id() {
- Some(head) => head,
- None => return Ok(()),
+ let Some(head) = child.head_id() else {
+ return Ok(());
};
// If the submodule hasn't been checked out yet, we need to
@@ -1087,7 +1086,7 @@ pub fn fetch(
debug!("fetch failed: {}", err);
if !repo_reinitialized.load(Ordering::Relaxed)
- // We check for errors that could occour if the configuration, refs or odb files are corrupted.
+ // We check for errors that could occur if the configuration, refs or odb files are corrupted.
// We don't check for errors related to writing as `gitoxide` is expected to create missing leading
// folder before writing files into it, or else not even open a directory as git repository (which is
// also handled here).
@@ -1313,16 +1312,12 @@ fn maybe_gc_repo(repo: &mut git2::Repository, config: &Config) -> CargoResult<()
/// filenames, so they never get cleaned up.
fn clean_repo_temp_files(repo: &git2::Repository) {
let path = repo.path().join("objects/pack/pack_git2_*");
- let pattern = match path.to_str() {
- Some(p) => p,
- None => {
- tracing::warn!("cannot convert {path:?} to a string");
- return;
- }
+ let Some(pattern) = path.to_str() else {
+ tracing::warn!("cannot convert {path:?} to a string");
+ return;
};
- let paths = match glob::glob(pattern) {
- Ok(paths) => paths,
- Err(_) => return,
+ let Ok(paths) = glob::glob(pattern) else {
+ return;
};
for path in paths {
if let Ok(path) = path {
@@ -1336,7 +1331,7 @@ fn clean_repo_temp_files(repo: &git2::Repository) {
}
}
-/// Reinitializes a given Git repository. This is useful when a Git repoistory
+/// Reinitializes a given Git repository. This is useful when a Git repository
/// seems corrupted and we want to start over.
fn reinitialize(repo: &mut git2::Repository) -> CargoResult<()> {
// Here we want to drop the current repository object pointed to by `repo`,
diff --git a/src/tools/cargo/src/cargo/sources/mod.rs b/src/tools/cargo/src/cargo/sources/mod.rs
index 81eda24ca..7da1d652d 100644
--- a/src/tools/cargo/src/cargo/sources/mod.rs
+++ b/src/tools/cargo/src/cargo/sources/mod.rs
@@ -1,6 +1,14 @@
-//! Implementations of `Source` trait.
+//! The trait for sources of Cargo packages and its built-in implementations.
//!
-//! Cargo provides several built-in implementations of [`Source`] trait. Namely,
+//! A source is a provider that contains source files and metadata of packages.
+//! It provides a number of methods to fetch those package information, for
+//! example, querying metadata or downloading files for a package. These
+//! information then can be used as dependencies for other Cargo packages.
+//!
+//! This module provides [`Source`][source::Source] trait as an abstraction of different sources,
+//! as well as [`SourceMap`][source::SourceMap] struct as a map of all available sources.
+//!
+//! Several built-in implementations of `Source` trait are provided. Namely,
//!
//! * [`RegistrySource`] --- A source that provides an index for people to query
//! a crate's metadata, and fetch files for a certain crate. crates.io falls
@@ -16,7 +24,6 @@
//! This module also contains [`SourceConfigMap`], which is effectively the
//! representation of the `[source.*]` value in Cargo configuration.
//!
-//! [`Source`]: crate::core::Source
//! [source replacement]: https://doc.rust-lang.org/nightly/cargo/reference/source-replacement.html
pub use self::config::SourceConfigMap;
@@ -32,3 +39,4 @@ pub mod git;
pub mod path;
pub mod registry;
pub mod replaced;
+pub mod source;
diff --git a/src/tools/cargo/src/cargo/sources/path.rs b/src/tools/cargo/src/cargo/sources/path.rs
index 1d8ffc35c..0cc639976 100644
--- a/src/tools/cargo/src/cargo/sources/path.rs
+++ b/src/tools/cargo/src/cargo/sources/path.rs
@@ -3,9 +3,11 @@ use std::fmt::{self, Debug, Formatter};
use std::path::{Path, PathBuf};
use std::task::Poll;
-use crate::core::source::MaybePackage;
-use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary};
+use crate::core::{Dependency, Package, PackageId, SourceId, Summary};
use crate::ops;
+use crate::sources::source::MaybePackage;
+use crate::sources::source::QueryKind;
+use crate::sources::source::Source;
use crate::util::{internal, CargoResult, Config};
use anyhow::Context as _;
use cargo_util::paths;
@@ -28,7 +30,7 @@ pub struct PathSource<'cfg> {
source_id: SourceId,
/// The root path of this source.
path: PathBuf,
- /// Whether this source has updated all package informations it may contain.
+ /// Whether this source has updated all package information it may contain.
updated: bool,
/// Packages that this sources has discovered.
packages: Vec<Package>,
@@ -95,7 +97,7 @@ impl<'cfg> PathSource<'cfg> {
}
/// Returns the packages discovered by this source. It may walk the
- /// filesystem if package informations haven't yet updated.
+ /// filesystem if package information haven't yet updated.
pub fn read_packages(&self) -> CargoResult<Vec<Package>> {
if self.updated {
Ok(self.packages.clone())
@@ -173,9 +175,8 @@ impl<'cfg> PathSource<'cfg> {
};
let filter = |path: &Path, is_dir: bool| {
- let relative_path = match path.strip_prefix(root) {
- Ok(p) => p,
- Err(_) => return false,
+ let Ok(relative_path) = path.strip_prefix(root) else {
+ return false;
};
let rel = relative_path.as_os_str();
diff --git a/src/tools/cargo/src/cargo/sources/registry/download.rs b/src/tools/cargo/src/cargo/sources/registry/download.rs
index 08940b3a1..9bf838625 100644
--- a/src/tools/cargo/src/cargo/sources/registry/download.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/download.rs
@@ -85,6 +85,7 @@ pub(super) fn download(
None,
Operation::Read,
vec![],
+ true,
)?)
} else {
None
diff --git a/src/tools/cargo/src/cargo/sources/registry/http_remote.rs b/src/tools/cargo/src/cargo/sources/registry/http_remote.rs
index 52f6f392e..9fe76333b 100644
--- a/src/tools/cargo/src/cargo/sources/registry/http_remote.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/http_remote.rs
@@ -335,7 +335,7 @@ impl<'cfg> HttpRegistry<'cfg> {
}),
RetryResult::Err(e) => Err(e),
RetryResult::Retry(sleep) => {
- debug!("download retry {:?} for {sleep}ms", download.path);
+ debug!(target: "network", "download retry {:?} for {sleep}ms", download.path);
self.downloads.sleeping.push(sleep, (download, handle));
continue;
}
@@ -547,11 +547,9 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
return Poll::Ready(Ok(LoadResponse::NotFound));
}
StatusCode::Unauthorized
- if !self.auth_required
- && path == Path::new(RegistryConfig::NAME)
- && self.config.cli_unstable().registry_auth =>
+ if !self.auth_required && path == Path::new(RegistryConfig::NAME) =>
{
- debug!("re-attempting request for config.json with authorization included.");
+ debug!(target: "network", "re-attempting request for config.json with authorization included.");
self.fresh.remove(path);
self.auth_required = true;
@@ -568,9 +566,11 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
}
}
Ok(challenge) => {
- debug!("ignoring non-Cargo challenge: {}", challenge.scheme)
+ debug!(target: "network", "ignoring non-Cargo challenge: {}", challenge.scheme)
+ }
+ Err(e) => {
+ debug!(target: "network", "failed to parse challenge: {}", e)
}
- Err(e) => debug!("failed to parse challenge: {}", e),
}
}
}
@@ -586,12 +586,13 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
}
.into());
if self.auth_required {
- return Poll::Ready(err.context(auth::AuthorizationError {
- sid: self.source_id.clone(),
- default_registry: self.config.default_registry()?,
- login_url: self.login_url.clone(),
- reason: auth::AuthorizationErrorReason::TokenRejected,
- }));
+ let auth_error = auth::AuthorizationError::new(
+ self.config,
+ self.source_id,
+ self.login_url.clone(),
+ auth::AuthorizationErrorReason::TokenRejected,
+ )?;
+ return Poll::Ready(err.context(auth_error));
} else {
return Poll::Ready(err);
}
@@ -609,16 +610,12 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
}
}
- if !self.config.cli_unstable().registry_auth {
- self.auth_required = false;
- }
-
// Looks like we're going to have to do a network request.
self.start_fetch()?;
let mut handle = http_handle(self.config)?;
let full_url = self.full_url(path);
- debug!("fetch {}", full_url);
+ debug!(target: "network", "fetch {}", full_url);
handle.get(true)?;
handle.url(&full_url)?;
handle.follow_location(true)?;
@@ -651,9 +648,10 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
self.login_url.as_ref(),
Operation::Read,
self.auth_error_headers.clone(),
+ true,
)?;
headers.append(&format!("Authorization: {}", authorization))?;
- trace!("including authorization for {}", full_url);
+ trace!(target: "network", "including authorization for {}", full_url);
}
handle.http_headers(headers)?;
@@ -662,7 +660,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
// We do that through this token. Each request (and associated response) gets one.
let token = self.downloads.next;
self.downloads.next += 1;
- debug!("downloading {} as {}", path.display(), token);
+ debug!(target: "network", "downloading {} as {}", path.display(), token);
let is_new = self.downloads.pending_paths.insert(path.to_path_buf());
assert!(is_new, "path queued for download more than once");
@@ -671,7 +669,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
// That thread-local is set up in `block_until_ready` when it calls self.multi.perform,
// which is what ultimately calls this method.
handle.write_function(move |buf| {
- trace!("{} - {} bytes of data", token, buf.len());
+ trace!(target: "network", "{} - {} bytes of data", token, buf.len());
tls::with(|downloads| {
if let Some(downloads) = downloads {
downloads.pending[&token]
@@ -721,10 +719,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
}
fn config(&mut self) -> Poll<CargoResult<Option<RegistryConfig>>> {
- let mut cfg = ready!(self.config()?).clone();
- if !self.config.cli_unstable().registry_auth {
- cfg.auth_required = false;
- }
+ let cfg = ready!(self.config()?).clone();
Poll::Ready(Ok(Some(cfg)))
}
@@ -772,7 +767,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
}
fn block_until_ready(&mut self) -> CargoResult<()> {
- trace!(
+ trace!(target: "network",
"block_until_ready: {} transfers pending",
self.downloads.pending.len()
);
@@ -787,7 +782,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
.perform()
.with_context(|| "failed to perform http requests")
})?;
- trace!("{} transfers remaining", remaining_in_multi);
+ trace!(target: "network", "{} transfers remaining", remaining_in_multi);
if remaining_in_multi + self.downloads.sleeping.len() as u32 == 0 {
return Ok(());
@@ -795,7 +790,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
if self.downloads.pending.is_empty() {
let delay = self.downloads.sleeping.time_to_next().unwrap();
- debug!("sleeping main thread for {delay:?}");
+ debug!(target: "network", "sleeping main thread for {delay:?}");
std::thread::sleep(delay);
} else {
// We have no more replies to provide the caller with,
diff --git a/src/tools/cargo/src/cargo/sources/registry/index.rs b/src/tools/cargo/src/cargo/sources/registry/index.rs
index 05bfe71af..ca1cf4069 100644
--- a/src/tools/cargo/src/cargo/sources/registry/index.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/index.rs
@@ -85,13 +85,13 @@
//! [`RemoteRegistry`]: super::remote::RemoteRegistry
//! [`Dependency`]: crate::core::Dependency
-use crate::core::dependency::DepKind;
+use crate::core::dependency::{Artifact, DepKind};
use crate::core::Dependency;
use crate::core::{PackageId, SourceId, Summary};
use crate::sources::registry::{LoadResponse, RegistryData};
use crate::util::interning::InternedString;
use crate::util::IntoUrl;
-use crate::util::{internal, CargoResult, Config, Filesystem, OptVersionReq, ToSemver};
+use crate::util::{internal, CargoResult, Config, Filesystem, OptVersionReq, RustVersion};
use anyhow::bail;
use cargo_util::{paths, registry::make_dep_path};
use semver::Version;
@@ -189,11 +189,64 @@ enum MaybeIndexSummary {
/// from a line from a raw index file, or a JSON blob from on-disk index cache.
///
/// In addition to a full [`Summary`], we have information on whether it is `yanked`.
-pub struct IndexSummary {
- pub summary: Summary,
- pub yanked: bool,
- /// Schema version, see [`IndexPackage::v`].
- v: u32,
+#[derive(Clone, Debug)]
+pub enum IndexSummary {
+ /// Available for consideration
+ Candidate(Summary),
+ /// Yanked within its registry
+ Yanked(Summary),
+ /// Not available as we are offline and create is not downloaded yet
+ Offline(Summary),
+ /// From a newer schema version and is likely incomplete or inaccurate
+ Unsupported(Summary, u32),
+}
+
+impl IndexSummary {
+ /// Extract the summary from any variant
+ pub fn as_summary(&self) -> &Summary {
+ match self {
+ IndexSummary::Candidate(sum)
+ | IndexSummary::Yanked(sum)
+ | IndexSummary::Offline(sum)
+ | IndexSummary::Unsupported(sum, _) => sum,
+ }
+ }
+
+ /// Extract the summary from any variant
+ pub fn into_summary(self) -> Summary {
+ match self {
+ IndexSummary::Candidate(sum)
+ | IndexSummary::Yanked(sum)
+ | IndexSummary::Offline(sum)
+ | IndexSummary::Unsupported(sum, _) => sum,
+ }
+ }
+
+ /// Extract the package id from any variant
+ pub fn package_id(&self) -> PackageId {
+ match self {
+ IndexSummary::Candidate(sum)
+ | IndexSummary::Yanked(sum)
+ | IndexSummary::Offline(sum)
+ | IndexSummary::Unsupported(sum, _) => sum.package_id(),
+ }
+ }
+
+ /// Returns `true` if the index summary is [`Yanked`].
+ ///
+ /// [`Yanked`]: IndexSummary::Yanked
+ #[must_use]
+ pub fn is_yanked(&self) -> bool {
+ matches!(self, Self::Yanked(..))
+ }
+
+ /// Returns `true` if the index summary is [`Offline`].
+ ///
+ /// [`Offline`]: IndexSummary::Offline
+ #[must_use]
+ pub fn is_offline(&self) -> bool {
+ matches!(self, Self::Offline(..))
+ }
}
/// A representation of the cache on disk that Cargo maintains of summaries.
@@ -270,7 +323,7 @@ struct SummariesCache<'a> {
/// A single line in the index representing a single version of a package.
#[derive(Deserialize)]
pub struct IndexPackage<'a> {
- /// Name of the pacakge.
+ /// Name of the package.
name: InternedString,
/// The version of this dependency.
vers: Version,
@@ -305,7 +358,7 @@ pub struct IndexPackage<'a> {
///
/// Added in 2023 (see <https://github.com/rust-lang/crates.io/pull/6267>),
/// can be `None` if published before then or if not set in the manifest.
- rust_version: Option<InternedString>,
+ rust_version: Option<RustVersion>,
/// The schema version for this entry.
///
/// If this is None, it defaults to version `1`. Entries with unknown
@@ -313,6 +366,9 @@ pub struct IndexPackage<'a> {
///
/// Version `2` schema adds the `features2` field.
///
+ /// Version `3` schema adds `artifact`, `bindep_targes`, and `lib` for
+ /// artifact dependencies support.
+ ///
/// This provides a method to safely introduce changes to index entries
/// and allow older versions of cargo to ignore newer entries it doesn't
/// understand. This is honored as of 1.51, so unfortunately older
@@ -356,6 +412,10 @@ struct RegistryDependency<'a> {
///
/// [RFC 1977]: https://rust-lang.github.io/rfcs/1977-public-private-dependencies.html
public: Option<bool>,
+ artifact: Option<Vec<Cow<'a, str>>>,
+ bindep_target: Option<Cow<'a, str>>,
+ #[serde(default)]
+ lib: bool,
}
impl<'cfg> RegistryIndex<'cfg> {
@@ -378,13 +438,13 @@ impl<'cfg> RegistryIndex<'cfg> {
/// the index file, aka [`IndexSummary`].
pub fn hash(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> Poll<CargoResult<&str>> {
let req = OptVersionReq::exact(pkg.version());
- let summary = self.summaries(&pkg.name(), &req, load)?;
+ let summary = self.summaries(pkg.name(), &req, load)?;
let summary = ready!(summary)
- .filter(|s| s.summary.version() == pkg.version())
+ .filter(|s| s.package_id().version() == pkg.version())
.next();
Poll::Ready(Ok(summary
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?
- .summary
+ .as_summary()
.checksum()
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?))
}
@@ -400,19 +460,20 @@ impl<'cfg> RegistryIndex<'cfg> {
///
/// Internally there's quite a few layer of caching to amortize this cost
/// though since this method is called quite a lot on null builds in Cargo.
- pub fn summaries<'a, 'b>(
+ fn summaries<'a, 'b>(
&'a mut self,
- name: &str,
+ name: InternedString,
req: &'b OptVersionReq,
load: &mut dyn RegistryData,
) -> Poll<CargoResult<impl Iterator<Item = &'a IndexSummary> + 'b>>
where
'a: 'b,
{
+ let bindeps = self.config.cli_unstable().bindeps;
+
let source_id = self.source_id;
// First up parse what summaries we have available.
- let name = InternedString::new(name);
let summaries = ready!(self.load_summaries(name, load)?);
// Iterate over our summaries, extract all relevant ones which match our
@@ -426,24 +487,27 @@ impl<'cfg> RegistryIndex<'cfg> {
.versions
.iter_mut()
.filter_map(move |(k, v)| if req.matches(k) { Some(v) } else { None })
- .filter_map(move |maybe| match maybe.parse(raw_data, source_id) {
- Ok(summary) => Some(summary),
- Err(e) => {
- info!("failed to parse `{}` registry package: {}", name, e);
- None
- }
- })
- .filter(move |is| {
- if is.v > INDEX_V_MAX {
- debug!(
- "unsupported schema version {} ({} {})",
- is.v,
- is.summary.name(),
- is.summary.version()
- );
- false
- } else {
- true
+ .filter_map(move |maybe| {
+ match maybe.parse(raw_data, source_id, bindeps) {
+ Ok(sum @ IndexSummary::Candidate(_) | sum @ IndexSummary::Yanked(_)) => {
+ Some(sum)
+ }
+ Ok(IndexSummary::Unsupported(summary, v)) => {
+ debug!(
+ "unsupported schema version {} ({} {})",
+ v,
+ summary.name(),
+ summary.version()
+ );
+ None
+ }
+ Ok(IndexSummary::Offline(_)) => {
+ unreachable!("We do not check for off-line until later")
+ }
+ Err(e) => {
+ info!("failed to parse `{}` registry package: {}", name, e);
+ None
+ }
}
})))
}
@@ -458,7 +522,7 @@ impl<'cfg> RegistryIndex<'cfg> {
/// The actual kind index file being parsed depends on which kind of
/// [`RegistryData`] the `load` argument is given. For example, a
/// Git-based [`RemoteRegistry`] will first try a on-disk index cache
- /// file, and then try parsing registry raw index fomr Git repository.
+ /// file, and then try parsing registry raw index from Git repository.
///
/// In effect, this is intended to be a quite cheap operation.
///
@@ -507,7 +571,7 @@ impl<'cfg> RegistryIndex<'cfg> {
/// This is primarily used by [`Source::query`](super::Source).
pub fn query_inner(
&mut self,
- name: &str,
+ name: InternedString,
req: &OptVersionReq,
load: &mut dyn RegistryData,
yanked_whitelist: &HashSet<PackageId>,
@@ -524,14 +588,35 @@ impl<'cfg> RegistryIndex<'cfg> {
// then cargo will fail to download and an error message
// indicating that the required dependency is unavailable while
// offline will be displayed.
- if ready!(self.query_inner_with_online(name, req, load, yanked_whitelist, f, false)?)
- > 0
- {
+ let mut called = false;
+ let callback = &mut |s: IndexSummary| {
+ if !s.is_offline() {
+ called = true;
+ f(s.into_summary());
+ }
+ };
+ ready!(self.query_inner_with_online(
+ name,
+ req,
+ load,
+ yanked_whitelist,
+ callback,
+ false
+ )?);
+ if called {
return Poll::Ready(Ok(()));
}
}
- self.query_inner_with_online(name, req, load, yanked_whitelist, f, true)
- .map_ok(|_| ())
+ self.query_inner_with_online(
+ name,
+ req,
+ load,
+ yanked_whitelist,
+ &mut |s| {
+ f(s.into_summary());
+ },
+ true,
+ )
}
/// Inner implementation of [`Self::query_inner`]. Returns the number of
@@ -540,13 +625,13 @@ impl<'cfg> RegistryIndex<'cfg> {
/// The `online` controls whether Cargo can access the network when needed.
fn query_inner_with_online(
&mut self,
- name: &str,
+ name: InternedString,
req: &OptVersionReq,
load: &mut dyn RegistryData,
yanked_whitelist: &HashSet<PackageId>,
- f: &mut dyn FnMut(Summary),
+ f: &mut dyn FnMut(IndexSummary),
online: bool,
- ) -> Poll<CargoResult<usize>> {
+ ) -> Poll<CargoResult<()>> {
let source_id = self.source_id;
let summaries = ready!(self.summaries(name, req, load))?;
@@ -562,27 +647,20 @@ impl<'cfg> RegistryIndex<'cfg> {
// does not satisfy the requirements, then resolution will
// fail. Unfortunately, whether or not something is optional
// is not known here.
- .filter(|s| (online || load.is_crate_downloaded(s.summary.package_id())))
+ .map(|s| {
+ if online || load.is_crate_downloaded(s.package_id()) {
+ s.clone()
+ } else {
+ IndexSummary::Offline(s.as_summary().clone())
+ }
+ })
// Next filter out all yanked packages. Some yanked packages may
// leak through if they're in a whitelist (aka if they were
// previously in `Cargo.lock`
- .filter(|s| !s.yanked || yanked_whitelist.contains(&s.summary.package_id()))
- .map(|s| s.summary.clone());
-
- // Handle `cargo update --precise` here. If specified, our own source
- // will have a precise version listed of the form
- // `<pkg>=<p_req>o-><f_req>` where `<pkg>` is the name of a crate on
- // this source, `<p_req>` is the version installed and `<f_req> is the
- // version requested (argument to `--precise`).
- let precise = match source_id.precise() {
- Some(p) if p.starts_with(name) && p[name.len()..].starts_with('=') => {
- let mut vers = p[name.len() + 1..].splitn(2, "->");
- let current_vers = vers.next().unwrap().to_semver().unwrap();
- let requested_vers = vers.next().unwrap().to_semver().unwrap();
- Some((current_vers, requested_vers))
- }
- _ => None,
- };
+ .filter(|s| !s.is_yanked() || yanked_whitelist.contains(&s.package_id()));
+
+ // Handle `cargo update --precise` here.
+ let precise = source_id.precise_registry_version(name.as_str());
let summaries = summaries.filter(|s| match &precise {
Some((current, requested)) => {
if req.matches(current) {
@@ -590,7 +668,7 @@ impl<'cfg> RegistryIndex<'cfg> {
// by build metadata. This shouldn't be allowed, but since
// it is, this will honor it if requested. However, if not
// specified, then ignore it.
- let s_vers = s.version();
+ let s_vers = s.package_id().version();
match (s_vers.build.is_empty(), requested.build.is_empty()) {
(true, true) => s_vers == requested,
(true, false) => false,
@@ -610,12 +688,8 @@ impl<'cfg> RegistryIndex<'cfg> {
None => true,
});
- let mut count = 0;
- for summary in summaries {
- f(summary);
- count += 1;
- }
- Poll::Ready(Ok(count))
+ summaries.for_each(f);
+ Poll::Ready(Ok(()))
}
/// Looks into the summaries to check if a package has been yanked.
@@ -625,9 +699,9 @@ impl<'cfg> RegistryIndex<'cfg> {
load: &mut dyn RegistryData,
) -> Poll<CargoResult<bool>> {
let req = OptVersionReq::exact(pkg.version());
- let found = ready!(self.summaries(&pkg.name(), &req, load))?
- .filter(|s| s.summary.version() == pkg.version())
- .any(|summary| summary.yanked);
+ let found = ready!(self.summaries(pkg.name(), &req, load))?
+ .filter(|s| s.package_id().version() == pkg.version())
+ .any(|s| s.is_yanked());
Poll::Ready(Ok(found))
}
}
@@ -683,6 +757,8 @@ impl Summaries {
let response = ready!(load.load(root, relative, index_version.as_deref())?);
+ let bindeps = config.cli_unstable().bindeps;
+
match response {
LoadResponse::CacheValid => {
tracing::debug!("fast path for registry cache of {:?}", relative);
@@ -713,7 +789,7 @@ impl Summaries {
// allow future cargo implementations to break the
// interpretation of each line here and older cargo will simply
// ignore the new lines.
- let summary = match IndexSummary::parse(line, source_id) {
+ let summary = match IndexSummary::parse(line, source_id, bindeps) {
Ok(summary) => summary,
Err(e) => {
// This should only happen when there is an index
@@ -732,7 +808,7 @@ impl Summaries {
continue;
}
};
- let version = summary.summary.package_id().version().clone();
+ let version = summary.package_id().version().clone();
cache.versions.push((version.clone(), line));
ret.versions.insert(version, summary.into());
}
@@ -866,12 +942,17 @@ impl MaybeIndexSummary {
/// Does nothing if this is already `Parsed`, and otherwise the `raw_data`
/// passed in is sliced with the bounds in `Unparsed` and then actually
/// parsed.
- fn parse(&mut self, raw_data: &[u8], source_id: SourceId) -> CargoResult<&IndexSummary> {
+ fn parse(
+ &mut self,
+ raw_data: &[u8],
+ source_id: SourceId,
+ bindeps: bool,
+ ) -> CargoResult<&IndexSummary> {
let (start, end) = match self {
MaybeIndexSummary::Unparsed { start, end } => (*start, *end),
MaybeIndexSummary::Parsed(summary) => return Ok(summary),
};
- let summary = IndexSummary::parse(&raw_data[start..end], source_id)?;
+ let summary = IndexSummary::parse(&raw_data[start..end], source_id, bindeps)?;
*self = MaybeIndexSummary::Parsed(summary);
match self {
MaybeIndexSummary::Unparsed { .. } => unreachable!(),
@@ -892,7 +973,7 @@ impl IndexSummary {
///
/// The `line` provided is expected to be valid JSON. It is supposed to be
/// a [`IndexPackage`].
- fn parse(line: &[u8], source_id: SourceId) -> CargoResult<IndexSummary> {
+ fn parse(line: &[u8], source_id: SourceId, bindeps: bool) -> CargoResult<IndexSummary> {
// ****CAUTION**** Please be extremely careful with returning errors
// from this function. Entries that error are not included in the
// index cache, and can cause cargo to get confused when switching
@@ -925,11 +1006,20 @@ impl IndexSummary {
}
let mut summary = Summary::new(pkgid, deps, &features, links, rust_version)?;
summary.set_checksum(cksum);
- Ok(IndexSummary {
- summary,
- yanked: yanked.unwrap_or(false),
- v,
- })
+
+ let v_max = if bindeps {
+ INDEX_V_MAX + 1
+ } else {
+ INDEX_V_MAX
+ };
+
+ if v_max < v {
+ Ok(IndexSummary::Unsupported(summary, v))
+ } else if yanked.unwrap_or(false) {
+ Ok(IndexSummary::Yanked(summary))
+ } else {
+ Ok(IndexSummary::Candidate(summary))
+ }
}
}
@@ -947,6 +1037,9 @@ impl<'a> RegistryDependency<'a> {
registry,
package,
public,
+ artifact,
+ bindep_target,
+ lib,
} = self;
let id = if let Some(registry) = &registry {
@@ -986,6 +1079,11 @@ impl<'a> RegistryDependency<'a> {
dep.set_registry_id(id);
}
+ if let Some(artifacts) = artifact {
+ let artifact = Artifact::parse(&artifacts, lib, bindep_target.as_deref())?;
+ dep.set_artifact(artifact);
+ }
+
dep.set_optional(optional)
.set_default_features(default_features)
.set_features(features)
diff --git a/src/tools/cargo/src/cargo/sources/registry/local.rs b/src/tools/cargo/src/cargo/sources/registry/local.rs
index 68fc61a6c..84ed52c39 100644
--- a/src/tools/cargo/src/cargo/sources/registry/local.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/local.rs
@@ -63,7 +63,7 @@ pub struct LocalRegistry<'cfg> {
/// Path where this local registry extract `.crate` tarballs to.
src_path: Filesystem,
config: &'cfg Config,
- /// Whether this source has updated all package informations it may contain.
+ /// Whether this source has updated all package information it may contain.
updated: bool,
/// Disables status messages.
quiet: bool,
diff --git a/src/tools/cargo/src/cargo/sources/registry/mod.rs b/src/tools/cargo/src/cargo/sources/registry/mod.rs
index c1ff8b12e..fb8f79817 100644
--- a/src/tools/cargo/src/cargo/sources/registry/mod.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/mod.rs
@@ -201,14 +201,15 @@ use tar::Archive;
use tracing::debug;
use crate::core::dependency::Dependency;
-use crate::core::source::MaybePackage;
-use crate::core::{Package, PackageId, QueryKind, Source, SourceId, Summary};
+use crate::core::{Package, PackageId, SourceId, Summary};
+use crate::sources::source::MaybePackage;
+use crate::sources::source::QueryKind;
+use crate::sources::source::Source;
use crate::sources::PathSource;
use crate::util::hex;
+use crate::util::interning::InternedString;
use crate::util::network::PollExt;
-use crate::util::{
- restricted_names, CargoResult, Config, Filesystem, LimitErrorReader, OptVersionReq,
-};
+use crate::util::{restricted_names, CargoResult, Config, Filesystem, LimitErrorReader};
/// The `.cargo-ok` file is used to track if the source is already unpacked.
/// See [`RegistrySource::unpack_package`] for more.
@@ -251,7 +252,7 @@ pub struct RegistrySource<'cfg> {
/// yanked.
///
/// This is populated from the entries in `Cargo.lock` to ensure that
- /// `cargo update -p somepkg` won't unlock yanked entries in `Cargo.lock`.
+ /// `cargo update somepkg` won't unlock yanked entries in `Cargo.lock`.
/// Otherwise, the resolver would think that those entries no longer
/// exist, and it would trigger updates to unrelated packages.
yanked_whitelist: HashSet<PackageId>,
@@ -688,20 +689,14 @@ impl<'cfg> RegistrySource<'cfg> {
// After we've loaded the package configure its summary's `checksum`
// field with the checksum we know for this `PackageId`.
- let req = OptVersionReq::exact(package.version());
- let summary_with_cksum = self
+ let cksum = self
.index
- .summaries(&package.name(), &req, &mut *self.ops)?
+ .hash(package, &mut *self.ops)
.expect("a downloaded dep now pending!?")
- .map(|s| s.summary.clone())
- .filter(|s| s.version() == package.version())
- .next()
.expect("summary not found");
- if let Some(cksum) = summary_with_cksum.checksum() {
- pkg.manifest_mut()
- .summary_mut()
- .set_checksum(cksum.to_string());
- }
+ pkg.manifest_mut()
+ .summary_mut()
+ .set_checksum(cksum.to_string());
Ok(pkg)
}
@@ -723,7 +718,7 @@ impl<'cfg> Source for RegistrySource<'cfg> {
debug!("attempting query without update");
let mut called = false;
ready!(self.index.query_inner(
- &dep.package_name(),
+ dep.package_name(),
dep.version_req(),
&mut *self.ops,
&self.yanked_whitelist,
@@ -744,7 +739,7 @@ impl<'cfg> Source for RegistrySource<'cfg> {
} else {
let mut called = false;
ready!(self.index.query_inner(
- &dep.package_name(),
+ dep.package_name(),
dep.version_req(),
&mut *self.ops,
&self.yanked_whitelist,
@@ -774,13 +769,14 @@ impl<'cfg> Source for RegistrySource<'cfg> {
dep.package_name().replace('-', "_"),
dep.package_name().replace('_', "-"),
] {
- if name_permutation.as_str() == dep.package_name().as_str() {
+ let name_permutation = InternedString::new(&name_permutation);
+ if name_permutation == dep.package_name() {
continue;
}
any_pending |= self
.index
.query_inner(
- &name_permutation,
+ name_permutation,
dep.version_req(),
&mut *self.ops,
&self.yanked_whitelist,
diff --git a/src/tools/cargo/src/cargo/sources/registry/remote.rs b/src/tools/cargo/src/cargo/sources/registry/remote.rs
index 89927181f..39eb14dc0 100644
--- a/src/tools/cargo/src/cargo/sources/registry/remote.rs
+++ b/src/tools/cargo/src/cargo/sources/registry/remote.rs
@@ -59,7 +59,7 @@ pub struct RemoteRegistry<'cfg> {
/// A Git [tree object] to help this registry find crate metadata from the
/// underlying Git repository.
///
- /// This is stored here to prevent Git from repeatly creating a tree object
+ /// This is stored here to prevent Git from repeatedly creating a tree object
/// during each call into `load()`.
///
/// [tree object]: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects#_tree_objects
@@ -70,7 +70,7 @@ pub struct RemoteRegistry<'cfg> {
head: Cell<Option<git2::Oid>>,
/// This stores sha value of the current HEAD commit for convenience.
current_sha: Cell<Option<InternedString>>,
- /// Whether this registry needs to update package informations.
+ /// Whether this registry needs to update package information.
///
/// See [`RemoteRegistry::mark_updated`] on how to make sure a registry
/// index is updated only once per session.
@@ -269,9 +269,8 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
}
let object = entry.to_object(repo)?;
- let blob = match object.as_blob() {
- Some(blob) => blob,
- None => anyhow::bail!("path `{}` is not a blob in the git repo", path.display()),
+ let Some(blob) = object.as_blob() else {
+ anyhow::bail!("path `{}` is not a blob in the git repo", path.display())
};
Ok(LoadResponse::Data {
@@ -307,10 +306,7 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
match ready!(self.load(Path::new(""), Path::new(RegistryConfig::NAME), None)?) {
LoadResponse::Data { raw_data, .. } => {
trace!("config loaded");
- let mut cfg: RegistryConfig = serde_json::from_slice(&raw_data)?;
- if !self.config.cli_unstable().registry_auth {
- cfg.auth_required = false;
- }
+ let cfg: RegistryConfig = serde_json::from_slice(&raw_data)?;
Poll::Ready(Ok(Some(cfg)))
}
_ => Poll::Ready(Ok(None)),
diff --git a/src/tools/cargo/src/cargo/sources/replaced.rs b/src/tools/cargo/src/cargo/sources/replaced.rs
index eef30e80c..f224e073d 100644
--- a/src/tools/cargo/src/cargo/sources/replaced.rs
+++ b/src/tools/cargo/src/cargo/sources/replaced.rs
@@ -1,5 +1,7 @@
-use crate::core::source::MaybePackage;
-use crate::core::{Dependency, Package, PackageId, QueryKind, Source, SourceId, Summary};
+use crate::core::{Dependency, Package, PackageId, SourceId, Summary};
+use crate::sources::source::MaybePackage;
+use crate::sources::source::QueryKind;
+use crate::sources::source::Source;
use crate::util::errors::CargoResult;
use std::task::Poll;
diff --git a/src/tools/cargo/src/cargo/core/source/mod.rs b/src/tools/cargo/src/cargo/sources/source.rs
index 2d1db1d53..5a3439e5d 100644
--- a/src/tools/cargo/src/cargo/core/source/mod.rs
+++ b/src/tools/cargo/src/cargo/sources/source.rs
@@ -1,30 +1,14 @@
-//! Fundamental types and traits for sources of Cargo packages.
-//!
-//! A source is a provider that contains source files and metadata of packages.
-//! It provides a number of methods to fetch those package informations, for
-//! example, querying metadata or downloading files for a package. These
-//! informations then can be used as dependencies for other Cargo packages.
-//!
-//! Notably, this module contains
-//!
-//! * [`Source`] trait as an abstraction of different sources
-//! * [`SourceMap`] struct as a map of all available sources
-//! * [`SourceId`] struct as an unique identifier for a certain source
-//!
-//! For implementations of `Source` trait, see [`crate::sources`].
+//! [`Source`] trait for sources of Cargo packages.
use std::collections::hash_map::HashMap;
use std::fmt;
use std::task::Poll;
use crate::core::package::PackageSet;
+use crate::core::SourceId;
use crate::core::{Dependency, Package, PackageId, Summary};
use crate::util::{CargoResult, Config};
-mod source_id;
-
-pub use self::source_id::{GitReference, SourceId};
-
/// An abstraction of different sources of Cargo packages.
///
/// The [`Source`] trait generalizes the API to interact with these providers.
@@ -63,7 +47,7 @@ pub trait Source {
/// Attempts to find the packages that match a dependency request.
///
/// Usually you should call [`Source::block_until_ready`] somewhere and
- /// wait until package informations become available. Otherwise any query
+ /// wait until package information become available. Otherwise any query
/// may return a [`Poll::Pending`].
///
/// The `f` argument is expected to get called when any [`Summary`] becomes available.
diff --git a/src/tools/cargo/src/cargo/util/auth/mod.rs b/src/tools/cargo/src/cargo/util/auth/mod.rs
index 60a356fa0..ea82dce0c 100644
--- a/src/tools/cargo/src/cargo/util/auth/mod.rs
+++ b/src/tools/cargo/src/cargo/util/auth/mod.rs
@@ -1,7 +1,7 @@
//! Registry authentication support.
use crate::{
- sources::CRATES_IO_REGISTRY,
+ core::features::cargo_docs_link,
util::{config::ConfigKey, CanonicalUrl, CargoResult, Config, IntoUrl},
};
use anyhow::{bail, Context as _};
@@ -74,11 +74,25 @@ impl RegistryConfigExtended {
}
/// Get the list of credential providers for a registry source.
-fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<String>>> {
+fn credential_provider(
+ config: &Config,
+ sid: &SourceId,
+ require_cred_provider_config: bool,
+ show_warnings: bool,
+) -> CargoResult<Vec<Vec<String>>> {
+ let warn = |message: String| {
+ if show_warnings {
+ config.shell().warn(message)
+ } else {
+ Ok(())
+ }
+ };
+
let cfg = registry_credential_config_raw(config, sid)?;
- let allow_cred_proc = config.cli_unstable().credential_process;
+ let mut global_provider_defined = true;
let default_providers = || {
- if allow_cred_proc {
+ global_provider_defined = false;
+ if config.cli_unstable().asymmetric_token {
// Enable the PASETO provider
vec![
vec!["cargo:token".to_string()],
@@ -90,7 +104,7 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<S
};
let global_providers = config
.get::<Option<Vec<Value<String>>>>("registry.global-credential-providers")?
- .filter(|p| !p.is_empty() && allow_cred_proc)
+ .filter(|p| !p.is_empty())
.map(|p| {
p.iter()
.rev()
@@ -101,29 +115,34 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<S
.unwrap_or_else(default_providers);
tracing::debug!(?global_providers);
- let providers = match cfg {
+ match cfg {
// If there's a specific provider configured for this registry, use it.
Some(RegistryConfig {
credential_provider: Some(provider),
token,
secret_key,
..
- }) if allow_cred_proc => {
+ }) => {
+ let provider = resolve_credential_alias(config, provider);
if let Some(token) = token {
- config.shell().warn(format!(
- "{sid} has a token configured in {} that will be ignored \
- because a credential-provider is configured for this registry`",
- token.definition
- ))?;
+ if provider[0] != "cargo:token" {
+ warn(format!(
+ "{sid} has a token configured in {} that will be ignored \
+ because this registry is configured to use credential-provider `{}`",
+ token.definition, provider[0],
+ ))?;
+ }
}
if let Some(secret_key) = secret_key {
- config.shell().warn(format!(
- "{sid} has a secret-key configured in {} that will be ignored \
- because a credential-provider is configured for this registry`",
- secret_key.definition
- ))?;
+ if provider[0] != "cargo:paseto" {
+ warn(format!(
+ "{sid} has a secret-key configured in {} that will be ignored \
+ because this registry is configured to use credential-provider `{}`",
+ secret_key.definition, provider[0],
+ ))?;
+ }
}
- vec![resolve_credential_alias(config, provider)]
+ return Ok(vec![provider]);
}
// Warning for both `token` and `secret-key`, stating which will be ignored
@@ -131,7 +150,7 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<S
token: Some(token),
secret_key: Some(secret_key),
..
- }) if allow_cred_proc => {
+ }) if config.cli_unstable().asymmetric_token => {
let token_pos = global_providers
.iter()
.position(|p| p.first().map(String::as_str) == Some("cargo:token"));
@@ -141,14 +160,14 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<S
match (token_pos, paseto_pos) {
(Some(token_pos), Some(paseto_pos)) => {
if token_pos < paseto_pos {
- config.shell().warn(format!(
+ warn(format!(
"{sid} has a `secret_key` configured in {} that will be ignored \
because a `token` is also configured, and the `cargo:token` provider is \
configured with higher precedence",
secret_key.definition
))?;
} else {
- config.shell().warn(format!("{sid} has a `token` configured in {} that will be ignored \
+ warn(format!("{sid} has a `token` configured in {} that will be ignored \
because a `secret_key` is also configured, and the `cargo:paseto` provider is \
configured with higher precedence", token.definition))?;
}
@@ -157,7 +176,6 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<S
// One or both of the below individual warnings will trigger
}
}
- global_providers
}
// Check if a `token` is configured that will be ignored.
@@ -168,39 +186,44 @@ fn credential_provider(config: &Config, sid: &SourceId) -> CargoResult<Vec<Vec<S
.iter()
.any(|p| p.first().map(String::as_str) == Some("cargo:token"))
{
- config.shell().warn(format!(
+ warn(format!(
"{sid} has a token configured in {} that will be ignored \
because the `cargo:token` credential provider is not listed in \
`registry.global-credential-providers`",
token.definition
))?;
}
- global_providers
}
// Check if a asymmetric token is configured that will be ignored.
Some(RegistryConfig {
secret_key: Some(token),
..
- }) if allow_cred_proc => {
+ }) if config.cli_unstable().asymmetric_token => {
if !global_providers
.iter()
.any(|p| p.first().map(String::as_str) == Some("cargo:paseto"))
{
- config.shell().warn(format!(
+ warn(format!(
"{sid} has a secret-key configured in {} that will be ignored \
because the `cargo:paseto` credential provider is not listed in \
`registry.global-credential-providers`",
token.definition
))?;
}
- global_providers
}
// If we couldn't find a registry-specific provider, use the fallback provider list.
- None | Some(RegistryConfig { .. }) => global_providers,
+ None | Some(RegistryConfig { .. }) => {}
};
- Ok(providers)
+ if !global_provider_defined && require_cred_provider_config {
+ bail!(
+ "authenticated registries require a credential-provider to be configured\n\
+ see {} for details",
+ cargo_docs_link("reference/registry-authentication.html")
+ );
+ }
+ Ok(global_providers)
}
/// Get the credential configuration for a `SourceId`.
@@ -319,10 +342,19 @@ fn registry_credential_config_raw_uncached(
/// Use the `[credential-alias]` table to see if the provider name has been aliased.
fn resolve_credential_alias(config: &Config, mut provider: PathAndArgs) -> Vec<String> {
if provider.args.is_empty() {
- let key = format!("credential-alias.{}", provider.path.raw_value());
- if let Ok(alias) = config.get::<PathAndArgs>(&key) {
+ let name = provider.path.raw_value();
+ let key = format!("credential-alias.{name}");
+ if let Ok(alias) = config.get::<Value<PathAndArgs>>(&key) {
tracing::debug!("resolving credential alias '{key}' -> '{alias:?}'");
- provider = alias;
+ if BUILT_IN_PROVIDERS.contains(&name) {
+ let _ = config.shell().warn(format!(
+ "credential-alias `{name}` (defined in `{}`) will be \
+ ignored because it would shadow a built-in credential-provider",
+ alias.definition
+ ));
+ } else {
+ provider = alias.val;
+ }
}
}
provider.args.insert(
@@ -356,14 +388,40 @@ impl fmt::Display for AuthorizationErrorReason {
#[derive(Debug)]
pub struct AuthorizationError {
/// Url that was attempted
- pub sid: SourceId,
+ sid: SourceId,
/// The `registry.default` config value.
- pub default_registry: Option<String>,
+ default_registry: Option<String>,
/// Url where the user could log in.
pub login_url: Option<Url>,
/// Specific reason indicating what failed
- pub reason: AuthorizationErrorReason,
+ reason: AuthorizationErrorReason,
+ /// Should the _TOKEN environment variable name be included when displaying this error?
+ display_token_env_help: bool,
}
+
+impl AuthorizationError {
+ pub fn new(
+ config: &Config,
+ sid: SourceId,
+ login_url: Option<Url>,
+ reason: AuthorizationErrorReason,
+ ) -> CargoResult<Self> {
+ // Only display the _TOKEN environment variable suggestion if the `cargo:token` credential
+ // provider is available for the source. Otherwise setting the environment variable will
+ // have no effect.
+ let display_token_env_help = credential_provider(config, &sid, false, false)?
+ .iter()
+ .any(|p| p.first().map(String::as_str) == Some("cargo:token"));
+ Ok(AuthorizationError {
+ sid,
+ default_registry: config.default_registry()?,
+ login_url,
+ reason,
+ display_token_env_help,
+ })
+ }
+}
+
impl Error for AuthorizationError {}
impl fmt::Display for AuthorizationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -373,20 +431,23 @@ impl fmt::Display for AuthorizationError {
} else {
""
};
- write!(
- f,
- "{}, please run `cargo login{args}`\nor use environment variable CARGO_REGISTRY_TOKEN",
- self.reason
- )
+ write!(f, "{}, please run `cargo login{args}`", self.reason)?;
+ if self.display_token_env_help {
+ write!(f, "\nor use environment variable CARGO_REGISTRY_TOKEN")?;
+ }
+ Ok(())
} else if let Some(name) = self.sid.alt_registry_key() {
let key = ConfigKey::from_str(&format!("registries.{name}.token"));
write!(
f,
- "{} for `{}`, please run `cargo login --registry {name}`\nor use environment variable {}",
+ "{} for `{}`, please run `cargo login --registry {name}`",
self.reason,
self.sid.display_registry_name(),
- key.as_env_key(),
- )
+ )?;
+ if self.display_token_env_help {
+ write!(f, "\nor use environment variable {}", key.as_env_key())?;
+ }
+ Ok(())
} else if self.reason == AuthorizationErrorReason::TokenMissing {
write!(
f,
@@ -412,7 +473,7 @@ my-registry = {{ index = "{}" }}
}
}
-// Store a token in the cache for future calls.
+/// Store a token in the cache for future calls.
pub fn cache_token_from_commandline(config: &Config, sid: &SourceId, token: Secret<&str>) {
let url = sid.canonical_url();
config.credential_cache().insert(
@@ -425,36 +486,48 @@ pub fn cache_token_from_commandline(config: &Config, sid: &SourceId, token: Secr
);
}
+/// List of credential providers built-in to Cargo.
+/// Keep in sync with the `match` in `credential_action`.
+static BUILT_IN_PROVIDERS: &[&'static str] = &[
+ "cargo:token",
+ "cargo:paseto",
+ "cargo:token-from-stdout",
+ "cargo:wincred",
+ "cargo:macos-keychain",
+ "cargo:libsecret",
+];
+
fn credential_action(
config: &Config,
sid: &SourceId,
action: Action<'_>,
headers: Vec<String>,
args: &[&str],
+ require_cred_provider_config: bool,
) -> CargoResult<CredentialResponse> {
- let name = if sid.is_crates_io() {
- Some(CRATES_IO_REGISTRY)
- } else {
- sid.alt_registry_key()
- };
+ let name = sid.alt_registry_key();
let registry = RegistryInfo {
index_url: sid.url().as_str(),
name,
headers,
};
- let providers = credential_provider(config, sid)?;
+ let providers = credential_provider(config, sid, require_cred_provider_config, true)?;
let mut any_not_found = false;
for provider in providers {
let args: Vec<&str> = provider
.iter()
.map(String::as_str)
- .chain(args.iter().map(|s| *s))
+ .chain(args.iter().copied())
.collect();
let process = args[0];
tracing::debug!("attempting credential provider: {args:?}");
+ // If the available built-in providers are changed, update the `BUILT_IN_PROVIDERS` list.
let provider: Box<dyn Credential> = match process {
"cargo:token" => Box::new(TokenCredential::new(config)),
- "cargo:paseto" => Box::new(PasetoCredential::new(config)),
+ "cargo:paseto" if config.cli_unstable().asymmetric_token => {
+ Box::new(PasetoCredential::new(config))
+ }
+ "cargo:paseto" => bail!("cargo:paseto requires -Zasymmetric-token"),
"cargo:token-from-stdout" => Box::new(BasicProcessCredential {}),
"cargo:wincred" => Box::new(cargo_credential_wincred::WindowsCredential {}),
"cargo:macos-keychain" => Box::new(cargo_credential_macos_keychain::MacKeychain {}),
@@ -501,15 +574,22 @@ pub fn auth_token(
login_url: Option<&Url>,
operation: Operation<'_>,
headers: Vec<String>,
+ require_cred_provider_config: bool,
) -> CargoResult<String> {
- match auth_token_optional(config, sid, operation, headers)? {
+ match auth_token_optional(
+ config,
+ sid,
+ operation,
+ headers,
+ require_cred_provider_config,
+ )? {
Some(token) => Ok(token.expose()),
- None => Err(AuthorizationError {
- sid: sid.clone(),
- default_registry: config.default_registry()?,
- login_url: login_url.cloned(),
- reason: AuthorizationErrorReason::TokenMissing,
- }
+ None => Err(AuthorizationError::new(
+ config,
+ *sid,
+ login_url.cloned(),
+ AuthorizationErrorReason::TokenMissing,
+ )?
.into()),
}
}
@@ -520,6 +600,7 @@ fn auth_token_optional(
sid: &SourceId,
operation: Operation<'_>,
headers: Vec<String>,
+ require_cred_provider_config: bool,
) -> CargoResult<Option<Secret<String>>> {
tracing::trace!("token requested for {}", sid.display_registry_name());
let mut cache = config.credential_cache();
@@ -540,7 +621,14 @@ fn auth_token_optional(
}
}
- let credential_response = credential_action(config, sid, Action::Get(operation), headers, &[]);
+ let credential_response = credential_action(
+ config,
+ sid,
+ Action::Get(operation),
+ headers,
+ &[],
+ require_cred_provider_config,
+ );
if let Some(e) = credential_response.as_ref().err() {
if let Some(e) = e.downcast_ref::<cargo_credential::Error>() {
if matches!(e, cargo_credential::Error::NotFound) {
@@ -561,7 +649,7 @@ fn auth_token_optional(
let token = Secret::from(token);
tracing::trace!("found token");
let expiration = match cache_control {
- CacheControl::Expires(expiration) => Some(expiration),
+ CacheControl::Expires { expiration } => Some(expiration),
CacheControl::Session => None,
CacheControl::Never | _ => return Ok(Some(token)),
};
@@ -579,7 +667,7 @@ fn auth_token_optional(
/// Log out from the given registry.
pub fn logout(config: &Config, sid: &SourceId) -> CargoResult<()> {
- let credential_response = credential_action(config, sid, Action::Logout, vec![], &[]);
+ let credential_response = credential_action(config, sid, Action::Logout, vec![], &[], false);
if let Some(e) = credential_response.as_ref().err() {
if let Some(e) = e.downcast_ref::<cargo_credential::Error>() {
if matches!(e, cargo_credential::Error::NotFound) {
@@ -608,7 +696,8 @@ pub fn login(
options: LoginOptions<'_>,
args: &[&str],
) -> CargoResult<()> {
- let credential_response = credential_action(config, sid, Action::Login(options), vec![], args)?;
+ let credential_response =
+ credential_action(config, sid, Action::Login(options), vec![], args, false)?;
let CredentialResponse::Login = credential_response else {
bail!("credential provider produced unexpected response for `login` request: {credential_response:?}")
};
diff --git a/src/tools/cargo/src/cargo/util/command_prelude.rs b/src/tools/cargo/src/cargo/util/command_prelude.rs
index bc707ef6f..bd8889bef 100644
--- a/src/tools/cargo/src/cargo/util/command_prelude.rs
+++ b/src/tools/cargo/src/cargo/util/command_prelude.rs
@@ -1,9 +1,11 @@
use crate::core::compiler::{BuildConfig, MessageFormat, TimingOutput};
use crate::core::resolver::CliFeatures;
use crate::core::{Edition, Workspace};
+use crate::ops::registry::RegistryOrIndex;
use crate::ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl};
use crate::util::important_paths::find_root_manifest_for_wd;
use crate::util::interning::InternedString;
+use crate::util::is_rustup;
use crate::util::restricted_names::is_glob_pattern;
use crate::util::toml::{StringOrVec, TomlProfile};
use crate::util::validate_package_name;
@@ -14,6 +16,7 @@ use crate::util::{
use crate::CargoResult;
use anyhow::bail;
use cargo_util::paths;
+use clap::builder::UnknownArgumentValueParser;
use std::ffi::{OsStr, OsString};
use std::path::Path;
use std::path::PathBuf;
@@ -25,6 +28,7 @@ pub use clap::{value_parser, Arg, ArgAction, ArgMatches};
pub use clap::Command;
use super::config::JobsConfig;
+use super::IntoUrl;
pub mod heading {
pub const PACKAGE_SELECTION: &str = "Package Selection";
@@ -82,17 +86,17 @@ pub trait CommandExt: Sized {
)
}
- fn arg_jobs(self) -> Self {
- self.arg_jobs_without_keep_going()._arg(
+ fn arg_parallel(self) -> Self {
+ self.arg_jobs()._arg(
flag(
"keep-going",
- "Do not abort the build as soon as there is an error (unstable)",
+ "Do not abort the build as soon as there is an error",
)
.help_heading(heading::COMPILATION_OPTIONS),
)
}
- fn arg_jobs_without_keep_going(self) -> Self {
+ fn arg_jobs(self) -> Self {
self._arg(
opt("jobs", "Number of parallel jobs, defaults to # of CPUs.")
.short('j')
@@ -102,6 +106,23 @@ pub trait CommandExt: Sized {
)
}
+ fn arg_unsupported_keep_going(self) -> Self {
+ let msg = "use `--no-fail-fast` to run as many tests as possible regardless of failure";
+ let value_parser = UnknownArgumentValueParser::suggest(msg);
+ self._arg(flag("keep-going", "").value_parser(value_parser).hide(true))
+ }
+
+ fn arg_redundant_default_mode(
+ self,
+ default_mode: &'static str,
+ command: &'static str,
+ supported_mode: &'static str,
+ ) -> Self {
+ let msg = format!("`--{default_mode}` is the default for `cargo {command}`; instead `--{supported_mode}` is supported");
+ let value_parser = UnknownArgumentValueParser::suggest(msg);
+ self._arg(flag(default_mode, "").value_parser(value_parser).hide(true))
+ }
+
fn arg_targets_all(
self,
lib: &'static str,
@@ -211,7 +232,10 @@ pub trait CommandExt: Sized {
}
fn arg_target_triple(self, target: &'static str) -> Self {
- self._arg(multi_opt("target", "TRIPLE", target).help_heading(heading::COMPILATION_OPTIONS))
+ self._arg(
+ optional_multi_opt("target", "TRIPLE", target)
+ .help_heading(heading::COMPILATION_OPTIONS),
+ )
}
fn arg_target_dir(self) -> Self {
@@ -253,8 +277,7 @@ pub trait CommandExt: Sized {
opt(
"vcs",
"Initialize a new repository for the given version \
- control system (git, hg, pijul, or fossil) or do not \
- initialize any version control at all (none), overriding \
+ control system, overriding \
a global configuration.",
)
.value_name("VCS")
@@ -276,12 +299,21 @@ pub trait CommandExt: Sized {
)
}
- fn arg_index(self) -> Self {
- self._arg(opt("index", "Registry index URL to upload the package to").value_name("INDEX"))
+ fn arg_registry(self, help: &'static str) -> Self {
+ self._arg(opt("registry", help).value_name("REGISTRY"))
+ }
+
+ fn arg_index(self, help: &'static str) -> Self {
+ // Always conflicts with `--registry`.
+ self._arg(
+ opt("index", help)
+ .value_name("INDEX")
+ .conflicts_with("registry"),
+ )
}
fn arg_dry_run(self, dry_run: &'static str) -> Self {
- self._arg(flag("dry-run", dry_run))
+ self._arg(flag("dry-run", dry_run).short('n'))
}
fn arg_ignore_rust_version(self) -> Self {
@@ -299,6 +331,18 @@ pub trait CommandExt: Sized {
}
fn arg_quiet(self) -> Self {
+ let unsupported_silent_arg = {
+ let value_parser = UnknownArgumentValueParser::suggest_arg("--quiet");
+ flag("silent", "")
+ .short('s')
+ .value_parser(value_parser)
+ .hide(true)
+ };
+ self._arg(flag("quiet", "Do not print cargo log messages").short('q'))
+ ._arg(unsupported_silent_arg)
+ }
+
+ fn arg_quiet_without_unknown_silent_arg_tip(self) -> Self {
self._arg(flag("quiet", "Do not print cargo log messages").short('q'))
}
@@ -431,11 +475,23 @@ pub trait ArgMatchesExt {
}
fn keep_going(&self) -> bool {
- self.flag("keep-going")
+ self.maybe_flag("keep-going")
}
- fn targets(&self) -> Vec<String> {
- self._values_of("target")
+ fn targets(&self) -> CargoResult<Vec<String>> {
+ if self.is_present_with_zero_values("target") {
+ let cmd = if is_rustup() {
+ "rustup target list"
+ } else {
+ "rustc --print target-list"
+ };
+ bail!(
+ "\"--target\" takes a target architecture as an argument.
+
+Run `{cmd}` to see possible targets."
+ );
+ }
+ Ok(self._values_of("target"))
}
fn get_profile_name(
@@ -453,7 +509,7 @@ pub trait ArgMatchesExt {
(Some(name @ ("dev" | "test" | "bench" | "check")), ProfileChecking::LegacyRustc)
// `cargo fix` and `cargo check` has legacy handling of this profile name
| (Some(name @ "test"), ProfileChecking::LegacyTestOnly) => {
- if self.flag("release") {
+ if self.maybe_flag("release") {
config.shell().warn(
"the `--release` flag should not be specified with the `--profile` flag\n\
The `--release` flag will be ignored.\n\
@@ -477,7 +533,11 @@ pub trait ArgMatchesExt {
)
};
- let name = match (self.flag("release"), self.flag("debug"), specified_profile) {
+ let name = match (
+ self.maybe_flag("release"),
+ self.maybe_flag("debug"),
+ specified_profile,
+ ) {
(false, false, None) => default,
(true, _, None | Some("release")) => "release",
(true, _, Some(name)) => return Err(conflict("release", "release", name)),
@@ -584,7 +644,7 @@ pub trait ArgMatchesExt {
config,
self.jobs()?,
self.keep_going(),
- &self.targets(),
+ &self.targets()?,
mode,
)?;
build_config.message_format = message_format.unwrap_or(MessageFormat::Human);
@@ -620,11 +680,6 @@ pub trait ArgMatchesExt {
}
}
- if build_config.keep_going {
- config
- .cli_unstable()
- .fail_if_stable_opt("--keep-going", 10496)?;
- }
if build_config.build_plan {
config
.cli_unstable()
@@ -718,29 +773,32 @@ pub trait ArgMatchesExt {
)
}
- fn registry(&self, config: &Config) -> CargoResult<Option<String>> {
+ fn registry_or_index(&self, config: &Config) -> CargoResult<Option<RegistryOrIndex>> {
let registry = self._value_of("registry");
let index = self._value_of("index");
let result = match (registry, index) {
- (None, None) => config.default_registry()?,
- (None, Some(_)) => {
- // If --index is set, then do not look at registry.default.
- None
- }
+ (None, None) => config.default_registry()?.map(RegistryOrIndex::Registry),
+ (None, Some(i)) => Some(RegistryOrIndex::Index(i.into_url()?)),
(Some(r), None) => {
validate_package_name(r, "registry name", "")?;
- Some(r.to_string())
+ Some(RegistryOrIndex::Registry(r.to_string()))
}
(Some(_), Some(_)) => {
- bail!("both `--index` and `--registry` should not be set at the same time")
+ // Should be guarded by clap
+ unreachable!("both `--index` and `--registry` should not be set at the same time")
}
};
Ok(result)
}
- fn index(&self) -> CargoResult<Option<String>> {
- let index = self._value_of("index").map(|s| s.to_string());
- Ok(index)
+ fn registry(&self, config: &Config) -> CargoResult<Option<String>> {
+ match self._value_of("registry").map(|s| s.to_string()) {
+ None => config.default_registry(),
+ Some(registry) => {
+ validate_package_name(&registry, "registry name", "")?;
+ Ok(Some(registry))
+ }
+ }
}
fn check_optional_opts(
@@ -777,6 +835,8 @@ pub trait ArgMatchesExt {
fn flag(&self, name: &str) -> bool;
+ fn maybe_flag(&self, name: &str) -> bool;
+
fn _value_of(&self, name: &str) -> Option<&str>;
fn _values_of(&self, name: &str) -> Vec<String>;
@@ -797,6 +857,17 @@ impl<'a> ArgMatchesExt for ArgMatches {
.unwrap_or(false)
}
+ // This works around before an upstream fix in clap for `UnknownArgumentValueParser` accepting
+ // generics arguments. `flag()` cannot be used with `--keep-going` at this moment due to
+ // <https://github.com/clap-rs/clap/issues/5081>.
+ fn maybe_flag(&self, name: &str) -> bool {
+ self.try_get_one::<bool>(name)
+ .ok()
+ .flatten()
+ .copied()
+ .unwrap_or_default()
+ }
+
fn _value_of(&self, name: &str) -> Option<&str> {
ignore_unknown(self.try_get_one::<String>(name)).map(String::as_str)
}
diff --git a/src/tools/cargo/src/cargo/util/config/de.rs b/src/tools/cargo/src/cargo/util/config/de.rs
index a9147ab03..e12a2d0b0 100644
--- a/src/tools/cargo/src/cargo/util/config/de.rs
+++ b/src/tools/cargo/src/cargo/util/config/de.rs
@@ -216,9 +216,8 @@ impl<'config> ConfigMapAccess<'config> {
// `CARGO_PROFILE_DEV_PACKAGE_`
let env_prefix = format!("{}_", de.key.as_env_key());
for env_key in de.config.env_keys() {
- if env_key.starts_with(&env_prefix) {
- // `CARGO_PROFILE_DEV_PACKAGE_bar_OPT_LEVEL = 3`
- let rest = &env_key[env_prefix.len()..];
+ // `CARGO_PROFILE_DEV_PACKAGE_bar_OPT_LEVEL = 3`
+ if let Some(rest) = env_key.strip_prefix(&env_prefix) {
// `rest = bar_OPT_LEVEL`
let part = rest.splitn(2, '_').next().unwrap();
// `part = "bar"`
diff --git a/src/tools/cargo/src/cargo/util/config/key.rs b/src/tools/cargo/src/cargo/util/config/key.rs
index 228d85844..cd1901140 100644
--- a/src/tools/cargo/src/cargo/util/config/key.rs
+++ b/src/tools/cargo/src/cargo/util/config/key.rs
@@ -49,7 +49,7 @@ impl ConfigKey {
/// equivalent to accessing a sub-table in TOML.
///
/// Note that this considers `name` to be case-insensitive, meaning that the
- /// corrseponding toml key is appended with this `name` as-is and the
+ /// corresponding toml key is appended with this `name` as-is and the
/// corresponding env key is appended with `name` after transforming it to
/// uppercase characters.
pub fn push(&mut self, name: &str) {
diff --git a/src/tools/cargo/src/cargo/util/config/mod.rs b/src/tools/cargo/src/cargo/util/config/mod.rs
index cf977d38d..b87f98afd 100644
--- a/src/tools/cargo/src/cargo/util/config/mod.rs
+++ b/src/tools/cargo/src/cargo/util/config/mod.rs
@@ -70,6 +70,8 @@ use crate::core::compiler::rustdoc::RustdocExternMap;
use crate::core::shell::Verbosity;
use crate::core::{features, CliUnstable, Shell, SourceId, Workspace, WorkspaceRootConfig};
use crate::ops::RegistryCredentialConfig;
+use crate::sources::CRATES_IO_INDEX;
+use crate::sources::CRATES_IO_REGISTRY;
use crate::util::errors::CargoResult;
use crate::util::network::http::configure_http_handle;
use crate::util::network::http::http_handle;
@@ -84,6 +86,7 @@ use curl::easy::Easy;
use lazycell::LazyCell;
use serde::de::IntoDeserializer as _;
use serde::Deserialize;
+use serde_untagged::UntaggedEnumVisitor;
use time::OffsetDateTime;
use toml_edit::Item;
use url::Url;
@@ -621,9 +624,8 @@ impl Config {
)));
}
let mut parts = key.parts().enumerate();
- let mut val = match vals.get(parts.next().unwrap().1) {
- Some(val) => val,
- None => return Ok(None),
+ let Some(mut val) = vals.get(parts.next().unwrap().1) else {
+ return Ok(None);
};
for (i, part) in parts {
match val {
@@ -905,12 +907,9 @@ impl Config {
key: &ConfigKey,
output: &mut Vec<(String, Definition)>,
) -> CargoResult<()> {
- let env_val = match self.env.get_str(key.as_env_key()) {
- Some(v) => v,
- None => {
- self.check_environment_key_case_mismatch(key);
- return Ok(());
- }
+ let Some(env_val) = self.env.get_str(key.as_env_key()) else {
+ self.check_environment_key_case_mismatch(key);
+ return Ok(());
};
let def = Definition::Environment(key.as_env_key().to_string());
@@ -938,6 +937,7 @@ impl Config {
.map(|s| (s.to_string(), def.clone())),
);
}
+ output.sort_by(|a, b| a.1.cmp(&b.1));
Ok(())
}
@@ -1259,9 +1259,8 @@ impl Config {
};
(path.to_string(), abs_path, def.clone())
};
- let table = match cv {
- CV::Table(table, _def) => table,
- _ => unreachable!(),
+ let CV::Table(table, _def) = cv else {
+ unreachable!()
};
let owned;
let include = if remove {
@@ -1300,9 +1299,8 @@ impl Config {
/// Parses the CLI config args and returns them as a table.
pub(crate) fn cli_args_as_table(&self) -> CargoResult<ConfigValue> {
let mut loaded_args = CV::Table(HashMap::new(), Definition::Cli(None));
- let cli_args = match &self.cli_config {
- Some(cli_args) => cli_args,
- None => return Ok(loaded_args),
+ let Some(cli_args) = &self.cli_config else {
+ return Ok(loaded_args);
};
let mut seen = HashSet::new();
for arg in cli_args {
@@ -1448,9 +1446,8 @@ impl Config {
/// Add config arguments passed on the command line.
fn merge_cli_args(&mut self) -> CargoResult<()> {
- let loaded_map = match self.cli_args_as_table()? {
- CV::Table(table, _def) => table,
- _ => unreachable!(),
+ let CV::Table(loaded_map, _def) = self.cli_args_as_table()? else {
+ unreachable!()
};
let values = self.values_mut()?;
for (key, value) in loaded_map.into_iter() {
@@ -1551,7 +1548,10 @@ impl Config {
)
})
} else {
- bail!("no index found for registry: `{}`", registry);
+ bail!(
+ "registry index was not found in any configuration: `{}`",
+ registry
+ );
}
}
@@ -1594,17 +1594,15 @@ impl Config {
}
let home_path = self.home_path.clone().into_path_unlocked();
- let credentials = match self.get_file_path(&home_path, "credentials", true)? {
- Some(credentials) => credentials,
- None => return Ok(()),
+ let Some(credentials) = self.get_file_path(&home_path, "credentials", true)? else {
+ return Ok(());
};
let mut value = self.load_file(&credentials)?;
// Backwards compatibility for old `.cargo/credentials` layout.
{
- let (value_map, def) = match value {
- CV::Table(ref mut value, ref def) => (value, def),
- _ => unreachable!(),
+ let CV::Table(ref mut value_map, ref def) = value else {
+ unreachable!();
};
if let Some(token) = value_map.remove("token") {
@@ -1838,11 +1836,17 @@ impl Config {
target::load_target_triple(self, target)
}
- pub fn crates_io_source_id<F>(&self, f: F) -> CargoResult<SourceId>
- where
- F: FnMut() -> CargoResult<SourceId>,
- {
- Ok(*(self.crates_io_source_id.try_borrow_with(f)?))
+ /// Returns the cached [`SourceId`] corresponding to the main repository.
+ ///
+ /// This is the main cargo registry by default, but it can be overridden in
+ /// a `.cargo/config.toml`.
+ pub fn crates_io_source_id(&self) -> CargoResult<SourceId> {
+ let source_id = self.crates_io_source_id.try_borrow_with(|| {
+ self.check_registry_index_not_set()?;
+ let url = CRATES_IO_INDEX.into_url().unwrap();
+ SourceId::for_alt_registry(&url, CRATES_IO_REGISTRY)
+ })?;
+ Ok(*source_id)
}
pub fn creation_time(&self) -> Instant {
@@ -2106,8 +2110,8 @@ impl ConfigValue {
/// Merge the given value into self.
///
- /// If `force` is true, primitive (non-container) types will override existing values.
- /// If false, the original will be kept and the new value ignored.
+ /// If `force` is true, primitive (non-container) types will override existing values
+ /// of equal priority. For arrays, incoming values of equal priority will be placed later.
///
/// Container types (tables and arrays) are merged with existing values.
///
@@ -2115,7 +2119,13 @@ impl ConfigValue {
fn merge(&mut self, from: ConfigValue, force: bool) -> CargoResult<()> {
match (self, from) {
(&mut CV::List(ref mut old, _), CV::List(ref mut new, _)) => {
- old.extend(mem::take(new).into_iter());
+ if force {
+ old.append(new);
+ } else {
+ new.append(old);
+ mem::swap(new, old);
+ }
+ old.sort_by(|a, b| a.1.cmp(&b.1));
}
(&mut CV::Table(ref mut old, _), CV::Table(ref mut new, _)) => {
for (key, value) in mem::take(new) {
@@ -2446,13 +2456,24 @@ impl CargoFutureIncompatConfig {
/// ssl-version.min = "tlsv1.2"
/// ssl-version.max = "tlsv1.3"
/// ```
-#[derive(Clone, Debug, Deserialize, PartialEq)]
-#[serde(untagged)]
+#[derive(Clone, Debug, PartialEq)]
pub enum SslVersionConfig {
Single(String),
Range(SslVersionConfigRange),
}
+impl<'de> Deserialize<'de> for SslVersionConfig {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ UntaggedEnumVisitor::new()
+ .string(|single| Ok(SslVersionConfig::Single(single.to_owned())))
+ .map(|map| map.deserialize().map(SslVersionConfig::Range))
+ .deserialize(deserializer)
+ }
+}
+
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct SslVersionConfigRange {
pub min: Option<String>,
@@ -2486,13 +2507,24 @@ pub struct CargoSshConfig {
/// [build]
/// jobs = "default" # Currently only support "default".
/// ```
-#[derive(Debug, Deserialize, Clone)]
-#[serde(untagged)]
+#[derive(Debug, Clone)]
pub enum JobsConfig {
Integer(i32),
String(String),
}
+impl<'de> Deserialize<'de> for JobsConfig {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ UntaggedEnumVisitor::new()
+ .i32(|int| Ok(JobsConfig::Integer(int)))
+ .string(|string| Ok(JobsConfig::String(string.to_owned())))
+ .deserialize(deserializer)
+ }
+}
+
#[derive(Debug, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct CargoBuildConfig {
@@ -2527,13 +2559,24 @@ pub struct BuildTargetConfig {
inner: Value<BuildTargetConfigInner>,
}
-#[derive(Debug, Deserialize)]
-#[serde(untagged)]
+#[derive(Debug)]
enum BuildTargetConfigInner {
One(String),
Many(Vec<String>),
}
+impl<'de> Deserialize<'de> for BuildTargetConfigInner {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ UntaggedEnumVisitor::new()
+ .string(|one| Ok(BuildTargetConfigInner::One(one.to_owned())))
+ .seq(|many| many.deserialize().map(BuildTargetConfigInner::Many))
+ .deserialize(deserializer)
+ }
+}
+
impl BuildTargetConfig {
/// Gets values of `build.target` as a list of strings.
pub fn values(&self, config: &Config) -> CargoResult<Vec<String>> {
@@ -2645,19 +2688,44 @@ where
deserializer.deserialize_option(ProgressVisitor)
}
-#[derive(Debug, Deserialize)]
-#[serde(untagged)]
+#[derive(Debug)]
enum EnvConfigValueInner {
Simple(String),
WithOptions {
value: String,
- #[serde(default)]
force: bool,
- #[serde(default)]
relative: bool,
},
}
+impl<'de> Deserialize<'de> for EnvConfigValueInner {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ #[derive(Deserialize)]
+ struct WithOptions {
+ value: String,
+ #[serde(default)]
+ force: bool,
+ #[serde(default)]
+ relative: bool,
+ }
+
+ UntaggedEnumVisitor::new()
+ .string(|simple| Ok(EnvConfigValueInner::Simple(simple.to_owned())))
+ .map(|map| {
+ let with_options: WithOptions = map.deserialize()?;
+ Ok(EnvConfigValueInner::WithOptions {
+ value: with_options.value,
+ force: with_options.force,
+ relative: with_options.relative,
+ })
+ })
+ .deserialize(deserializer)
+ }
+}
+
#[derive(Debug, Deserialize)]
#[serde(transparent)]
pub struct EnvConfigValue {
diff --git a/src/tools/cargo/src/cargo/util/config/target.rs b/src/tools/cargo/src/cargo/util/config/target.rs
index b8aaf906d..6d6a6beff 100644
--- a/src/tools/cargo/src/cargo/util/config/target.rs
+++ b/src/tools/cargo/src/cargo/util/config/target.rs
@@ -12,6 +12,7 @@ use std::path::PathBuf;
pub struct TargetCfgConfig {
pub runner: OptValue<PathAndArgs>,
pub rustflags: OptValue<StringList>,
+ pub linker: OptValue<ConfigRelativePath>,
// This is here just to ignore fields from normal `TargetConfig` because
// all `[target]` tables are getting deserialized, whether they start with
// `cfg(` or not.
diff --git a/src/tools/cargo/src/cargo/util/config/value.rs b/src/tools/cargo/src/cargo/util/config/value.rs
index a70d75a07..7232bf39e 100644
--- a/src/tools/cargo/src/cargo/util/config/value.rs
+++ b/src/tools/cargo/src/cargo/util/config/value.rs
@@ -10,6 +10,7 @@
use crate::util::config::Config;
use serde::de;
+use std::cmp::Ordering;
use std::fmt;
use std::marker;
use std::mem;
@@ -63,6 +64,24 @@ pub enum Definition {
Cli(Option<PathBuf>),
}
+impl PartialOrd for Definition {
+ fn partial_cmp(&self, other: &Definition) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Definition {
+ fn cmp(&self, other: &Definition) -> Ordering {
+ if mem::discriminant(self) == mem::discriminant(other) {
+ Ordering::Equal
+ } else if self.is_higher_priority(other) {
+ Ordering::Greater
+ } else {
+ Ordering::Less
+ }
+ }
+}
+
impl Definition {
/// Root directory where this is defined.
///
diff --git a/src/tools/cargo/src/cargo/util/credential/paseto.rs b/src/tools/cargo/src/cargo/util/credential/paseto.rs
index 329d1f11c..bd49af98a 100644
--- a/src/tools/cargo/src/cargo/util/credential/paseto.rs
+++ b/src/tools/cargo/src/cargo/util/credential/paseto.rs
@@ -200,8 +200,17 @@ impl<'a> Credential for PasetoCredential<'a> {
Ok(CredentialResponse::Login)
}
Action::Logout => {
- config::save_credentials(self.config, None, &sid)?;
- Ok(CredentialResponse::Logout)
+ if reg_cfg.and_then(|c| c.secret_key).is_some() {
+ config::save_credentials(self.config, None, &sid)?;
+ let reg_name = sid.display_registry_name();
+ let _ = self.config.shell().status(
+ "Logout",
+ format!("secret-key for `{reg_name}` has been removed from local storage"),
+ );
+ Ok(CredentialResponse::Logout)
+ } else {
+ Err(Error::NotFound)
+ }
}
_ => Err(Error::OperationNotSupported),
}
diff --git a/src/tools/cargo/src/cargo/util/credential/process.rs b/src/tools/cargo/src/cargo/util/credential/process.rs
index 89eac1af6..6a6a0a69e 100644
--- a/src/tools/cargo/src/cargo/util/credential/process.rs
+++ b/src/tools/cargo/src/cargo/util/credential/process.rs
@@ -4,12 +4,12 @@
use std::{
io::{BufRead, BufReader, Write},
path::PathBuf,
- process::{Command, Stdio},
+ process::{Child, Command, Stdio},
};
use anyhow::Context;
use cargo_credential::{
- Action, Credential, CredentialHello, CredentialRequest, CredentialResponse, RegistryInfo,
+ Action, Credential, CredentialHello, CredentialRequest, CredentialResponse, Error, RegistryInfo,
};
pub struct CredentialProcessCredential {
@@ -22,31 +22,38 @@ impl<'a> CredentialProcessCredential {
path: PathBuf::from(path),
}
}
-}
-impl<'a> Credential for CredentialProcessCredential {
- fn perform(
+ fn run(
&self,
- registry: &RegistryInfo<'_>,
+ child: &mut Child,
action: &Action<'_>,
+ registry: &RegistryInfo<'_>,
args: &[&str],
- ) -> Result<CredentialResponse, cargo_credential::Error> {
- let mut cmd = Command::new(&self.path);
- cmd.stdout(Stdio::piped());
- cmd.stdin(Stdio::piped());
- cmd.arg("--cargo-plugin");
- tracing::debug!("credential-process: {cmd:?}");
- let mut child = cmd.spawn().context("failed to spawn credential process")?;
+ ) -> Result<Result<CredentialResponse, Error>, Error> {
let mut output_from_child = BufReader::new(child.stdout.take().unwrap());
let mut input_to_child = child.stdin.take().unwrap();
let mut buffer = String::new();
+
+ // Read the CredentialHello
output_from_child
.read_line(&mut buffer)
.context("failed to read hello from credential provider")?;
let credential_hello: CredentialHello =
serde_json::from_str(&buffer).context("failed to deserialize hello")?;
tracing::debug!("credential-process > {credential_hello:?}");
+ if !credential_hello
+ .v
+ .contains(&cargo_credential::PROTOCOL_VERSION_1)
+ {
+ return Err(format!(
+ "credential provider supports protocol versions {:?}, while Cargo supports {:?}",
+ credential_hello.v,
+ [cargo_credential::PROTOCOL_VERSION_1]
+ )
+ .into());
+ }
+ // Send the Credential Request
let req = CredentialRequest {
v: cargo_credential::PROTOCOL_VERSION_1,
action: action.clone(),
@@ -56,14 +63,17 @@ impl<'a> Credential for CredentialProcessCredential {
let request = serde_json::to_string(&req).context("failed to serialize request")?;
tracing::debug!("credential-process < {req:?}");
writeln!(input_to_child, "{request}").context("failed to write to credential provider")?;
-
buffer.clear();
output_from_child
.read_line(&mut buffer)
.context("failed to read response from credential provider")?;
- let response: Result<CredentialResponse, cargo_credential::Error> =
+
+ // Read the Credential Response
+ let response: Result<CredentialResponse, Error> =
serde_json::from_str(&buffer).context("failed to deserialize response")?;
tracing::debug!("credential-process > {response:?}");
+
+ // Tell the credential process we're done by closing stdin. It should exit cleanly.
drop(input_to_child);
let status = child.wait().context("credential process never started")?;
if !status.success() {
@@ -75,6 +85,31 @@ impl<'a> Credential for CredentialProcessCredential {
.into());
}
tracing::trace!("credential process exited successfully");
- response
+ Ok(response)
+ }
+}
+
+impl<'a> Credential for CredentialProcessCredential {
+ fn perform(
+ &self,
+ registry: &RegistryInfo<'_>,
+ action: &Action<'_>,
+ args: &[&str],
+ ) -> Result<CredentialResponse, Error> {
+ let mut cmd = Command::new(&self.path);
+ cmd.stdout(Stdio::piped());
+ cmd.stdin(Stdio::piped());
+ cmd.arg("--cargo-plugin");
+ tracing::debug!("credential-process: {cmd:?}");
+ let mut child = cmd.spawn().context("failed to spawn credential process")?;
+ match self.run(&mut child, action, registry, args) {
+ Err(e) => {
+ // Since running the credential process itself failed, ensure the
+ // process is stopped.
+ let _ = child.kill();
+ Err(e)
+ }
+ Ok(response) => response,
+ }
}
}
diff --git a/src/tools/cargo/src/cargo/util/dependency_queue.rs b/src/tools/cargo/src/cargo/util/dependency_queue.rs
index 33e8bf28e..5650f4b25 100644
--- a/src/tools/cargo/src/cargo/util/dependency_queue.rs
+++ b/src/tools/cargo/src/cargo/util/dependency_queue.rs
@@ -181,9 +181,8 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
pub fn finish(&mut self, node: &N, edge: &E) -> Vec<&N> {
// hashset<Node>
let reverse_deps = self.reverse_dep_map.get(node).and_then(|map| map.get(edge));
- let reverse_deps = match reverse_deps {
- Some(deps) => deps,
- None => return Vec::new(),
+ let Some(reverse_deps) = reverse_deps else {
+ return Vec::new();
};
let key = (node.clone(), edge.clone());
let mut result = Vec::new();
diff --git a/src/tools/cargo/src/cargo/util/flock.rs b/src/tools/cargo/src/cargo/util/flock.rs
index 295eb1e14..aa056c965 100644
--- a/src/tools/cargo/src/cargo/util/flock.rs
+++ b/src/tools/cargo/src/cargo/util/flock.rs
@@ -4,11 +4,11 @@ use std::io::{Read, Seek, SeekFrom, Write};
use std::path::{Display, Path, PathBuf};
use crate::util::errors::CargoResult;
+use crate::util::style;
use crate::util::Config;
use anyhow::Context as _;
use cargo_util::paths;
use sys::*;
-use termcolor::Color::Cyan;
#[derive(Debug)]
pub struct FileLock {
@@ -312,7 +312,9 @@ fn acquire(
}
}
let msg = format!("waiting for file lock on {}", msg);
- config.shell().status_with_color("Blocking", &msg, Cyan)?;
+ config
+ .shell()
+ .status_with_color("Blocking", &msg, &style::NOTE)?;
lock_block().with_context(|| format!("failed to lock file: {}", path.display()))?;
return Ok(());
@@ -323,9 +325,8 @@ fn acquire(
use std::mem;
use std::os::unix::prelude::*;
- let path = match CString::new(path.as_os_str().as_bytes()) {
- Ok(path) => path,
- Err(_) => return false,
+ let Ok(path) = CString::new(path.as_os_str().as_bytes()) else {
+ return false;
};
unsafe {
diff --git a/src/tools/cargo/src/cargo/util/graph.rs b/src/tools/cargo/src/cargo/util/graph.rs
index ff4018201..8c4a593ea 100644
--- a/src/tools/cargo/src/cargo/util/graph.rs
+++ b/src/tools/cargo/src/cargo/util/graph.rs
@@ -1,5 +1,5 @@
use std::borrow::Borrow;
-use std::collections::BTreeSet;
+use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::fmt;
pub struct Graph<N: Clone, E: Clone> {
@@ -87,57 +87,107 @@ impl<N: Eq + Ord + Clone, E: Default + Clone> Graph<N, E> {
false
}
- /// Resolves one of the paths from the given dependent package down to
- /// a leaf.
+ /// Resolves one of the paths from the given dependent package down to a leaf.
+ ///
+ /// The path return will be the shortest path, or more accurately one of the paths with the shortest length.
///
/// Each element contains a node along with an edge except the first one.
/// The representation would look like:
///
/// (Node0,) -> (Node1, Edge01) -> (Node2, Edge12)...
- pub fn path_to_bottom<'a>(&'a self, mut pkg: &'a N) -> Vec<(&'a N, Option<&'a E>)> {
- let mut result = vec![(pkg, None)];
- while let Some(p) = self.nodes.get(pkg).and_then(|p| {
- p.iter()
- // Note that we can have "cycles" introduced through dev-dependency
- // edges, so make sure we don't loop infinitely.
- .find(|&(node, _)| result.iter().all(|p| p.0 != node))
- .map(|(node, edge)| (node, Some(edge)))
- }) {
- result.push(p);
- pkg = p.0;
- }
- result
+ pub fn path_to_bottom<'a>(&'a self, pkg: &'a N) -> Vec<(&'a N, Option<&'a E>)> {
+ self.path_to(pkg, |s, p| s.edges(p))
}
- /// Resolves one of the paths from the given dependent package up to
- /// the root.
+ /// Resolves one of the paths from the given dependent package up to the root.
+ ///
+ /// The path return will be the shortest path, or more accurately one of the paths with the shortest length.
///
/// Each element contains a node along with an edge except the first one.
/// The representation would look like:
///
/// (Node0,) -> (Node1, Edge01) -> (Node2, Edge12)...
- pub fn path_to_top<'a>(&'a self, mut pkg: &'a N) -> Vec<(&'a N, Option<&'a E>)> {
- // Note that this implementation isn't the most robust per se, we'll
- // likely have to tweak this over time. For now though it works for what
- // it's used for!
- let mut result = vec![(pkg, None)];
- let first_pkg_depending_on = |pkg, res: &[(&N, Option<&E>)]| {
- self.nodes
+ pub fn path_to_top<'a>(&'a self, pkg: &'a N) -> Vec<(&'a N, Option<&'a E>)> {
+ self.path_to(pkg, |s, pk| {
+ // Note that this implementation isn't the most robust per se, we'll
+ // likely have to tweak this over time. For now though it works for what
+ // it's used for!
+ s.nodes
.iter()
- .filter(|(_, adjacent)| adjacent.contains_key(pkg))
- // Note that we can have "cycles" introduced through dev-dependency
- // edges, so make sure we don't loop infinitely.
- .find(|&(node, _)| !res.iter().any(|p| p.0 == node))
- .map(|(p, adjacent)| (p, adjacent.get(pkg)))
- };
- while let Some(p) = first_pkg_depending_on(pkg, &result) {
- result.push(p);
- pkg = p.0;
+ .filter_map(|(p, adjacent)| adjacent.get(pk).map(|e| (p, e)))
+ })
+ }
+}
+
+impl<'s, N: Eq + Ord + Clone + 's, E: Default + Clone + 's> Graph<N, E> {
+ fn path_to<'a, F, I>(&'s self, pkg: &'a N, fn_edge: F) -> Vec<(&'a N, Option<&'a E>)>
+ where
+ I: Iterator<Item = (&'a N, &'a E)>,
+ F: Fn(&'s Self, &'a N) -> I,
+ 'a: 's,
+ {
+ let mut back_link = BTreeMap::new();
+ let mut queue = VecDeque::from([pkg]);
+ let mut bottom = None;
+
+ while let Some(p) = queue.pop_front() {
+ bottom = Some(p);
+ for (child, edge) in fn_edge(&self, p) {
+ bottom = None;
+ back_link.entry(child).or_insert_with(|| {
+ queue.push_back(child);
+ (p, edge)
+ });
+ }
+ if bottom.is_some() {
+ break;
+ }
+ }
+
+ let mut result = Vec::new();
+ let mut next =
+ bottom.expect("the only path was a cycle, no dependency graph has this shape");
+ while let Some((p, e)) = back_link.remove(&next) {
+ result.push((next, Some(e)));
+ next = p;
+ }
+ result.push((next, None));
+ result.reverse();
+ #[cfg(debug_assertions)]
+ {
+ for x in result.windows(2) {
+ let [(n2, _), (n1, Some(e12))] = x else {
+ unreachable!()
+ };
+ assert!(std::ptr::eq(
+ self.edge(n1, n2).or(self.edge(n2, n1)).unwrap(),
+ *e12
+ ));
+ }
+ let last = result.last().unwrap().0;
+ // fixme: this may sometimes be wrong when there are cycles.
+ if !fn_edge(&self, last).next().is_none() {
+ self.print_for_test();
+ unreachable!("The last element in the path should not have outgoing edges");
+ }
}
result
}
}
+#[test]
+fn path_to_case() {
+ let mut new = Graph::new();
+ new.link(0, 3);
+ new.link(1, 0);
+ new.link(2, 0);
+ new.link(2, 1);
+ assert_eq!(
+ new.path_to_bottom(&2),
+ vec![(&2, None), (&0, Some(&())), (&3, Some(&()))]
+ );
+}
+
impl<N: Eq + Ord + Clone, E: Default + Clone> Default for Graph<N, E> {
fn default() -> Graph<N, E> {
Graph::new()
@@ -162,6 +212,36 @@ impl<N: fmt::Display + Eq + Ord + Clone, E: Clone> fmt::Debug for Graph<N, E> {
}
}
+impl<N: Eq + Ord + Clone, E: Clone> Graph<N, E> {
+ /// Prints the graph for constructing unit tests.
+ ///
+ /// For purposes of graph traversal algorithms the edge values do not matter,
+ /// and the only value of the node we care about is the order it gets compared in.
+ /// This constructs a graph with the same topology but with integer keys and unit edges.
+ #[cfg(debug_assertions)]
+ #[allow(clippy::print_stderr)]
+ fn print_for_test(&self) {
+ // Isolate and print a test case.
+ let names = self
+ .nodes
+ .keys()
+ .chain(self.nodes.values().flat_map(|vs| vs.keys()))
+ .collect::<BTreeSet<_>>()
+ .into_iter()
+ .collect::<Vec<_>>();
+ let mut new = Graph::new();
+ for n1 in self.nodes.keys() {
+ let name1 = names.binary_search(&n1).unwrap();
+ new.add(name1);
+ for n2 in self.nodes[n1].keys() {
+ let name2 = names.binary_search(&n2).unwrap();
+ *new.link(name1, name2) = ();
+ }
+ }
+ eprintln!("Graph for tests = {new:#?}");
+ }
+}
+
impl<N: Eq + Ord + Clone, E: Eq + Clone> PartialEq for Graph<N, E> {
fn eq(&self, other: &Graph<N, E>) -> bool {
self.nodes.eq(&other.nodes)
diff --git a/src/tools/cargo/src/cargo/util/interning.rs b/src/tools/cargo/src/cargo/util/interning.rs
index 584fdf623..2e3848eaa 100644
--- a/src/tools/cargo/src/cargo/util/interning.rs
+++ b/src/tools/cargo/src/cargo/util/interning.rs
@@ -1,4 +1,5 @@
use serde::{Serialize, Serializer};
+use serde_untagged::UntaggedEnumVisitor;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::collections::HashSet;
@@ -12,10 +13,6 @@ use std::str;
use std::sync::Mutex;
use std::sync::OnceLock;
-fn leak(s: String) -> &'static str {
- Box::leak(s.into_boxed_str())
-}
-
static STRING_CACHE: OnceLock<Mutex<HashSet<&'static str>>> = OnceLock::new();
#[derive(Clone, Copy)]
@@ -63,12 +60,9 @@ impl Eq for InternedString {}
impl InternedString {
pub fn new(str: &str) -> InternedString {
- let mut cache = STRING_CACHE
- .get_or_init(|| Default::default())
- .lock()
- .unwrap();
+ let mut cache = STRING_CACHE.get_or_init(Default::default).lock().unwrap();
let s = cache.get(str).cloned().unwrap_or_else(|| {
- let s = leak(str.to_string());
+ let s = str.to_string().leak();
cache.insert(s);
s
});
@@ -157,28 +151,14 @@ impl Serialize for InternedString {
}
}
-struct InternedStringVisitor;
-
impl<'de> serde::Deserialize<'de> for InternedString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
- deserializer.deserialize_str(InternedStringVisitor)
- }
-}
-
-impl<'de> serde::de::Visitor<'de> for InternedStringVisitor {
- type Value = InternedString;
-
- fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- formatter.write_str("an String like thing")
- }
-
- fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
- where
- E: serde::de::Error,
- {
- Ok(InternedString::new(v))
+ UntaggedEnumVisitor::new()
+ .expecting("an String like thing")
+ .string(|value| Ok(InternedString::new(value)))
+ .deserialize(deserializer)
}
}
diff --git a/src/tools/cargo/src/cargo/util/mod.rs b/src/tools/cargo/src/cargo/util/mod.rs
index 26e97e2d2..b4d14f038 100644
--- a/src/tools/cargo/src/cargo/util/mod.rs
+++ b/src/tools/cargo/src/cargo/util/mod.rs
@@ -22,7 +22,7 @@ pub use self::progress::{Progress, ProgressStyle};
pub use self::queue::Queue;
pub use self::restricted_names::validate_package_name;
pub use self::rustc::Rustc;
-pub use self::semver_ext::{OptVersionReq, VersionExt, VersionReqExt};
+pub use self::semver_ext::{OptVersionReq, PartialVersion, RustVersion, VersionExt, VersionReqExt};
pub use self::to_semver::ToSemver;
pub use self::vcs::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
pub use self::workspace::{
@@ -60,12 +60,20 @@ mod queue;
pub mod restricted_names;
pub mod rustc;
mod semver_ext;
+pub mod style;
pub mod to_semver;
pub mod toml;
pub mod toml_mut;
mod vcs;
mod workspace;
+pub fn is_rustup() -> bool {
+ // ALLOWED: `RUSTUP_HOME` should only be read from process env, otherwise
+ // other tools may point to executables from incompatible distributions.
+ #[allow(clippy::disallowed_methods)]
+ std::env::var_os("RUSTUP_HOME").is_some()
+}
+
pub fn elapsed(duration: Duration) -> String {
let secs = duration.as_secs();
@@ -153,7 +161,7 @@ pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> std::io::Result<PathBuf> {
// On Windows `canonicalize` may fail, so we fall back to getting an absolute path.
std::fs::canonicalize(&path).or_else(|_| {
- // Return an error if a file does not exist for better compatiblity with `canonicalize`
+ // Return an error if a file does not exist for better compatibility with `canonicalize`
if !path.as_ref().try_exists()? {
return Err(Error::new(ErrorKind::NotFound, "the path was not found"));
}
@@ -216,7 +224,7 @@ pub fn get_umask() -> u32 {
use std::sync::OnceLock;
static UMASK: OnceLock<libc::mode_t> = OnceLock::new();
// SAFETY: Syscalls are unsafe. Calling `umask` twice is even unsafer for
- // multithreading program, since it doesn't provide a way to retrive the
+ // multithreading program, since it doesn't provide a way to retrieve the
// value without modifications. We use a static `OnceLock` here to ensure
// it only gets call once during the entire program lifetime.
*UMASK.get_or_init(|| unsafe {
diff --git a/src/tools/cargo/src/cargo/util/network/http.rs b/src/tools/cargo/src/cargo/util/network/http.rs
index 73880f60e..869b2fc22 100644
--- a/src/tools/cargo/src/cargo/util/network/http.rs
+++ b/src/tools/cargo/src/cargo/util/network/http.rs
@@ -135,7 +135,7 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<
if let Some(true) = http.debug {
handle.verbose(true)?;
- tracing::debug!("{:#?}", curl::Version::get());
+ tracing::debug!(target: "network", "{:#?}", curl::Version::get());
handle.debug_function(|kind, data| {
enum LogLevel {
Debug,
@@ -167,16 +167,20 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<
line = "set-cookie: [REDACTED]";
}
match level {
- Debug => debug!("http-debug: {prefix} {line}"),
- Trace => trace!("http-debug: {prefix} {line}"),
+ Debug => debug!(target: "network", "http-debug: {prefix} {line}"),
+ Trace => trace!(target: "network", "http-debug: {prefix} {line}"),
}
}
}
Err(_) => {
let len = data.len();
match level {
- Debug => debug!("http-debug: {prefix} ({len} bytes of data)"),
- Trace => trace!("http-debug: {prefix} ({len} bytes of data)"),
+ Debug => {
+ debug!(target: "network", "http-debug: {prefix} ({len} bytes of data)")
+ }
+ Trace => {
+ trace!(target: "network", "http-debug: {prefix} ({len} bytes of data)")
+ }
}
}
}
diff --git a/src/tools/cargo/src/cargo/util/network/mod.rs b/src/tools/cargo/src/cargo/util/network/mod.rs
index 5db594945..2bf781595 100644
--- a/src/tools/cargo/src/cargo/util/network/mod.rs
+++ b/src/tools/cargo/src/cargo/util/network/mod.rs
@@ -29,7 +29,7 @@ macro_rules! try_old_curl {
let result = $e;
if cfg!(target_os = "macos") {
if let Err(e) = result {
- ::tracing::warn!("ignoring libcurl {} error: {}", $msg, e);
+ ::tracing::warn!(target: "network", "ignoring libcurl {} error: {}", $msg, e);
}
} else {
use ::anyhow::Context;
diff --git a/src/tools/cargo/src/cargo/util/network/retry.rs b/src/tools/cargo/src/cargo/util/network/retry.rs
index 5cb7d1e4f..742c2f01c 100644
--- a/src/tools/cargo/src/cargo/util/network/retry.rs
+++ b/src/tools/cargo/src/cargo/util/network/retry.rs
@@ -1,4 +1,45 @@
//! Utilities for retrying a network operation.
+//!
+//! Some network errors are considered "spurious", meaning it is not a real
+//! error (such as a 404 not found) and is likely a transient error (like a
+//! bad network connection) that we can hope will resolve itself shortly. The
+//! [`Retry`] type offers a way to repeatedly perform some kind of network
+//! operation with a delay if it detects one of these possibly transient
+//! errors.
+//!
+//! This supports errors from [`git2`], [`gix`], [`curl`], and
+//! [`HttpNotSuccessful`] 5xx HTTP errors.
+//!
+//! The number of retries can be configured by the user via the `net.retry`
+//! config option. This indicates the number of times to retry the operation
+//! (default 3 times for a total of 4 attempts).
+//!
+//! There are hard-coded constants that indicate how long to sleep between
+//! retries. The constants are tuned to balance a few factors, such as the
+//! responsiveness to the user (we don't want cargo to hang for too long
+//! retrying things), and accommodating things like Cloudfront's default
+//! negative TTL of 10 seconds (if Cloudfront gets a 5xx error for whatever
+//! reason it won't try to fetch again for 10 seconds).
+//!
+//! The timeout also implements a primitive form of random jitter. This is so
+//! that if multiple requests fail at the same time that they don't all flood
+//! the server at the same time when they are retried. This jitter still has
+//! some clumping behavior, but should be good enough.
+//!
+//! [`Retry`] is the core type for implementing retry logic. The
+//! [`Retry::try`] method can be called with a callback, and it will
+//! indicate if it needs to be called again sometime in the future if there
+//! was a possibly transient error. The caller is responsible for sleeping the
+//! appropriate amount of time and then calling [`Retry::try`] again.
+//!
+//! [`with_retry`] is a convenience function that will create a [`Retry`] and
+//! handle repeatedly running a callback until it succeeds, or it runs out of
+//! retries.
+//!
+//! Some interesting resources about retries:
+//! - <https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/>
+//! - <https://en.wikipedia.org/wiki/Exponential_backoff>
+//! - <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After>
use crate::util::errors::HttpNotSuccessful;
use crate::{CargoResult, Config};
@@ -7,15 +48,32 @@ use rand::Rng;
use std::cmp::min;
use std::time::Duration;
+/// State for managing retrying a network operation.
pub struct Retry<'a> {
config: &'a Config,
+ /// The number of failed attempts that have been done so far.
+ ///
+ /// Starts at 0, and increases by one each time an attempt fails.
retries: u64,
+ /// The maximum number of times the operation should be retried.
+ ///
+ /// 0 means it should never retry.
max_retries: u64,
}
+/// The result of attempting some operation via [`Retry::try`].
pub enum RetryResult<T> {
+ /// The operation was successful.
+ ///
+ /// The wrapped value is the return value of the callback function.
Success(T),
+ /// The operation was an error, and it should not be tried again.
Err(anyhow::Error),
+ /// The operation failed, and should be tried again in the future.
+ ///
+ /// The wrapped value is the number of milliseconds to wait before trying
+ /// again. The caller is responsible for waiting this long and then
+ /// calling [`Retry::try`] again.
Retry(u64),
}
@@ -40,7 +98,9 @@ impl<'a> Retry<'a> {
})
}
- /// Returns `Ok(None)` for operations that should be re-tried.
+ /// Calls the given callback, and returns a [`RetryResult`] which
+ /// indicates whether or not this needs to be called again at some point
+ /// in the future to retry the operation if it failed.
pub fn r#try<T>(&mut self, f: impl FnOnce() -> CargoResult<T>) -> RetryResult<T> {
match f() {
Err(ref e) if maybe_spurious(e) && self.retries < self.max_retries => {
diff --git a/src/tools/cargo/src/cargo/util/network/sleep.rs b/src/tools/cargo/src/cargo/util/network/sleep.rs
index fab53263b..d3c770f85 100644
--- a/src/tools/cargo/src/cargo/util/network/sleep.rs
+++ b/src/tools/cargo/src/cargo/util/network/sleep.rs
@@ -68,7 +68,6 @@ impl<T> SleepTracker<T> {
let now = Instant::now();
let mut result = Vec::new();
while let Some(next) = self.heap.peek() {
- tracing::debug!("ERIC: now={now:?} next={:?}", next.wakeup);
if next.wakeup < now {
result.push(self.heap.pop().unwrap().data);
} else {
diff --git a/src/tools/cargo/src/cargo/util/profile.rs b/src/tools/cargo/src/cargo/util/profile.rs
index 29b110492..ede8db191 100644
--- a/src/tools/cargo/src/cargo/util/profile.rs
+++ b/src/tools/cargo/src/cargo/util/profile.rs
@@ -43,9 +43,8 @@ pub fn start<T: fmt::Display>(desc: T) -> Profiler {
impl Drop for Profiler {
fn drop(&mut self) {
- let enabled = match enabled_level() {
- Some(i) => i,
- None => return,
+ let Some(enabled) = enabled_level() else {
+ return;
};
let (start, stack_len) = PROFILE_STACK.with(|stack| {
diff --git a/src/tools/cargo/src/cargo/util/progress.rs b/src/tools/cargo/src/cargo/util/progress.rs
index bcbc1bc0e..374f782bb 100644
--- a/src/tools/cargo/src/cargo/util/progress.rs
+++ b/src/tools/cargo/src/cargo/util/progress.rs
@@ -160,9 +160,8 @@ impl<'cfg> Progress<'cfg> {
/// This may not actually update the display if `tick` is being called too
/// quickly.
pub fn tick(&mut self, cur: usize, max: usize, msg: &str) -> CargoResult<()> {
- let s = match &mut self.state {
- Some(s) => s,
- None => return Ok(()),
+ let Some(s) = &mut self.state else {
+ return Ok(());
};
// Don't update too often as it can cause excessive performance loss
@@ -340,9 +339,8 @@ impl Format {
ProgressStyle::Indeterminate => String::new(),
};
let extra_len = stats.len() + 2 /* [ and ] */ + 15 /* status header */;
- let display_width = match self.width().checked_sub(extra_len) {
- Some(n) => n,
- None => return None,
+ let Some(display_width) = self.width().checked_sub(extra_len) else {
+ return None;
};
let mut string = String::with_capacity(self.max_width);
diff --git a/src/tools/cargo/src/cargo/util/rustc.rs b/src/tools/cargo/src/cargo/util/rustc.rs
index 238145af6..d1bb3981d 100644
--- a/src/tools/cargo/src/cargo/util/rustc.rs
+++ b/src/tools/cargo/src/cargo/util/rustc.rs
@@ -63,8 +63,7 @@ impl Rustc {
let extract = |field: &str| -> CargoResult<&str> {
verbose_version
.lines()
- .find(|l| l.starts_with(field))
- .map(|l| &l[field.len()..])
+ .find_map(|l| l.strip_prefix(field))
.ok_or_else(|| {
anyhow::format_err!(
"`rustc -vV` didn't have a line for `{}`, got:\n{}",
diff --git a/src/tools/cargo/src/cargo/util/semver_ext.rs b/src/tools/cargo/src/cargo/util/semver_ext.rs
index de6d68e16..5839d85d2 100644
--- a/src/tools/cargo/src/cargo/util/semver_ext.rs
+++ b/src/tools/cargo/src/cargo/util/semver_ext.rs
@@ -1,4 +1,5 @@
use semver::{Comparator, Op, Version, VersionReq};
+use serde_untagged::UntaggedEnumVisitor;
use std::fmt::{self, Display};
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
@@ -108,6 +109,218 @@ impl From<VersionReq> for OptVersionReq {
}
}
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug, serde::Serialize)]
+#[serde(transparent)]
+pub struct RustVersion(PartialVersion);
+
+impl std::ops::Deref for RustVersion {
+ type Target = PartialVersion;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl std::str::FromStr for RustVersion {
+ type Err = anyhow::Error;
+
+ fn from_str(value: &str) -> Result<Self, Self::Err> {
+ let partial = value.parse::<PartialVersion>()?;
+ if partial.pre.is_some() {
+ anyhow::bail!("unexpected prerelease field, expected a version like \"1.32\"")
+ }
+ if partial.build.is_some() {
+ anyhow::bail!("unexpected prerelease field, expected a version like \"1.32\"")
+ }
+ Ok(Self(partial))
+ }
+}
+
+impl<'de> serde::Deserialize<'de> for RustVersion {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ UntaggedEnumVisitor::new()
+ .expecting("SemVer version")
+ .string(|value| value.parse().map_err(serde::de::Error::custom))
+ .deserialize(deserializer)
+ }
+}
+
+impl Display for RustVersion {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
+pub struct PartialVersion {
+ pub major: u64,
+ pub minor: Option<u64>,
+ pub patch: Option<u64>,
+ pub pre: Option<semver::Prerelease>,
+ pub build: Option<semver::BuildMetadata>,
+}
+
+impl PartialVersion {
+ pub fn version(&self) -> Option<Version> {
+ Some(Version {
+ major: self.major,
+ minor: self.minor?,
+ patch: self.patch?,
+ pre: self.pre.clone().unwrap_or_default(),
+ build: self.build.clone().unwrap_or_default(),
+ })
+ }
+
+ pub fn caret_req(&self) -> VersionReq {
+ VersionReq {
+ comparators: vec![Comparator {
+ op: semver::Op::Caret,
+ major: self.major,
+ minor: self.minor,
+ patch: self.patch,
+ pre: self.pre.as_ref().cloned().unwrap_or_default(),
+ }],
+ }
+ }
+
+ /// Check if this matches a version, including build metadata
+ ///
+ /// Build metadata does not affect version precedence but may be necessary for uniquely
+ /// identifying a package.
+ pub fn matches(&self, version: &Version) -> bool {
+ if !version.pre.is_empty() && self.pre.is_none() {
+ // Pre-release versions must be explicitly opted into, if for no other reason than to
+ // give us room to figure out and define the semantics
+ return false;
+ }
+ self.major == version.major
+ && self.minor.map(|f| f == version.minor).unwrap_or(true)
+ && self.patch.map(|f| f == version.patch).unwrap_or(true)
+ && self.pre.as_ref().map(|f| f == &version.pre).unwrap_or(true)
+ && self
+ .build
+ .as_ref()
+ .map(|f| f == &version.build)
+ .unwrap_or(true)
+ }
+}
+
+impl From<semver::Version> for PartialVersion {
+ fn from(ver: semver::Version) -> Self {
+ let pre = if ver.pre.is_empty() {
+ None
+ } else {
+ Some(ver.pre)
+ };
+ let build = if ver.build.is_empty() {
+ None
+ } else {
+ Some(ver.build)
+ };
+ Self {
+ major: ver.major,
+ minor: Some(ver.minor),
+ patch: Some(ver.patch),
+ pre,
+ build,
+ }
+ }
+}
+
+impl std::str::FromStr for PartialVersion {
+ type Err = anyhow::Error;
+
+ fn from_str(value: &str) -> Result<Self, Self::Err> {
+ if is_req(value) {
+ anyhow::bail!("unexpected version requirement, expected a version like \"1.32\"")
+ }
+ match semver::Version::parse(value) {
+ Ok(ver) => Ok(ver.into()),
+ Err(_) => {
+ // HACK: Leverage `VersionReq` for partial version parsing
+ let mut version_req = match semver::VersionReq::parse(value) {
+ Ok(req) => req,
+ Err(_) if value.contains('-') => {
+ anyhow::bail!(
+ "unexpected prerelease field, expected a version like \"1.32\""
+ )
+ }
+ Err(_) if value.contains('+') => {
+ anyhow::bail!("unexpected build field, expected a version like \"1.32\"")
+ }
+ Err(_) => anyhow::bail!("expected a version like \"1.32\""),
+ };
+ assert_eq!(version_req.comparators.len(), 1, "guaranteed by is_req");
+ let comp = version_req.comparators.pop().unwrap();
+ assert_eq!(comp.op, semver::Op::Caret, "guaranteed by is_req");
+ let pre = if comp.pre.is_empty() {
+ None
+ } else {
+ Some(comp.pre)
+ };
+ Ok(Self {
+ major: comp.major,
+ minor: comp.minor,
+ patch: comp.patch,
+ pre,
+ build: None,
+ })
+ }
+ }
+ }
+}
+
+impl Display for PartialVersion {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let major = self.major;
+ write!(f, "{major}")?;
+ if let Some(minor) = self.minor {
+ write!(f, ".{minor}")?;
+ }
+ if let Some(patch) = self.patch {
+ write!(f, ".{patch}")?;
+ }
+ if let Some(pre) = self.pre.as_ref() {
+ write!(f, "-{pre}")?;
+ }
+ if let Some(build) = self.build.as_ref() {
+ write!(f, "+{build}")?;
+ }
+ Ok(())
+ }
+}
+
+impl serde::Serialize for PartialVersion {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ serializer.collect_str(self)
+ }
+}
+
+impl<'de> serde::Deserialize<'de> for PartialVersion {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ UntaggedEnumVisitor::new()
+ .expecting("SemVer version")
+ .string(|value| value.parse().map_err(serde::de::Error::custom))
+ .deserialize(deserializer)
+ }
+}
+
+fn is_req(value: &str) -> bool {
+ let Some(first) = value.chars().next() else {
+ return false;
+ };
+ "<>=^~".contains(first) || value.contains('*') || value.contains(',')
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src/tools/cargo/src/cargo/util/style.rs b/src/tools/cargo/src/cargo/util/style.rs
new file mode 100644
index 000000000..618a10876
--- /dev/null
+++ b/src/tools/cargo/src/cargo/util/style.rs
@@ -0,0 +1,13 @@
+use anstyle::*;
+
+pub const NOP: Style = Style::new();
+pub const HEADER: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
+pub const USAGE: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
+pub const LITERAL: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
+pub const PLACEHOLDER: Style = AnsiColor::Cyan.on_default();
+pub const ERROR: Style = AnsiColor::Red.on_default().effects(Effects::BOLD);
+pub const WARN: Style = AnsiColor::Yellow.on_default().effects(Effects::BOLD);
+pub const NOTE: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
+pub const GOOD: Style = AnsiColor::Green.on_default().effects(Effects::BOLD);
+pub const VALID: Style = AnsiColor::Cyan.on_default().effects(Effects::BOLD);
+pub const INVALID: Style = AnsiColor::Yellow.on_default().effects(Effects::BOLD);
diff --git a/src/tools/cargo/src/cargo/util/to_semver.rs b/src/tools/cargo/src/cargo/util/to_semver.rs
index 25da9dfb9..3cc9e5706 100644
--- a/src/tools/cargo/src/cargo/util/to_semver.rs
+++ b/src/tools/cargo/src/cargo/util/to_semver.rs
@@ -15,7 +15,10 @@ impl<'a> ToSemver for &'a str {
fn to_semver(self) -> CargoResult<Version> {
match Version::parse(self.trim()) {
Ok(v) => Ok(v),
- Err(..) => Err(anyhow::format_err!("cannot parse '{}' as a semver", self)),
+ Err(..) => Err(anyhow::format_err!(
+ "cannot parse '{}' as a SemVer version",
+ self
+ )),
}
}
}
diff --git a/src/tools/cargo/src/cargo/util/toml/embedded.rs b/src/tools/cargo/src/cargo/util/toml/embedded.rs
index 395430c1b..482268923 100644
--- a/src/tools/cargo/src/cargo/util/toml/embedded.rs
+++ b/src/tools/cargo/src/cargo/util/toml/embedded.rs
@@ -15,26 +15,72 @@ pub fn expand_manifest(
path: &std::path::Path,
config: &Config,
) -> CargoResult<String> {
- let comment = match extract_comment(content) {
- Ok(comment) => Some(comment),
- Err(err) => {
- tracing::trace!("failed to extract doc comment: {err}");
- None
+ let source = split_source(content)?;
+ if let Some(frontmatter) = source.frontmatter {
+ match source.info {
+ Some("cargo") => {}
+ None => {
+ anyhow::bail!("frontmatter is missing an infostring; specify `cargo` for embedding a manifest");
+ }
+ Some(other) => {
+ if let Some(remainder) = other.strip_prefix("cargo,") {
+ anyhow::bail!("cargo does not support frontmatter infostring attributes like `{remainder}` at this time")
+ } else {
+ anyhow::bail!("frontmatter infostring `{other}` is unsupported by cargo; specify `cargo` for embedding a manifest")
+ }
+ }
}
- }
- .unwrap_or_default();
- let manifest = match extract_manifest(&comment)? {
- Some(manifest) => Some(manifest),
- None => {
- tracing::trace!("failed to extract manifest");
- None
+
+ // HACK: until rustc has native support for this syntax, we have to remove it from the
+ // source file
+ use std::fmt::Write as _;
+ let hash = crate::util::hex::short_hash(&path.to_string_lossy());
+ let mut rel_path = std::path::PathBuf::new();
+ rel_path.push("target");
+ rel_path.push(&hash[0..2]);
+ rel_path.push(&hash[2..]);
+ let target_dir = config.home().join(rel_path);
+ let hacked_path = target_dir
+ .join(
+ path.file_name()
+ .expect("always a name for embedded manifests"),
+ )
+ .into_path_unlocked();
+ let mut hacked_source = String::new();
+ if let Some(shebang) = source.shebang {
+ writeln!(hacked_source, "{shebang}")?;
+ }
+ writeln!(hacked_source)?; // open
+ for _ in 0..frontmatter.lines().count() {
+ writeln!(hacked_source)?;
}
+ writeln!(hacked_source)?; // close
+ writeln!(hacked_source, "{}", source.content)?;
+ if let Some(parent) = hacked_path.parent() {
+ cargo_util::paths::create_dir_all(parent)?;
+ }
+ cargo_util::paths::write_if_changed(&hacked_path, hacked_source)?;
+
+ let manifest = expand_manifest_(&frontmatter, &hacked_path, config)
+ .with_context(|| format!("failed to parse manifest at {}", path.display()))?;
+ let manifest = toml::to_string_pretty(&manifest)?;
+ Ok(manifest)
+ } else {
+ // Legacy doc-comment support; here only for transitional purposes
+ let comment = extract_comment(content)?.unwrap_or_default();
+ let manifest = match extract_manifest(&comment)? {
+ Some(manifest) => Some(manifest),
+ None => {
+ tracing::trace!("failed to extract manifest");
+ None
+ }
+ }
+ .unwrap_or_default();
+ let manifest = expand_manifest_(&manifest, path, config)
+ .with_context(|| format!("failed to parse manifest at {}", path.display()))?;
+ let manifest = toml::to_string_pretty(&manifest)?;
+ Ok(manifest)
}
- .unwrap_or_default();
- let manifest = expand_manifest_(&manifest, path, config)
- .with_context(|| format!("failed to parse manifest at {}", path.display()))?;
- let manifest = toml::to_string_pretty(&manifest)?;
- Ok(manifest)
}
fn expand_manifest_(
@@ -66,10 +112,8 @@ fn expand_manifest_(
anyhow::bail!("`package.{key}` is not allowed in embedded manifests")
}
}
- let file_name = path
- .file_name()
- .ok_or_else(|| anyhow::format_err!("no file name"))?
- .to_string_lossy();
+ // HACK: Using an absolute path while `hacked_path` is in use
+ let bin_path = path.to_string_lossy().into_owned();
let file_stem = path
.file_stem()
.ok_or_else(|| anyhow::format_err!("no file name"))?
@@ -103,10 +147,7 @@ fn expand_manifest_(
let mut bin = toml::Table::new();
bin.insert("name".to_owned(), toml::Value::String(bin_name));
- bin.insert(
- "path".to_owned(),
- toml::Value::String(file_name.into_owned()),
- );
+ bin.insert("path".to_owned(), toml::Value::String(bin_path));
manifest.insert(
"bin".to_owned(),
toml::Value::Array(vec![toml::Value::Table(bin)]),
@@ -159,8 +200,82 @@ fn sanitize_name(name: &str) -> String {
name
}
+struct Source<'s> {
+ shebang: Option<&'s str>,
+ info: Option<&'s str>,
+ frontmatter: Option<&'s str>,
+ content: &'s str,
+}
+
+fn split_source(input: &str) -> CargoResult<Source<'_>> {
+ let mut source = Source {
+ shebang: None,
+ info: None,
+ frontmatter: None,
+ content: input,
+ };
+
+ // See rust-lang/rust's compiler/rustc_lexer/src/lib.rs's `strip_shebang`
+ // Shebang must start with `#!` literally, without any preceding whitespace.
+ // For simplicity we consider any line starting with `#!` a shebang,
+ // regardless of restrictions put on shebangs by specific platforms.
+ if let Some(rest) = source.content.strip_prefix("#!") {
+ // Ok, this is a shebang but if the next non-whitespace token is `[`,
+ // then it may be valid Rust code, so consider it Rust code.
+ if rest.trim_start().starts_with('[') {
+ return Ok(source);
+ }
+
+ // No other choice than to consider this a shebang.
+ let (shebang, content) = source
+ .content
+ .split_once('\n')
+ .unwrap_or((source.content, ""));
+ source.shebang = Some(shebang);
+ source.content = content;
+ }
+
+ let tick_end = source
+ .content
+ .char_indices()
+ .find_map(|(i, c)| (c != '`').then_some(i))
+ .unwrap_or(source.content.len());
+ let (fence_pattern, rest) = match tick_end {
+ 0 => {
+ return Ok(source);
+ }
+ 1 | 2 => {
+ anyhow::bail!("found {tick_end} backticks in rust frontmatter, expected at least 3")
+ }
+ _ => source.content.split_at(tick_end),
+ };
+ let (info, content) = rest.split_once("\n").unwrap_or((rest, ""));
+ if !info.is_empty() {
+ source.info = Some(info.trim_end());
+ }
+ source.content = content;
+
+ let Some((frontmatter, content)) = source.content.split_once(fence_pattern) else {
+ anyhow::bail!("no closing `{fence_pattern}` found for frontmatter");
+ };
+ source.frontmatter = Some(frontmatter);
+ source.content = content;
+
+ let (line, content) = source
+ .content
+ .split_once("\n")
+ .unwrap_or((source.content, ""));
+ let line = line.trim();
+ if !line.is_empty() {
+ anyhow::bail!("unexpected trailing content on closing fence: `{line}`");
+ }
+ source.content = content;
+
+ Ok(source)
+}
+
/// Locates a "code block manifest" in Rust source.
-fn extract_comment(input: &str) -> CargoResult<String> {
+fn extract_comment(input: &str) -> CargoResult<Option<String>> {
let mut doc_fragments = Vec::new();
let file = syn::parse_file(input)?;
// HACK: `syn` doesn't tell us what kind of comment was used, so infer it from how many
@@ -181,7 +296,7 @@ fn extract_comment(input: &str) -> CargoResult<String> {
}
}
if doc_fragments.is_empty() {
- anyhow::bail!("no doc-comment found");
+ return Ok(None);
}
unindent_doc_fragments(&mut doc_fragments);
@@ -190,7 +305,7 @@ fn extract_comment(input: &str) -> CargoResult<String> {
add_doc_fragment(&mut doc_comment, frag);
}
- Ok(doc_comment)
+ Ok(Some(doc_comment))
}
/// A `#[doc]`
@@ -496,7 +611,7 @@ mod test_expand {
snapbox::assert_eq(
r#"[[bin]]
name = "test-"
-path = "test.rs"
+path = "/home/me/test.rs"
[package]
autobenches = false
@@ -523,7 +638,7 @@ strip = true
snapbox::assert_eq(
r#"[[bin]]
name = "test-"
-path = "test.rs"
+path = "/home/me/test.rs"
[dependencies]
time = "0.1.25"
@@ -561,29 +676,30 @@ mod test_comment {
macro_rules! ec {
($s:expr) => {
- extract_comment($s).unwrap_or_else(|err| panic!("{}", err))
+ extract_comment($s)
+ .unwrap_or_else(|err| panic!("{}", err))
+ .unwrap()
};
}
#[test]
fn test_no_comment() {
- snapbox::assert_eq(
- "no doc-comment found",
+ assert_eq!(
+ None,
extract_comment(
r#"
fn main () {
}
"#,
)
- .unwrap_err()
- .to_string(),
+ .unwrap()
);
}
#[test]
fn test_no_comment_she_bang() {
- snapbox::assert_eq(
- "no doc-comment found",
+ assert_eq!(
+ None,
extract_comment(
r#"#!/usr/bin/env cargo-eval
@@ -591,8 +707,7 @@ fn main () {
}
"#,
)
- .unwrap_err()
- .to_string(),
+ .unwrap()
);
}
diff --git a/src/tools/cargo/src/cargo/util/toml/mod.rs b/src/tools/cargo/src/cargo/util/toml/mod.rs
index 963c4afaa..2e730b4e9 100644
--- a/src/tools/cargo/src/cargo/util/toml/mod.rs
+++ b/src/tools/cargo/src/cargo/util/toml/mod.rs
@@ -1,7 +1,6 @@
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::ffi::OsStr;
use std::fmt::{self, Display, Write};
-use std::marker::PhantomData;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::str::{self, FromStr};
@@ -11,11 +10,10 @@ use cargo_platform::Platform;
use cargo_util::paths;
use itertools::Itertools;
use lazycell::LazyCell;
-use semver::{self, VersionReq};
-use serde::de::IntoDeserializer as _;
-use serde::de::{self, Unexpected};
+use serde::de::{self, IntoDeserializer as _, Unexpected};
use serde::ser;
use serde::{Deserialize, Serialize};
+use serde_untagged::UntaggedEnumVisitor;
use tracing::{debug, trace};
use url::Url;
@@ -31,7 +29,8 @@ use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY};
use crate::util::errors::{CargoResult, ManifestError};
use crate::util::interning::InternedString;
use crate::util::{
- self, config::ConfigRelativePath, validate_package_name, Config, IntoUrl, VersionReqExt,
+ self, config::ConfigRelativePath, validate_package_name, Config, IntoUrl, OptVersionReq,
+ RustVersion,
};
pub mod embedded;
@@ -99,26 +98,9 @@ fn read_manifest_from_str(
) -> CargoResult<(EitherManifest, Vec<PathBuf>)> {
let package_root = manifest_file.parent().unwrap();
- let toml = {
- let pretty_filename = manifest_file
- .strip_prefix(config.cwd())
- .unwrap_or(manifest_file);
- parse_document(contents, pretty_filename, config)?
- };
-
- // Provide a helpful error message for a common user error.
- if let Some(package) = toml.get("package").or_else(|| toml.get("project")) {
- if let Some(feats) = package.get("cargo-features") {
- bail!(
- "cargo-features = {} was found in the wrong location: it \
- should be set at the top of Cargo.toml before any tables",
- feats
- );
- }
- }
-
let mut unused = BTreeSet::new();
- let manifest: TomlManifest = serde_ignored::deserialize(toml.into_deserializer(), |path| {
+ let deserializer = toml::de::Deserializer::new(contents);
+ let manifest: TomlManifest = serde_ignored::deserialize(deserializer, |path| {
let mut key = String::new();
stringify(&mut key, &path);
unused.insert(key);
@@ -194,8 +176,7 @@ fn read_manifest_from_str(
pub fn parse_document(toml: &str, _file: &Path, _config: &Config) -> CargoResult<toml::Table> {
// At the moment, no compatibility checks are needed.
- toml.parse()
- .map_err(|e| anyhow::Error::from(e).context("could not parse input as TOML"))
+ toml.parse().map_err(Into::into)
}
/// Warn about paths that have been deprecated and may conflict.
@@ -230,34 +211,14 @@ impl<'de, P: Deserialize<'de> + Clone> de::Deserialize<'de> for TomlDependency<P
where
D: de::Deserializer<'de>,
{
- struct TomlDependencyVisitor<P>(PhantomData<P>);
-
- impl<'de, P: Deserialize<'de> + Clone> de::Visitor<'de> for TomlDependencyVisitor<P> {
- type Value = TomlDependency<P>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- formatter.write_str(
- "a version string like \"0.9.8\" or a \
+ UntaggedEnumVisitor::new()
+ .expecting(
+ "a version string like \"0.9.8\" or a \
detailed dependency like { version = \"0.9.8\" }",
- )
- }
-
- fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- Ok(TomlDependency::Simple(s.to_owned()))
- }
-
- fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error>
- where
- V: de::MapAccess<'de>,
- {
- let mvd = de::value::MapAccessDeserializer::new(map);
- DetailedTomlDependency::deserialize(mvd).map(TomlDependency::Detailed)
- }
- }
- deserializer.deserialize_any(TomlDependencyVisitor(PhantomData))
+ )
+ .string(|value| Ok(TomlDependency::Simple(value.to_owned())))
+ .map(|value| value.deserialize().map(TomlDependency::Detailed))
+ .deserialize(deserializer)
}
}
@@ -377,7 +338,7 @@ pub struct TomlManifest {
patch: Option<BTreeMap<String, BTreeMap<String, TomlDependency>>>,
workspace: Option<TomlWorkspace>,
badges: Option<MaybeWorkspaceBtreeMap>,
- lints: Option<toml::Value>,
+ lints: Option<MaybeWorkspaceLints>,
}
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
@@ -417,39 +378,22 @@ impl<'de> de::Deserialize<'de> for TomlOptLevel {
where
D: de::Deserializer<'de>,
{
- struct Visitor;
-
- impl<'de> de::Visitor<'de> for Visitor {
- type Value = TomlOptLevel;
-
- fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- formatter.write_str("an optimization level")
- }
-
- fn visit_i64<E>(self, value: i64) -> Result<TomlOptLevel, E>
- where
- E: de::Error,
- {
- Ok(TomlOptLevel(value.to_string()))
- }
-
- fn visit_str<E>(self, value: &str) -> Result<TomlOptLevel, E>
- where
- E: de::Error,
- {
+ use serde::de::Error as _;
+ UntaggedEnumVisitor::new()
+ .expecting("an optimization level")
+ .i64(|value| Ok(TomlOptLevel(value.to_string())))
+ .string(|value| {
if value == "s" || value == "z" {
Ok(TomlOptLevel(value.to_string()))
} else {
- Err(E::custom(format!(
+ Err(serde_untagged::de::Error::custom(format!(
"must be `0`, `1`, `2`, `3`, `s` or `z`, \
but found the string: \"{}\"",
value
)))
}
- }
- }
-
- d.deserialize_any(Visitor)
+ })
+ .deserialize(d)
}
}
@@ -494,58 +438,48 @@ impl<'de> de::Deserialize<'de> for TomlDebugInfo {
where
D: de::Deserializer<'de>,
{
- struct Visitor;
-
- impl<'de> de::Visitor<'de> for Visitor {
- type Value = TomlDebugInfo;
-
- fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- formatter.write_str(
- "a boolean, 0, 1, 2, \"line-tables-only\", or \"line-directives-only\"",
- )
- }
-
- fn visit_i64<E>(self, value: i64) -> Result<TomlDebugInfo, E>
- where
- E: de::Error,
- {
+ use serde::de::Error as _;
+ let expecting = "a boolean, 0, 1, 2, \"line-tables-only\", or \"line-directives-only\"";
+ UntaggedEnumVisitor::new()
+ .expecting(expecting)
+ .bool(|value| {
+ Ok(if value {
+ TomlDebugInfo::Full
+ } else {
+ TomlDebugInfo::None
+ })
+ })
+ .i64(|value| {
let debuginfo = match value {
0 => TomlDebugInfo::None,
1 => TomlDebugInfo::Limited,
2 => TomlDebugInfo::Full,
- _ => return Err(de::Error::invalid_value(Unexpected::Signed(value), &self)),
+ _ => {
+ return Err(serde_untagged::de::Error::invalid_value(
+ Unexpected::Signed(value),
+ &expecting,
+ ))
+ }
};
Ok(debuginfo)
- }
-
- fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- Ok(if v {
- TomlDebugInfo::Full
- } else {
- TomlDebugInfo::None
- })
- }
-
- fn visit_str<E>(self, value: &str) -> Result<TomlDebugInfo, E>
- where
- E: de::Error,
- {
+ })
+ .string(|value| {
let debuginfo = match value {
"none" => TomlDebugInfo::None,
"limited" => TomlDebugInfo::Limited,
"full" => TomlDebugInfo::Full,
"line-directives-only" => TomlDebugInfo::LineDirectivesOnly,
"line-tables-only" => TomlDebugInfo::LineTablesOnly,
- _ => return Err(de::Error::invalid_value(Unexpected::Str(value), &self)),
+ _ => {
+ return Err(serde_untagged::de::Error::invalid_value(
+ Unexpected::Str(value),
+ &expecting,
+ ))
+ }
};
Ok(debuginfo)
- }
- }
-
- d.deserialize_any(Visitor)
+ })
+ .deserialize(d)
}
}
@@ -865,8 +799,8 @@ impl TomlProfile {
self.codegen_units = Some(v);
}
- if let Some(v) = &profile.debug {
- self.debug = Some(v.clone());
+ if let Some(v) = profile.debug {
+ self.debug = Some(v);
}
if let Some(v) = profile.debug_assertions {
@@ -944,32 +878,11 @@ impl<'de> de::Deserialize<'de> for StringOrVec {
where
D: de::Deserializer<'de>,
{
- struct Visitor;
-
- impl<'de> de::Visitor<'de> for Visitor {
- type Value = StringOrVec;
-
- fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- formatter.write_str("string or list of strings")
- }
-
- fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- Ok(StringOrVec(vec![s.to_string()]))
- }
-
- fn visit_seq<V>(self, v: V) -> Result<Self::Value, V::Error>
- where
- V: de::SeqAccess<'de>,
- {
- let seq = de::value::SeqAccessDeserializer::new(v);
- Vec::deserialize(seq).map(StringOrVec)
- }
- }
-
- deserializer.deserialize_any(Visitor)
+ UntaggedEnumVisitor::new()
+ .expecting("string or list of strings")
+ .string(|value| Ok(StringOrVec(vec![value.to_owned()])))
+ .seq(|value| value.deserialize().map(StringOrVec))
+ .deserialize(deserializer)
}
}
@@ -979,13 +892,25 @@ impl StringOrVec {
}
}
-#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
-#[serde(untagged, expecting = "expected a boolean or a string")]
+#[derive(Clone, Debug, Serialize, Eq, PartialEq)]
+#[serde(untagged)]
pub enum StringOrBool {
String(String),
Bool(bool),
}
+impl<'de> Deserialize<'de> for StringOrBool {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ UntaggedEnumVisitor::new()
+ .bool(|b| Ok(StringOrBool::Bool(b)))
+ .string(|s| Ok(StringOrBool::String(s.to_owned())))
+ .deserialize(deserializer)
+ }
+}
+
#[derive(PartialEq, Clone, Debug, Serialize)]
#[serde(untagged)]
pub enum VecStringOrBool {
@@ -998,32 +923,11 @@ impl<'de> de::Deserialize<'de> for VecStringOrBool {
where
D: de::Deserializer<'de>,
{
- struct Visitor;
-
- impl<'de> de::Visitor<'de> for Visitor {
- type Value = VecStringOrBool;
-
- fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- formatter.write_str("a boolean or vector of strings")
- }
-
- fn visit_seq<V>(self, v: V) -> Result<Self::Value, V::Error>
- where
- V: de::SeqAccess<'de>,
- {
- let seq = de::value::SeqAccessDeserializer::new(v);
- Vec::deserialize(seq).map(VecStringOrBool::VecString)
- }
-
- fn visit_bool<E>(self, b: bool) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- Ok(VecStringOrBool::Bool(b))
- }
- }
-
- deserializer.deserialize_any(Visitor)
+ UntaggedEnumVisitor::new()
+ .expecting("a boolean or vector of strings")
+ .bool(|value| Ok(VecStringOrBool::Bool(value)))
+ .seq(|value| value.deserialize().map(VecStringOrBool::VecString))
+ .deserialize(deserializer)
}
}
@@ -1031,35 +935,16 @@ fn version_trim_whitespace<'de, D>(deserializer: D) -> Result<MaybeWorkspaceSemv
where
D: de::Deserializer<'de>,
{
- struct Visitor;
-
- impl<'de> de::Visitor<'de> for Visitor {
- type Value = MaybeWorkspaceSemverVersion;
-
- fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
- formatter.write_str("SemVer version")
- }
-
- fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- match string.trim().parse().map_err(de::Error::custom) {
+ UntaggedEnumVisitor::new()
+ .expecting("SemVer version")
+ .string(
+ |value| match value.trim().parse().map_err(de::Error::custom) {
Ok(parsed) => Ok(MaybeWorkspace::Defined(parsed)),
Err(e) => Err(e),
- }
- }
-
- fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error>
- where
- V: de::MapAccess<'de>,
- {
- let mvd = de::value::MapAccessDeserializer::new(map);
- TomlWorkspaceField::deserialize(mvd).map(MaybeWorkspace::Workspace)
- }
- }
-
- deserializer.deserialize_any(Visitor)
+ },
+ )
+ .map(|value| value.deserialize().map(MaybeWorkspace::Workspace))
+ .deserialize(deserializer)
}
/// This Trait exists to make [`MaybeWorkspace::Workspace`] generic. It makes deserialization of
@@ -1078,7 +963,7 @@ pub trait WorkspaceInherit {
}
/// An enum that allows for inheriting keys from a workspace in a Cargo.toml.
-#[derive(Serialize, Clone, Debug)]
+#[derive(Serialize, Copy, Clone, Debug)]
#[serde(untagged)]
pub enum MaybeWorkspace<T, W: WorkspaceInherit> {
/// The "defined" type, or the type that that is used when not inheriting from a workspace.
@@ -1297,6 +1182,42 @@ impl<'de> de::Deserialize<'de> for MaybeWorkspaceString {
}
}
+type MaybeWorkspaceRustVersion = MaybeWorkspace<RustVersion, TomlWorkspaceField>;
+impl<'de> de::Deserialize<'de> for MaybeWorkspaceRustVersion {
+ fn deserialize<D>(d: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct Visitor;
+
+ impl<'de> de::Visitor<'de> for Visitor {
+ type Value = MaybeWorkspaceRustVersion;
+
+ fn expecting(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+ f.write_str("a semver or workspace")
+ }
+
+ fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ let value = value.parse::<RustVersion>().map_err(|e| E::custom(e))?;
+ Ok(MaybeWorkspaceRustVersion::Defined(value))
+ }
+
+ fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error>
+ where
+ V: de::MapAccess<'de>,
+ {
+ let mvd = de::value::MapAccessDeserializer::new(map);
+ TomlWorkspaceField::deserialize(mvd).map(MaybeWorkspace::Workspace)
+ }
+ }
+
+ d.deserialize_any(Visitor)
+ }
+}
+
type MaybeWorkspaceVecString = MaybeWorkspace<Vec<String>, TomlWorkspaceField>;
impl<'de> de::Deserialize<'de> for MaybeWorkspaceVecString {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
@@ -1444,30 +1365,7 @@ impl<'de> de::Deserialize<'de> for MaybeWorkspaceBtreeMap {
}
}
-type MaybeWorkspaceLints = MaybeWorkspace<TomlLints, TomlWorkspaceField>;
-
-impl<'de> de::Deserialize<'de> for MaybeWorkspaceLints {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- let value = serde_value::Value::deserialize(deserializer)?;
-
- if let Ok(w) = TomlWorkspaceField::deserialize(
- serde_value::ValueDeserializer::<D::Error>::new(value.clone()),
- ) {
- return if w.workspace() {
- Ok(MaybeWorkspace::Workspace(w))
- } else {
- Err(de::Error::custom("`workspace` cannot be false"))
- };
- }
- TomlLints::deserialize(serde_value::ValueDeserializer::<D::Error>::new(value))
- .map(MaybeWorkspace::Defined)
- }
-}
-
-#[derive(Deserialize, Serialize, Clone, Debug)]
+#[derive(Deserialize, Serialize, Copy, Clone, Debug)]
pub struct TomlWorkspaceField {
#[serde(deserialize_with = "bool_no_false")]
workspace: bool,
@@ -1502,16 +1400,14 @@ impl WorkspaceInherit for TomlWorkspaceField {
#[serde(rename_all = "kebab-case")]
pub struct TomlPackage {
edition: Option<MaybeWorkspaceString>,
- rust_version: Option<MaybeWorkspaceString>,
+ rust_version: Option<MaybeWorkspaceRustVersion>,
name: InternedString,
#[serde(deserialize_with = "version_trim_whitespace")]
version: MaybeWorkspaceSemverVersion,
authors: Option<MaybeWorkspaceVecString>,
build: Option<StringOrBool>,
metabuild: Option<StringOrVec>,
- #[serde(rename = "default-target")]
default_target: Option<String>,
- #[serde(rename = "forced-target")]
forced_target: Option<String>,
links: Option<String>,
exclude: Option<MaybeWorkspaceVecString>,
@@ -1537,6 +1433,10 @@ pub struct TomlPackage {
repository: Option<MaybeWorkspaceString>,
resolver: Option<String>,
+ // Provide a helpful error message for a common user error.
+ #[serde(rename = "cargo-features", skip_serializing)]
+ _invalid_cargo_features: Option<InvalidCargoFeatures>,
+
// Note that this field must come last due to the way toml serialization
// works which requires tables to be emitted after all values.
metadata: Option<toml::Value>,
@@ -1553,7 +1453,7 @@ pub struct TomlWorkspace {
// Properties that can be inherited by members.
package: Option<InheritableFields>,
dependencies: Option<BTreeMap<String, TomlDependency>>,
- lints: Option<toml::Value>,
+ lints: Option<TomlLints>,
// Note that this field must come last due to the way toml serialization
// works which requires tables to be emitted after all values.
@@ -1588,7 +1488,7 @@ pub struct InheritableFields {
exclude: Option<Vec<String>>,
include: Option<Vec<String>>,
#[serde(rename = "rust-version")]
- rust_version: Option<String>,
+ rust_version: Option<RustVersion>,
// We use skip here since it will never be present when deserializing
// and we don't want it present when serializing
#[serde(skip)]
@@ -1628,7 +1528,7 @@ impl InheritableFields {
("package.license", license -> String),
("package.publish", publish -> VecStringOrBool),
("package.repository", repository -> String),
- ("package.rust-version", rust_version -> String),
+ ("package.rust-version", rust_version -> RustVersion),
("package.version", version -> semver::Version),
}
@@ -1857,10 +1757,7 @@ impl TomlManifest {
deps: Option<&BTreeMap<String, MaybeWorkspaceDependency>>,
filter: impl Fn(&TomlDependency) -> bool,
) -> CargoResult<Option<BTreeMap<String, MaybeWorkspaceDependency>>> {
- let deps = match deps {
- Some(deps) => deps,
- None => return Ok(None),
- };
+ let Some(deps) = deps else { return Ok(None) };
let deps = deps
.iter()
.filter(|(_k, v)| {
@@ -1940,6 +1837,13 @@ impl TomlManifest {
}
}
+ if !package_root.is_dir() {
+ bail!(
+ "package root '{}' is not a directory",
+ package_root.display()
+ );
+ };
+
let mut nested_paths = vec![];
let mut warnings = vec![];
let mut errors = vec![];
@@ -1979,7 +1883,7 @@ impl TomlManifest {
let mut inheritable = toml_config.package.clone().unwrap_or_default();
inheritable.update_ws_path(package_root.to_path_buf());
inheritable.update_deps(toml_config.dependencies.clone());
- let lints = parse_unstable_lints(toml_config.lints.clone(), config, &mut warnings)?;
+ let lints = toml_config.lints.clone();
let lints = verify_lints(lints)?;
inheritable.update_lints(lints);
if let Some(ws_deps) = &inheritable.dependencies {
@@ -2065,11 +1969,7 @@ impl TomlManifest {
let rust_version = rust_version
.clone()
.resolve("rust_version", || inherit()?.rust_version())?;
- let req = match semver::VersionReq::parse(&rust_version) {
- // Exclude semver operators like `^` and pre-release identifiers
- Ok(req) if rust_version.chars().all(|c| c.is_ascii_digit() || c == '.') => req,
- _ => bail!("`rust-version` must be a value like \"1.32\""),
- };
+ let req = rust_version.caret_req();
if let Some(first_version) = edition.first_version() {
let unsupported =
semver::Version::new(first_version.major, first_version.minor - 1, 9999);
@@ -2083,7 +1983,7 @@ impl TomlManifest {
)
}
}
- Some(rust_version.clone())
+ Some(rust_version)
} else {
None
};
@@ -2173,9 +2073,8 @@ impl TomlManifest {
workspace_config: &WorkspaceConfig,
inherit_cell: &LazyCell<InheritableFields>,
) -> CargoResult<Option<BTreeMap<String, MaybeWorkspaceDependency>>> {
- let dependencies = match new_deps {
- Some(dependencies) => dependencies,
- None => return Ok(None),
+ let Some(dependencies) = new_deps else {
+ return Ok(None);
};
let inheritable = || {
@@ -2245,10 +2144,11 @@ impl TomlManifest {
&inherit_cell,
)?;
- let lints =
- parse_unstable_lints::<MaybeWorkspaceLints>(me.lints.clone(), config, cx.warnings)?
- .map(|mw| mw.resolve("lints", || inherit()?.lints()))
- .transpose()?;
+ let lints = me
+ .lints
+ .clone()
+ .map(|mw| mw.resolve(|| inherit()?.lints()))
+ .transpose()?;
let lints = verify_lints(lints)?;
let default = TomlLints::default();
let rustflags = lints_to_rustflags(lints.as_ref().unwrap_or(&default));
@@ -2319,7 +2219,7 @@ impl TomlManifest {
let mut names_sources = BTreeMap::new();
for dep in &deps {
let name = dep.name_in_toml();
- let prev = names_sources.insert(name.to_string(), dep.source_id());
+ let prev = names_sources.insert(name, dep.source_id());
if prev.is_some() && prev != Some(dep.source_id()) {
bail!(
"Dependency '{}' has different source paths depending on the build \
@@ -2350,7 +2250,7 @@ impl TomlManifest {
deps,
me.features.as_ref().unwrap_or(&empty_features),
package.links.as_deref(),
- rust_version.as_deref().map(InternedString::new),
+ rust_version.clone(),
)?;
let metadata = ManifestMetadata {
@@ -2420,7 +2320,6 @@ impl TomlManifest {
links: package.links.clone(),
rust_version: package
.rust_version
- .clone()
.map(|mw| mw.resolve("rust-version", || inherit()?.rust_version()))
.transpose()?,
};
@@ -2550,8 +2449,10 @@ impl TomlManifest {
.badges
.as_ref()
.map(|_| MaybeWorkspace::Defined(metadata.badges.clone())),
- lints: lints
- .map(|lints| toml::Value::try_from(MaybeWorkspaceLints::Defined(lints)).unwrap()),
+ lints: lints.map(|lints| MaybeWorkspaceLints {
+ workspace: false,
+ lints,
+ }),
};
let mut manifest = Manifest::new(
summary,
@@ -2683,7 +2584,7 @@ impl TomlManifest {
let mut inheritable = toml_config.package.clone().unwrap_or_default();
inheritable.update_ws_path(root.to_path_buf());
inheritable.update_deps(toml_config.dependencies.clone());
- let lints = parse_unstable_lints(toml_config.lints.clone(), config, &mut warnings)?;
+ let lints = toml_config.lints.clone();
let lints = verify_lints(lints)?;
inheritable.update_lints(lints);
let ws_root_config = WorkspaceRootConfig::new(
@@ -2756,8 +2657,8 @@ impl TomlManifest {
replacement.unused_keys(),
&mut cx.warnings,
);
- dep.set_version_req(VersionReq::exact(version))
- .lock_version(version);
+ dep.set_version_req(OptVersionReq::exact(&version))
+ .lock_version(&version);
replace.push((spec, dep));
}
Ok(replace)
@@ -2830,55 +2731,6 @@ impl TomlManifest {
}
}
-fn parse_unstable_lints<T: Deserialize<'static>>(
- lints: Option<toml::Value>,
- config: &Config,
- warnings: &mut Vec<String>,
-) -> CargoResult<Option<T>> {
- let Some(lints) = lints else {
- return Ok(None);
- };
-
- if !config.cli_unstable().lints {
- warn_for_lint_feature(config, warnings);
- return Ok(None);
- }
-
- lints.try_into().map(Some).map_err(|err| err.into())
-}
-
-fn warn_for_lint_feature(config: &Config, warnings: &mut Vec<String>) {
- use std::fmt::Write as _;
-
- let key_name = "lints";
- let feature_name = "lints";
-
- let mut message = String::new();
-
- let _ = write!(
- message,
- "unused manifest key `{key_name}` (may be supported in a future version)"
- );
- if config.nightly_features_allowed {
- let _ = write!(
- message,
- "
-
-consider passing `-Z{feature_name}` to enable this feature."
- );
- } else {
- let _ = write!(
- message,
- "
-
-this Cargo does not support nightly features, but if you
-switch to nightly channel you can pass
-`-Z{feature_name}` to enable this feature.",
- );
- }
- warnings.push(message);
-}
-
fn verify_lints(lints: Option<TomlLints>) -> CargoResult<Option<TomlLints>> {
let Some(lints) = lints else {
return Ok(None);
@@ -3302,7 +3154,7 @@ impl<P: ResolveToPath + Clone> DetailedTomlDependency<P> {
self.target.as_deref(),
) {
if cx.config.cli_unstable().bindeps {
- let artifact = Artifact::parse(artifact, is_lib, target)?;
+ let artifact = Artifact::parse(&artifact.0, is_lib, target)?;
if dep.kind() != DepKind::Build
&& artifact.target() == Some(ArtifactTarget::BuildDependencyAssumeTarget)
{
@@ -3493,17 +3345,63 @@ impl fmt::Debug for PathValue {
}
}
+#[derive(Deserialize, Serialize, Debug, Clone)]
+#[serde(expecting = "a lints table")]
+pub struct MaybeWorkspaceLints {
+ #[serde(skip_serializing_if = "is_false")]
+ #[serde(deserialize_with = "bool_no_false", default)]
+ workspace: bool,
+ #[serde(flatten)]
+ lints: TomlLints,
+}
+
+fn is_false(b: &bool) -> bool {
+ !b
+}
+
+impl MaybeWorkspaceLints {
+ fn resolve<'a>(
+ self,
+ get_ws_inheritable: impl FnOnce() -> CargoResult<TomlLints>,
+ ) -> CargoResult<TomlLints> {
+ if self.workspace {
+ if !self.lints.is_empty() {
+ anyhow::bail!("cannot override `workspace.lints` in `lints`, either remove the overrides or `lints.workspace = true` and manually specify the lints");
+ }
+ get_ws_inheritable().with_context(|| {
+ "error inheriting `lints` from workspace root manifest's `workspace.lints`"
+ })
+ } else {
+ Ok(self.lints)
+ }
+ }
+}
+
pub type TomlLints = BTreeMap<String, TomlToolLints>;
pub type TomlToolLints = BTreeMap<String, TomlLint>;
-#[derive(Serialize, Deserialize, Debug, Clone)]
+#[derive(Serialize, Debug, Clone)]
#[serde(untagged)]
pub enum TomlLint {
Level(TomlLintLevel),
Config(TomlLintConfig),
}
+impl<'de> Deserialize<'de> for TomlLint {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ UntaggedEnumVisitor::new()
+ .string(|string| {
+ TomlLintLevel::deserialize(string.into_deserializer()).map(TomlLint::Level)
+ })
+ .map(|map| map.deserialize().map(TomlLint::Config))
+ .deserialize(deserializer)
+ }
+}
+
impl TomlLint {
fn level(&self) -> TomlLintLevel {
match self {
@@ -3547,3 +3445,20 @@ impl TomlLintLevel {
}
}
}
+
+#[derive(Copy, Clone, Debug)]
+#[non_exhaustive]
+struct InvalidCargoFeatures {}
+
+impl<'de> de::Deserialize<'de> for InvalidCargoFeatures {
+ fn deserialize<D>(_d: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ use serde::de::Error as _;
+
+ Err(D::Error::custom(
+ "the field `cargo-features` should be set at the top of Cargo.toml before any tables",
+ ))
+ }
+}
diff --git a/src/tools/cargo/src/cargo/util/toml/targets.rs b/src/tools/cargo/src/cargo/util/toml/targets.rs
index a7e30c61b..afc4f258f 100644
--- a/src/tools/cargo/src/cargo/util/toml/targets.rs
+++ b/src/tools/cargo/src/cargo/util/toml/targets.rs
@@ -171,10 +171,7 @@ fn clean_lib(
}),
};
- let lib = match lib {
- Some(ref lib) => lib,
- None => return Ok(None),
- };
+ let Some(ref lib) = lib else { return Ok(None) };
lib.validate_proc_macro(warnings);
lib.validate_crate_types("library", warnings);
@@ -747,7 +744,7 @@ https://github.com/rust-lang/cargo/issues/5330",
fn inferred_to_toml_targets(inferred: &[(String, PathBuf)]) -> Vec<TomlTarget> {
inferred
.iter()
- .map(|&(ref name, ref path)| TomlTarget {
+ .map(|(name, path)| TomlTarget {
name: Some(name.clone()),
path: Some(PathValue(path.clone())),
..TomlTarget::new()
@@ -929,8 +926,8 @@ fn target_path(
let mut matching = inferred
.iter()
- .filter(|&&(ref n, _)| n == &name)
- .map(|&(_, ref p)| p.clone());
+ .filter(|(n, _)| n == &name)
+ .map(|(_, p)| p.clone());
let first = matching.next();
let second = matching.next();
diff --git a/src/tools/cargo/src/doc/book.toml b/src/tools/cargo/src/doc/book.toml
index 1dd1f8e0f..ae8280d28 100644
--- a/src/tools/cargo/src/doc/book.toml
+++ b/src/tools/cargo/src/doc/book.toml
@@ -6,3 +6,4 @@ author = "Alex Crichton, Steve Klabnik and Carol Nichols, with contributions fro
curly-quotes = true # Enable smart-punctuation feature for more than quotes.
git-repository-url = "https://github.com/rust-lang/cargo/tree/master/src/doc/src"
edit-url-template = "https://github.com/rust-lang/cargo/edit/master/src/doc/{path}"
+search.use-boolean-and = true
diff --git a/src/tools/cargo/src/doc/contrib/src/SUMMARY.md b/src/tools/cargo/src/doc/contrib/src/SUMMARY.md
index 053a9db35..f8796b3f3 100644
--- a/src/tools/cargo/src/doc/contrib/src/SUMMARY.md
+++ b/src/tools/cargo/src/doc/contrib/src/SUMMARY.md
@@ -7,6 +7,7 @@
- [Working on Cargo](./process/working-on-cargo.md)
- [Release process](./process/release.md)
- [Unstable features](./process/unstable.md)
+ - [Security issues](./process/security.md)
- [Design Principles](./design.md)
- [Implementing a Change](./implementation/index.md)
- [Architecture](./implementation/architecture.md)
diff --git a/src/tools/cargo/src/doc/contrib/src/implementation/debugging.md b/src/tools/cargo/src/doc/contrib/src/implementation/debugging.md
index 03940e2ff..c3a8e0423 100644
--- a/src/tools/cargo/src/doc/contrib/src/implementation/debugging.md
+++ b/src/tools/cargo/src/doc/contrib/src/implementation/debugging.md
@@ -16,12 +16,12 @@ CARGO_LOG=debug cargo generate-lockfile
CARGO_LOG=cargo::core::resolver=trace cargo generate-lockfile
# This will print lots of info about the download process. `trace` prints even more.
-CARGO_HTTP_DEBUG=true CARGO_LOG=cargo::ops::registry=debug cargo fetch
+CARGO_HTTP_DEBUG=true CARGO_LOG=network=debug cargo fetch
# This is an important command for diagnosing fingerprint issues.
CARGO_LOG=cargo::core::compiler::fingerprint=trace cargo build
```
[`tracing`]: https://docs.rs/tracing
-[directive]: https://docs.rs/tracing_subscriber/filter/struct.EnvFilter.html#directives
-[shorthand macros]: https://docs.rs/tracing/index.html#shorthand-macros
+[directive]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
+[shorthand macros]: https://docs.rs/tracing/latest/tracing/index.html#shorthand-macros
diff --git a/src/tools/cargo/src/doc/contrib/src/process/security.md b/src/tools/cargo/src/doc/contrib/src/process/security.md
new file mode 100644
index 000000000..84e587d7a
--- /dev/null
+++ b/src/tools/cargo/src/doc/contrib/src/process/security.md
@@ -0,0 +1,136 @@
+# Security issues
+
+Issues involving reporting a security vulnerability in cargo usually start by following the [Rust security policy].
+The Security Response Working Group ("the WG") is responsible for running the process of handling the response to a security issue.
+Their process is documented at [Handling Reports].
+This document gives an overview of the process from a Cargo team member's perspective.
+
+The general order of events happens as follows:
+
+1. The "reporter" (even if it is a Cargo team member) reports an issue to <security@rust-lang.org>.
+1. The WG will evaluate if the report is credible, and manages responses to the reporter.
+1. The WG will start a private Zulip stream to coordinate discussion and plans for a fix.
+1. The WG will pull in one or more team members into the Zulip stream ("responders").
+ - Security vulnerabilities are **embargoed** until they are released publicly.
+ People who are brought into these discussions should **not** discuss the issue with *anyone* outside of the group, including your employer, without first consulting The WG.
+1. A discussion then starts to evaluate the severity of the issue and what possible solutions should be considered.
+ This includes figuring out who will volunteer to actually develop the patches to resolve the issue, and who will review it.
+1. The WG will create a temporary private fork of the `rust-lang/cargo` repo using GitHub's [repository security advisory][github-advisory] system.
+ This provides a space where changes can be securely posted, and the security advisory can be drafted.
+ See ["Collaborating in a temporary private fork"][private-fork] for some screenshots of what this looks like.
+ GitHub includes instructions on how to work with the fork.
+
+ Beware that the private fork has some limitations, such as not supporting CI, or (for some weird reason) not supporting syntax highlighting.
+1. Someone will need to review the patches and make sure everyone agrees on the solution.
+ This may also involve the WG conferring with the reporter to validate the fix.
+1. Create a rollout plan.
+ This includes deciding if there will be a new patch release of Rust, or if it should wait for the next stable release, or whether to remove the embargo on the fix.
+1. The WG will handle drafting a Security Advisory using GitHub's Security Advisory ("GHSA") system.
+ [GHSA-r5w3-xm58-jv6j] is an example of what this looks like.
+ This process also involves reserving a [CVE](https://www.cve.org/) number, where the report will eventually be posted.
+
+ The responders should carefully review the report to make sure it is correct.
+
+ This process may also involve deciding on the CVSS score.
+ There are a bunch of calculators on the web where you can see how this works (such as the [FIRST CVSS Calculator][calc], or you can view GitHub's calculator by drafting a security advisory in one of your personal repos).
+ FIRST has a [user guide][first-guide] for deciding how to score each characteristic.
+1. If it is decided to do a patch release of Rust, the general overview of steps is:
+ 1. Finalizing the patches.
+ This includes all the little details like updating changelogs, version numbers, and such.
+ 1. Preparing PRs in the private fork against the stable, beta, and nightly (master) branches.
+ 1. The WG handles creating a private fork of `rust-lang/rust` to prepare the point release.
+ This usually includes changes for stable, beta, and nightly.
+ 1. The WG handles posting patches in various places (such as mailing lists), possibly several days in advance.
+ 1. The WG handles posting public PRs to `rust-lang/rust` to incorporate the fix and prepare a new release.
+ 1. The WG handles announcing everything, including publishing the GHSA, publishing a blog post, and several other places.
+
+## External dependency patches
+
+Sometimes it may be necessary to make changes to external dependencies to support a fix.
+This can make things complicated.
+If the change is by itself benign and not directly related to the security issue,
+then it may be safe to publicly propose the change (but not giving context) and try to get a new release of the dependency made (though confer with the WG first!).
+However, if the issue is directly related to the dependency, then it becomes significantly more awkward.
+
+The general process for [GHSA-r5w3-xm58-jv6j] which involved a fix in `git2-rs` was handled by the responders because it is a dependency owned by the rust-lang org.
+The general outline of how we managed this is:
+
+- Pre-release:
+ 1. Created a private fork of `rust-lang/git2-rs` just like we did for `rust-lang/cargo`.
+ git2-rs also had its own Security Advisory just like cargo did.
+ 1. Created and reviewed PRs in the private fork for the fixes.
+ - The PRs in the `rust-lang/cargo` private fork had to have a temporary `[patch]` git dependency on the `git2-rs` private fork.
+ 1. Before the release, the PRs were changed to remove the `[patch]`, and pretend as-if git2-rs had already been published.
+- Showtime:
+ 1. The git2-rs changes were publicly merged, and a new release was published to crates.io.
+ 1. The cargo PR was merged to cargo's stable branch.
+ 1. The private rust-lang/rust PR updated the cargo submodule and updated `Cargo.lock` to pick up the new git2 dependencies.
+ 1. Release proceeds as normal (publish both GHSA, create release, etc.).
+- Post-release:
+ 1. Various forward ports were created in git2-rs, and new releases were made.
+
+If the change is in a crate not managed by any responder, then confer with the WG on a strategy.
+One option is to create a temporary fork used for the security response that will be removed as soon as the security advisory is released and a new public release of the dependency is made with the fix.
+
+## Checklist
+
+There are a lot of details to handle, and it can be a bit of a challenge under time pressure.
+The following is a checklist of some items to pay attention to during the process.
+
+Pre-release:
+- [ ] Check for any SemVer-incompatible changes in the public API of any crates that are modified.
+ - Try to avoid these if at all possible.
+ Although not a severe problem, making Cargo's version number drift farther from Rust's can contribute to confusion.
+ - If a SemVer-breaking release is made to a dependency, make sure this is coordinated correctly between the stable, beta, and master branches.
+- [ ] With a checkout of the proposed fixes, run as much of cargo's CI testsuite locally as you can.
+ Since private forks don't support CI, the responders will be responsible for making sure all tests pass.
+ Enlist other responders if you don't have the necessary systems like Windows.
+- [ ] Manually exercise the fix locally.
+ Since we will essentially have *no* nightly testing, the responders are responsible for making sure things work.
+ Try to consider all the different environments users may be using.
+- [ ] Make sure any comments or docs that need updating get updated.
+- [ ] Review the git commit messages of the patch.
+ Make sure they clearly and accurately reflect what is being changed and why.
+ Clean up the commit history if it goes through several revisions during review.
+- [ ] Make sure that the *public* cargo repo's stable and beta branches are in a state where they are passing CI.
+ This may require backporting changes that fix problems that have already been fixed in master.
+ This can be done publicly at any time, and helps with ensuring a smooth process once the security issue is released.
+ (The WG may disable branch protections to push directly to the stable branch, but this step is still useful to assist with local testing and the beta branch.)
+- [ ] After the fix is approved, create backports to the stable and beta master branches and post PRs to the private fork.
+- [ ] If any internal dependencies are changed, make sure their versions are bumped appropriately, and dependency specifications are updated (stable, beta, and master branches).
+- [ ] Thoroughly test the stable and beta PRs locally, too. We want to make sure everything goes smoothly, and we can't assume that just because a patch applied cleanly that there won't be issues.
+- [ ] Make sure cargo's version in [`Cargo.toml`] is updated correctly on the stable branch private PR.
+- [ ] Make sure cargo's `Cargo.lock` is updated (stable, beta, master branches).
+- [ ] Update [`CHANGELOG.md`] on cargo's master branch private PR.
+- [ ] Update [`RELEASES.md`] on rust's master branch private PR (and stable and beta?).
+- [ ] Remove any temporary things in the patch, like a temporary `[patch]` table.
+
+Showtime:
+- [ ] Publish any embargoed external dependencies to crates.io.
+- [ ] (WG) Merge the cargo stable change.
+- [ ] (WG) Update the cargo submodule in the rust-lang/rust private PR to point to the new stable commit.
+ - [ ] Also update `Cargo.lock`.
+- [ ] (WG) Make a new stable release.
+- [ ] (WG) Publish the GHSA.
+- [ ] (WG) Send announcements.
+- [ ] Make sure stable, beta, and master branches of `rust-lang/cargo` get updated.
+- [ ] Make sure stable, beta, and master branches of `rust-lang/rust` get updated, pointing to the correct submodule versions.
+- [ ] If any external dependencies are updated, make sure their back or forward ports are handled.
+
+Post release:
+- [ ] Verify that the appropriate crates are published on crates.io.
+- [ ] Verify that `rust-lang/cargo` got a new tag.
+- [ ] Verify that the patches were backported to the correct branches in the `rust-lang/cargo` repository (stable, beta, and master).
+- [ ] Verify that the cargo submodule is updated on the correct branches in the `rust-lang/rust` repository (stable, beta, and master).
+- [ ] Follow up on any non-critical tasks that were identified during review.
+
+[Rust security policy]: https://www.rust-lang.org/policies/security
+[github-advisory]: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories
+[private-fork]: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-repository-security-vulnerability
+[calc]: https://www.first.org/cvss/calculator
+[GHSA-r5w3-xm58-jv6j]: https://github.com/rust-lang/cargo/security/advisories/GHSA-r5w3-xm58-jv6j
+[handling reports]: https://github.com/rust-lang/wg-security-response/blob/main/docs/handling-reports.md
+[first-guide]: https://www.first.org/cvss/user-guide
+[`CHANGELOG.md`]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md
+[`Cargo.toml`]: https://github.com/rust-lang/cargo/blob/master/Cargo.toml
+[`RELEASES.md`]: https://github.com/rust-lang/rust/blob/master/RELEASES.md
diff --git a/src/tools/cargo/src/doc/man/cargo-add.md b/src/tools/cargo/src/doc/man/cargo-add.md
index 3c15fc9d5..21c222a39 100644
--- a/src/tools/cargo/src/doc/man/cargo-add.md
+++ b/src/tools/cargo/src/doc/man/cargo-add.md
@@ -1,7 +1,7 @@
# cargo-add(1)
-
-{{*set actionverb="Add"}}
-{{*set nouns="adds"}}
+{{~*set command="add"}}
+{{~*set actionverb="Add"}}
+{{~*set nouns="adds"}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-bench.md b/src/tools/cargo/src/doc/man/cargo-bench.md
index 18771c3d2..a2a602847 100644
--- a/src/tools/cargo/src/doc/man/cargo-bench.md
+++ b/src/tools/cargo/src/doc/man/cargo-bench.md
@@ -1,7 +1,8 @@
# cargo-bench(1)
-{{*set actionverb="Benchmark"}}
-{{*set nouns="benchmarks"}}
-{{*set multitarget=true}}
+{{~*set command="bench"}}
+{{~*set actionverb="Benchmark"}}
+{{~*set nouns="benchmarks"}}
+{{~*set multitarget=true}}
## NAME
@@ -157,9 +158,16 @@ Rust test harness runs benchmarks serially in a single thread.
{{#options}}
{{> options-jobs }}
-{{> options-keep-going }}
{{/options}}
+While `cargo bench` involves compilation, it does not provide a `--keep-going`
+flag. Use `--no-fail-fast` to run as many benchmarks as possible without
+stopping at the first failure. To "compile" as many benchmarks as possible, use
+`--benches` to build benchmark binaries separately. For example:
+
+ cargo build --benches --release --keep-going
+ cargo bench --no-fail-fast
+
{{> section-environment }}
{{> section-exit-status }}
diff --git a/src/tools/cargo/src/doc/man/cargo-build.md b/src/tools/cargo/src/doc/man/cargo-build.md
index 986144443..18d6eeae8 100644
--- a/src/tools/cargo/src/doc/man/cargo-build.md
+++ b/src/tools/cargo/src/doc/man/cargo-build.md
@@ -1,6 +1,7 @@
# cargo-build(1)
-{{*set actionverb="Build"}}
-{{*set multitarget=true}}
+{{~*set command="build"}}
+{{~*set actionverb="Build"}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-check.md b/src/tools/cargo/src/doc/man/cargo-check.md
index 055adff0d..92c8a5d07 100644
--- a/src/tools/cargo/src/doc/man/cargo-check.md
+++ b/src/tools/cargo/src/doc/man/cargo-check.md
@@ -1,6 +1,7 @@
# cargo-check(1)
-{{*set actionverb="Check"}}
-{{*set multitarget=true}}
+{{~*set command="check"}}
+{{~*set actionverb="Check"}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-clean.md b/src/tools/cargo/src/doc/man/cargo-clean.md
index 3222f7bb0..ee920b223 100644
--- a/src/tools/cargo/src/doc/man/cargo-clean.md
+++ b/src/tools/cargo/src/doc/man/cargo-clean.md
@@ -1,6 +1,7 @@
# cargo-clean(1)
-{{*set actionverb="Clean"}}
-{{*set multitarget=true}}
+{{~*set command="clean"}}
+{{~*set actionverb="Clean"}}
+{{~*set multitarget=true}}
## NAME
@@ -35,6 +36,11 @@ multiple times. See {{man "cargo-pkgid" 1}} for the SPEC format.
{{#options}}
+{{#option "`--dry-run`" }}
+Displays a summary of what would be deleted without deleting anything.
+Use with `--verbose` to display the actual files that would be deleted.
+{{/option}}
+
{{#option "`--doc`" }}
This option will cause `cargo clean` to remove only the `doc` directory in
the target directory.
diff --git a/src/tools/cargo/src/doc/man/cargo-doc.md b/src/tools/cargo/src/doc/man/cargo-doc.md
index 9d5b77648..b2e273ee5 100644
--- a/src/tools/cargo/src/doc/man/cargo-doc.md
+++ b/src/tools/cargo/src/doc/man/cargo-doc.md
@@ -1,6 +1,7 @@
# cargo-doc(1)
-{{*set actionverb="Document"}}
-{{*set multitarget=true}}
+{{~*set command="doc"}}
+{{~*set actionverb="Document"}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-fetch.md b/src/tools/cargo/src/doc/man/cargo-fetch.md
index c31166a9b..b8a0eb666 100644
--- a/src/tools/cargo/src/doc/man/cargo-fetch.md
+++ b/src/tools/cargo/src/doc/man/cargo-fetch.md
@@ -1,7 +1,8 @@
# cargo-fetch(1)
-{{*set actionverb="Fetch"}}
-{{*set target-default-to-all-arch=true}}
-{{*set multitarget=true}}
+{{~*set command="fetch"}}
+{{~*set actionverb="Fetch"}}
+{{~*set target-default-to-all-arch=true}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-fix.md b/src/tools/cargo/src/doc/man/cargo-fix.md
index 64fe29944..89fb81cef 100644
--- a/src/tools/cargo/src/doc/man/cargo-fix.md
+++ b/src/tools/cargo/src/doc/man/cargo-fix.md
@@ -1,6 +1,7 @@
# cargo-fix(1)
-{{*set actionverb="Fix"}}
-{{*set multitarget=true}}
+{{~*set command="fix"}}
+{{~*set actionverb="Fix"}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-install.md b/src/tools/cargo/src/doc/man/cargo-install.md
index e6786318f..5431bdb79 100644
--- a/src/tools/cargo/src/doc/man/cargo-install.md
+++ b/src/tools/cargo/src/doc/man/cargo-install.md
@@ -1,6 +1,7 @@
# cargo-install(1)
-{{*set actionverb="Install"}}
-{{*set temp-target-dir=true}}
+{{~*set command="install"}}
+{{~*set actionverb="Install"}}
+{{~*set temp-target-dir=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-login.md b/src/tools/cargo/src/doc/man/cargo-login.md
index 54c823d2d..197636da8 100644
--- a/src/tools/cargo/src/doc/man/cargo-login.md
+++ b/src/tools/cargo/src/doc/man/cargo-login.md
@@ -2,18 +2,25 @@
## NAME
-cargo-login --- Save an API token from the registry locally
+cargo-login --- Log in to a registry
## SYNOPSIS
-`cargo login` [_options_] [_token_]
+`cargo login` [_options_] [_token_] -- [_args_]
## DESCRIPTION
-This command will save the API token to disk so that commands that require
-authentication, such as {{man "cargo-publish" 1}}, will be automatically
-authenticated. The token is saved in `$CARGO_HOME/credentials.toml`. `CARGO_HOME`
-defaults to `.cargo` in your home directory.
+This command will run a credential provider to save a token so that commands
+that require authentication, such as {{man "cargo-publish" 1}}, will be
+automatically authenticated.
+
+For the default `cargo:token` credential provider, the token is saved
+in `$CARGO_HOME/credentials.toml`. `CARGO_HOME` defaults to `.cargo`
+in your home directory.
+
+If a registry has a credential-provider specified, it will be used. Otherwise,
+the providers from the config value `registry.global-credential-providers` will
+be attempted, starting from the end of the list.
If the _token_ argument is not specified, it will be read from stdin.
@@ -43,9 +50,13 @@ Take care to keep the token secret, it should not be shared with anyone else.
## EXAMPLES
-1. Save the API token to disk:
+1. Save the token for the default registry:
cargo login
+2. Save the token for a specific registry:
+
+ cargo login --registry my-registry
+
## SEE ALSO
{{man "cargo" 1}}, {{man "cargo-logout" 1}}, {{man "cargo-publish" 1}}
diff --git a/src/tools/cargo/src/doc/man/cargo-logout.md b/src/tools/cargo/src/doc/man/cargo-logout.md
index f9c0db58c..d8277bf54 100644
--- a/src/tools/cargo/src/doc/man/cargo-logout.md
+++ b/src/tools/cargo/src/doc/man/cargo-logout.md
@@ -10,9 +10,15 @@ cargo-logout --- Remove an API token from the registry locally
## DESCRIPTION
-This command will remove the API token from the local credential storage.
-Credentials are stored in `$CARGO_HOME/credentials.toml` where `$CARGO_HOME`
-defaults to `.cargo` in your home directory.
+This command will run a credential provider to remove a saved token.
+
+For the default `cargo:token` credential provider, credentials are stored
+in `$CARGO_HOME/credentials.toml` where `$CARGO_HOME` defaults to `.cargo`
+in your home directory.
+
+If a registry has a credential-provider specified, it will be used. Otherwise,
+the providers from the config value `registry.global-credential-providers` will
+be attempted, starting from the end of the list.
If `--registry` is not specified, then the credentials for the default
registry will be removed (configured by
diff --git a/src/tools/cargo/src/doc/man/cargo-metadata.md b/src/tools/cargo/src/doc/man/cargo-metadata.md
index 8efb29a97..b7d04530d 100644
--- a/src/tools/cargo/src/doc/man/cargo-metadata.md
+++ b/src/tools/cargo/src/doc/man/cargo-metadata.md
@@ -27,7 +27,7 @@ for a Rust API for reading the metadata.
Within the same output format version, the compatibility is maintained, except
some scenarios. The following is a non-exhaustive list of changes that are not
-considersed as incompatibile:
+considersed as incompatible:
* **Adding new fields** — New fields will be added when needed. Reserving this
helps Cargo evolve without bumping the format version too often.
diff --git a/src/tools/cargo/src/doc/man/cargo-package.md b/src/tools/cargo/src/doc/man/cargo-package.md
index 2000353cc..5057e59fe 100644
--- a/src/tools/cargo/src/doc/man/cargo-package.md
+++ b/src/tools/cargo/src/doc/man/cargo-package.md
@@ -1,7 +1,8 @@
# cargo-package(1)
-{{*set actionverb="Package"}}
-{{*set noall=true}}
-{{*set multitarget=true}}
+{{~*set command="package"}}
+{{~*set actionverb="Package"}}
+{{~*set noall=true}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-publish.md b/src/tools/cargo/src/doc/man/cargo-publish.md
index 4ccb5b529..c5e64db80 100644
--- a/src/tools/cargo/src/doc/man/cargo-publish.md
+++ b/src/tools/cargo/src/doc/man/cargo-publish.md
@@ -1,6 +1,7 @@
# cargo-publish(1)
-{{*set actionverb="Publish"}}
-{{*set multitarget=true}}
+{{~*set command="publish"}}
+{{~*set actionverb="Publish"}}
+{{~*set multitarget=true}}
## NAME
@@ -21,8 +22,11 @@ following steps:
- Checks the `package.publish` key in the manifest for restrictions on
which registries you are allowed to publish to.
2. Create a `.crate` file by following the steps in {{man "cargo-package" 1}}.
-3. Upload the crate to the registry. Note that the server will perform
- additional checks on the crate.
+3. Upload the crate to the registry. The server will perform additional
+ checks on the crate.
+4. The client will poll waiting for the package to appear in the index,
+ and may timeout. In that case, you will need to check for completion
+ manually. This timeout does not affect the upload.
This command requires you to be authenticated with either the `--token` option
or using {{man "cargo-login" 1}}.
diff --git a/src/tools/cargo/src/doc/man/cargo-remove.md b/src/tools/cargo/src/doc/man/cargo-remove.md
index e38589ccb..0bdb04ac6 100644
--- a/src/tools/cargo/src/doc/man/cargo-remove.md
+++ b/src/tools/cargo/src/doc/man/cargo-remove.md
@@ -1,6 +1,7 @@
# cargo-remove(1)
-{{*set actionverb="Remove"}}
-{{*set nouns="removes"}}
+{{~*set command="remove"}}
+{{~*set actionverb="Remove"}}
+{{~*set nouns="removes"}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-run.md b/src/tools/cargo/src/doc/man/cargo-run.md
index 034a35f23..8a8ddb309 100644
--- a/src/tools/cargo/src/doc/man/cargo-run.md
+++ b/src/tools/cargo/src/doc/man/cargo-run.md
@@ -1,5 +1,6 @@
# cargo-run(1)
-{{*set actionverb="Run"}}
+{{~*set command="run"}}
+{{~*set actionverb="Run"}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-rustc.md b/src/tools/cargo/src/doc/man/cargo-rustc.md
index 18c0856f2..279c6dbd1 100644
--- a/src/tools/cargo/src/doc/man/cargo-rustc.md
+++ b/src/tools/cargo/src/doc/man/cargo-rustc.md
@@ -1,6 +1,7 @@
# cargo-rustc(1)
-{{*set actionverb="Build"}}
-{{*set multitarget=true}}
+{{~*set command="rustc"}}
+{{~*set actionverb="Build"}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-rustdoc.md b/src/tools/cargo/src/doc/man/cargo-rustdoc.md
index 23be579e9..39f70713c 100644
--- a/src/tools/cargo/src/doc/man/cargo-rustdoc.md
+++ b/src/tools/cargo/src/doc/man/cargo-rustdoc.md
@@ -1,6 +1,7 @@
# cargo-rustdoc(1)
-{{*set actionverb="Document"}}
-{{*set multitarget=true}}
+{{~*set command="rustdoc"}}
+{{~*set actionverb="Document"}}
+{{~*set multitarget=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-test.md b/src/tools/cargo/src/doc/man/cargo-test.md
index cba98b20d..1755ab7de 100644
--- a/src/tools/cargo/src/doc/man/cargo-test.md
+++ b/src/tools/cargo/src/doc/man/cargo-test.md
@@ -1,7 +1,8 @@
# cargo-test(1)
-{{*set actionverb="Test"}}
-{{*set nouns="tests"}}
-{{*set multitarget=true}}
+{{~*set command="test"}}
+{{~*set actionverb="Test"}}
+{{~*set nouns="tests"}}
+{{~*set multitarget=true}}
## NAME
@@ -190,6 +191,14 @@ includes an option to control the number of threads used:
{{/options}}
+While `cargo test` involves compilation, it does not provide a `--keep-going`
+flag. Use `--no-fail-fast` to run as many tests as possible without stopping at
+the first failure. To "compile" as many tests as possible, use `--tests` to
+build test binaries separately. For example:
+
+ cargo build --tests --keep-going
+ cargo test --tests --no-fail-fast
+
{{> section-environment }}
{{> section-exit-status }}
diff --git a/src/tools/cargo/src/doc/man/cargo-tree.md b/src/tools/cargo/src/doc/man/cargo-tree.md
index 3e1da20df..1bb52883c 100644
--- a/src/tools/cargo/src/doc/man/cargo-tree.md
+++ b/src/tools/cargo/src/doc/man/cargo-tree.md
@@ -1,6 +1,7 @@
# cargo-tree(1)
-{{*set actionverb="Display"}}
-{{*set noall=true}}
+{{~*set command="tree"}}
+{{~*set actionverb="Display"}}
+{{~*set noall=true}}
## NAME
diff --git a/src/tools/cargo/src/doc/man/cargo-update.md b/src/tools/cargo/src/doc/man/cargo-update.md
index e91606a6a..b392b8314 100644
--- a/src/tools/cargo/src/doc/man/cargo-update.md
+++ b/src/tools/cargo/src/doc/man/cargo-update.md
@@ -6,7 +6,7 @@ cargo-update --- Update dependencies as recorded in the local lock file
## SYNOPSIS
-`cargo update` [_options_]
+`cargo update` [_options_] _spec_
## DESCRIPTION
@@ -20,26 +20,26 @@ latest available versions.
{{#options}}
-{{#option "`-p` _spec_..." "`--package` _spec_..." }}
+{{#option "_spec_..." }}
Update only the specified packages. This flag may be specified
multiple times. See {{man "cargo-pkgid" 1}} for the SPEC format.
-If packages are specified with the `-p` flag, then a conservative update of
+If packages are specified with _spec_, then a conservative update of
the lockfile will be performed. This means that only the dependency specified
by SPEC will be updated. Its transitive dependencies will be updated only if
SPEC cannot be updated without updating dependencies. All other dependencies
will remain locked at their currently recorded versions.
-If `-p` is not specified, all dependencies are updated.
+If _spec_ is not specified, all dependencies are updated.
{{/option}}
-{{#option "`--aggressive`" }}
-When used with `-p`, dependencies of _spec_ are forced to update as well.
+{{#option "`--recursive`" }}
+When used with _spec_, dependencies of _spec_ are forced to update as well.
Cannot be used with `--precise`.
{{/option}}
{{#option "`--precise` _precise_" }}
-When used with `-p`, allows you to specify a specific version number to set
+When used with _spec_, allows you to specify a specific version number to set
the package to. If the package comes from a git repository, this can be a git
revision (such as a SHA hash or tag).
{{/option}}
@@ -87,11 +87,11 @@ Displays what would be updated, but doesn't actually write the lockfile.
2. Update only specific dependencies:
- cargo update -p foo -p bar
+ cargo update foo bar
3. Set a specific dependency to a specific version:
- cargo update -p foo --precise 1.2.3
+ cargo update foo --precise 1.2.3
## SEE ALSO
{{man "cargo" 1}}, {{man "cargo-generate-lockfile" 1}}
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-bench.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-bench.txt
index 9610b72f0..796fbd11b 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-bench.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-bench.txt
@@ -413,10 +413,14 @@ OPTIONS
If a string default is provided, it sets the value back to defaults.
Should not be 0.
- --keep-going
- Build as many crates in the dependency graph as possible, rather
- than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+ While cargo bench involves compilation, it does not provide a
+ --keep-going flag. Use --no-fail-fast to run as many benchmarks as
+ possible without stopping at the first failure. To “compile” as many
+ benchmarks as possible, use --benches to build benchmark binaries
+ separately. For example:
+
+ cargo build --benches --release --keep-going
+ cargo bench --no-fail-fast
ENVIRONMENT
See the reference
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-build.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-build.txt
index e396410d3..06a7a6b3c 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-build.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-build.txt
@@ -347,7 +347,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo build -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo build -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
--future-incompat-report
Displays a future-incompat report for any future-incompatible
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-check.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-check.txt
index 9814f445d..b447455ee 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-check.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-check.txt
@@ -332,7 +332,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo check -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo check -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
--future-incompat-report
Displays a future-incompat report for any future-incompatible
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-clean.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-clean.txt
index 33cebb719..d6b7facf4 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-clean.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-clean.txt
@@ -22,6 +22,11 @@ OPTIONS
multiple times. See cargo-pkgid(1) for the SPEC format.
Clean Options
+ --dry-run
+ Displays a summary of what would be deleted without deleting
+ anything. Use with --verbose to display the actual files that would
+ be deleted.
+
--doc
This option will cause cargo clean to remove only the doc directory
in the target directory.
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-doc.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-doc.txt
index 09f9b68c9..773d600c6 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-doc.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-doc.txt
@@ -303,7 +303,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo doc -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo doc -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
ENVIRONMENT
See the reference
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-fix.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-fix.txt
index b83c360eb..3e7910ca5 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-fix.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-fix.txt
@@ -405,7 +405,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo fix -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo fix -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
ENVIRONMENT
See the reference
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-install.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-install.txt
index a5b696111..02790f1d0 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-install.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-install.txt
@@ -280,7 +280,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo install -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo install -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
Display Options
-v, --verbose
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-login.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-login.txt
index cce8efcfb..ae8127fc9 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-login.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-login.txt
@@ -1,16 +1,24 @@
CARGO-LOGIN(1)
NAME
- cargo-login — Save an API token from the registry locally
+ cargo-login — Log in to a registry
SYNOPSIS
- cargo login [options] [token]
+ cargo login [options] [token] – [args]
DESCRIPTION
- This command will save the API token to disk so that commands that
- require authentication, such as cargo-publish(1), will be automatically
- authenticated. The token is saved in $CARGO_HOME/credentials.toml.
- CARGO_HOME defaults to .cargo in your home directory.
+ This command will run a credential provider to save a token so that
+ commands that require authentication, such as cargo-publish(1), will be
+ automatically authenticated.
+
+ For the default cargo:token credential provider, the token is saved in
+ $CARGO_HOME/credentials.toml. CARGO_HOME defaults to .cargo in your home
+ directory.
+
+ If a registry has a credential-provider specified, it will be used.
+ Otherwise, the providers from the config value
+ registry.global-credential-providers will be attempted, starting from
+ the end of the list.
If the token argument is not specified, it will be read from stdin.
@@ -102,10 +110,14 @@ EXIT STATUS
o 101: Cargo failed to complete.
EXAMPLES
- 1. Save the API token to disk:
+ 1. Save the token for the default registry:
cargo login
+ 2. Save the token for a specific registry:
+
+ cargo login --registry my-registry
+
SEE ALSO
cargo(1), cargo-logout(1), cargo-publish(1)
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-logout.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-logout.txt
index db21a39b4..73e50d9a4 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-logout.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-logout.txt
@@ -7,9 +7,16 @@ SYNOPSIS
cargo logout [options]
DESCRIPTION
- This command will remove the API token from the local credential
- storage. Credentials are stored in $CARGO_HOME/credentials.toml where
- $CARGO_HOME defaults to .cargo in your home directory.
+ This command will run a credential provider to remove a saved token.
+
+ For the default cargo:token credential provider, credentials are stored
+ in $CARGO_HOME/credentials.toml where $CARGO_HOME defaults to .cargo in
+ your home directory.
+
+ If a registry has a credential-provider specified, it will be used.
+ Otherwise, the providers from the config value
+ registry.global-credential-providers will be attempted, starting from
+ the end of the list.
If --registry is not specified, then the credentials for the default
registry will be removed (configured by registry.default
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-metadata.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-metadata.txt
index 3d37f6bb8..0d14cfe8e 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-metadata.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-metadata.txt
@@ -22,7 +22,7 @@ OUTPUT FORMAT
Compatibility
Within the same output format version, the compatibility is maintained,
except some scenarios. The following is a non-exhaustive list of changes
- that are not considersed as incompatibile:
+ that are not considersed as incompatible:
o Adding new fields — New fields will be added when needed. Reserving
this helps Cargo evolve without bumping the format version too often.
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-package.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-package.txt
index 1201f3d07..195b35144 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-package.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-package.txt
@@ -197,7 +197,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo package -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo package -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
Display Options
-v, --verbose
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-publish.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-publish.txt
index e8850e3d4..ab1337d3c 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-publish.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-publish.txt
@@ -18,8 +18,12 @@ DESCRIPTION
2. Create a .crate file by following the steps in cargo-package(1).
- 3. Upload the crate to the registry. Note that the server will perform
- additional checks on the crate.
+ 3. Upload the crate to the registry. The server will perform additional
+ checks on the crate.
+
+ 4. The client will poll waiting for the package to appear in the index,
+ and may timeout. In that case, you will need to check for completion
+ manually. This timeout does not affect the upload.
This command requires you to be authenticated with either the --token
option or using cargo-login(1).
@@ -163,7 +167,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo publish -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo publish -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
Display Options
-v, --verbose
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-run.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-run.txt
index 5fcfe66b4..495a08a6c 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-run.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-run.txt
@@ -251,7 +251,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo run -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo run -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
ENVIRONMENT
See the reference
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-rustc.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-rustc.txt
index 7a70c5363..af6ad9d59 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-rustc.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-rustc.txt
@@ -349,7 +349,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo rustc -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo rustc -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
--future-incompat-report
Displays a future-incompat report for any future-incompatible
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-rustdoc.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-rustdoc.txt
index 4db66b3a8..5ba200644 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-rustdoc.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-rustdoc.txt
@@ -319,7 +319,13 @@ OPTIONS
--keep-going
Build as many crates in the dependency graph as possible, rather
than aborting the build on the first one that fails to build.
- Unstable, requires -Zunstable-options.
+
+ For example if the current package depends on dependencies fails and
+ works, one of which fails to build, cargo rustdoc -j1 may or may not
+ build the one that succeeds (depending on which one of the two
+ builds Cargo picked to run first), whereas cargo rustdoc -j1
+ --keep-going would definitely run both builds, even if the one run
+ first fails.
ENVIRONMENT
See the reference
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-test.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-test.txt
index dc32bdbf7..b992d0d2f 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-test.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-test.txt
@@ -448,6 +448,14 @@ OPTIONS
See cargo-report(1)
+ While cargo test involves compilation, it does not provide a
+ --keep-going flag. Use --no-fail-fast to run as many tests as possible
+ without stopping at the first failure. To “compile” as many tests as
+ possible, use --tests to build test binaries separately. For example:
+
+ cargo build --tests --keep-going
+ cargo test --tests --no-fail-fast
+
ENVIRONMENT
See the reference
<https://doc.rust-lang.org/cargo/reference/environment-variables.html>
diff --git a/src/tools/cargo/src/doc/man/generated_txt/cargo-update.txt b/src/tools/cargo/src/doc/man/generated_txt/cargo-update.txt
index fb662c389..a96a34c96 100644
--- a/src/tools/cargo/src/doc/man/generated_txt/cargo-update.txt
+++ b/src/tools/cargo/src/doc/man/generated_txt/cargo-update.txt
@@ -4,7 +4,7 @@ NAME
cargo-update — Update dependencies as recorded in the local lock file
SYNOPSIS
- cargo update [options]
+ cargo update [options] spec
DESCRIPTION
This command will update dependencies in the Cargo.lock file to the
@@ -13,25 +13,25 @@ DESCRIPTION
OPTIONS
Update Options
- -p spec…, --package spec…
+ spec…
Update only the specified packages. This flag may be specified
multiple times. See cargo-pkgid(1) for the SPEC format.
- If packages are specified with the -p flag, then a conservative
- update of the lockfile will be performed. This means that only the
- dependency specified by SPEC will be updated. Its transitive
- dependencies will be updated only if SPEC cannot be updated without
- updating dependencies. All other dependencies will remain locked at
- their currently recorded versions.
+ If packages are specified with spec, then a conservative update of
+ the lockfile will be performed. This means that only the dependency
+ specified by SPEC will be updated. Its transitive dependencies will
+ be updated only if SPEC cannot be updated without updating
+ dependencies. All other dependencies will remain locked at their
+ currently recorded versions.
- If -p is not specified, all dependencies are updated.
+ If spec is not specified, all dependencies are updated.
- --aggressive
- When used with -p, dependencies of spec are forced to update as
+ --recursive
+ When used with spec, dependencies of spec are forced to update as
well. Cannot be used with --precise.
--precise precise
- When used with -p, allows you to specify a specific version number
+ When used with spec, allows you to specify a specific version number
to set the package to. If the package comes from a git repository,
this can be a git revision (such as a SHA hash or tag).
@@ -155,11 +155,11 @@ EXAMPLES
2. Update only specific dependencies:
- cargo update -p foo -p bar
+ cargo update foo bar
3. Set a specific dependency to a specific version:
- cargo update -p foo --precise 1.2.3
+ cargo update foo --precise 1.2.3
SEE ALSO
cargo(1), cargo-generate-lockfile(1)
diff --git a/src/tools/cargo/src/doc/man/includes/options-keep-going.md b/src/tools/cargo/src/doc/man/includes/options-keep-going.md
index 034181c0e..928c7f67a 100644
--- a/src/tools/cargo/src/doc/man/includes/options-keep-going.md
+++ b/src/tools/cargo/src/doc/man/includes/options-keep-going.md
@@ -1,5 +1,10 @@
{{#option "`--keep-going`"}}
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-`-Zunstable-options`.
+the build on the first one that fails to build.
+
+For example if the current package depends on dependencies `fails` and `works`,
+one of which fails to build, `cargo {{command}} -j1` may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas `cargo {{command}} -j1 --keep-going` would definitely run both
+builds, even if the one run first fails.
{{/option}}
diff --git a/src/tools/cargo/src/doc/src/SUMMARY.md b/src/tools/cargo/src/doc/src/SUMMARY.md
index 273936559..9ebd7915b 100644
--- a/src/tools/cargo/src/doc/src/SUMMARY.md
+++ b/src/tools/cargo/src/doc/src/SUMMARY.md
@@ -36,6 +36,8 @@
* [Source Replacement](reference/source-replacement.md)
* [External Tools](reference/external-tools.md)
* [Registries](reference/registries.md)
+ * [Registry Authentication](reference/registry-authentication.md)
+ * [Credential Provider Protocol](reference/credential-provider-protocol.md)
* [Running a Registry](reference/running-a-registry.md)
* [Registry Index](reference/registry-index.md)
* [Registry Web API](reference/registry-web-api.md)
diff --git a/src/tools/cargo/src/doc/src/appendix/glossary.md b/src/tools/cargo/src/doc/src/appendix/glossary.md
index 143736851..9186b51c3 100644
--- a/src/tools/cargo/src/doc/src/appendix/glossary.md
+++ b/src/tools/cargo/src/doc/src/appendix/glossary.md
@@ -1,25 +1,25 @@
# Glossary
-### Artifact
+## Artifact
An *artifact* is the file or set of files created as a result of the
compilation process. This includes linkable libraries, executable binaries,
and generated documentation.
-### Cargo
+## Cargo
*Cargo* is the Rust [*package manager*](#package-manager), and the primary
topic of this book.
-### Cargo.lock
+## Cargo.lock
See [*lock file*](#lock-file).
-### Cargo.toml
+## Cargo.toml
See [*manifest*](#manifest).
-### Crate
+## Crate
A Rust *crate* is either a library or an executable program, referred to as
either a *library crate* or a *binary crate*, respectively.
@@ -32,14 +32,14 @@ compressed package fetched from a [registry](#registry).
The source code for a given crate may be subdivided into [*modules*](#module).
-### Edition
+## Edition
A *Rust edition* is a developmental landmark of the Rust language. The
[edition of a package][edition-field] is specified in the `Cargo.toml`
[manifest](#manifest), and individual targets can specify which edition they
use. See the [Edition Guide] for more information.
-### Feature
+## Feature
The meaning of *feature* depends on the context:
@@ -58,19 +58,19 @@ The meaning of *feature* depends on the context:
- CPU targets have [*target features*][target-feature] which specify
capabilities of a CPU.
-### Index
+## Index
The *index* is the searchable list of [*crates*](#crate) in a
[*registry*](#registry).
-### Lock file
+## Lock file
The `Cargo.lock` *lock file* is a file that captures the exact version of
every dependency used in a [*workspace*](#workspace) or
[*package*](#package). It is automatically generated by Cargo. See
[Cargo.toml vs Cargo.lock].
-### Manifest
+## Manifest
A [*manifest*][manifest] is a description of a [package](#package) or a
[workspace](#workspace) in a file named `Cargo.toml`.
@@ -78,12 +78,12 @@ A [*manifest*][manifest] is a description of a [package](#package) or a
A [*virtual manifest*][virtual] is a `Cargo.toml` file that only describes a
workspace, and does not include a package.
-### Member
+## Member
A *member* is a [*package*](#package) that belongs to a
[*workspace*](#workspace).
-### Module
+## Module
Rust's module system is used to organize code into logical units called
*modules*, which provide isolated namespaces within the code.
@@ -98,7 +98,7 @@ A [`Cargo.toml`](#manifest) file is primarily concerned with the
which they depend. Nevertheless, you will see the term "module" often when
working with Rust, so you should understand its relationship to a given crate.
-### Package
+## Package
A *package* is a collection of source files and a `Cargo.toml`
[*manifest*](#manifest) file which describes the package. A package has a name
@@ -123,7 +123,7 @@ Larger projects may involve multiple packages, in which case Cargo
[*workspaces*](#workspace) can be used to manage common dependencies and other
related metadata between the packages.
-### Package manager
+## Package manager
Broadly speaking, a *package manager* is a program (or collection of related
programs) in a software ecosystem that automates the process of obtaining,
@@ -139,15 +139,15 @@ downloads your Rust [package](#package)’s dependencies
packages, makes distributable packages, and (optionally) uploads them to
[crates.io][], the Rust community’s [*package registry*](#registry).
-### Package registry
+## Package registry
See [*registry*](#registry).
-### Project
+## Project
Another name for a [package](#package).
-### Registry
+## Registry
A *registry* is a service that contains a collection of downloadable
[*crates*](#crate) that can be installed or used as dependencies for a
@@ -156,7 +156,7 @@ A *registry* is a service that contains a collection of downloadable
contains a list of all crates, and tells Cargo how to download the crates that
are needed.
-### Source
+## Source
A *source* is a provider that contains [*crates*](#crate) that may be included
as dependencies for a [*package*](#package). There are several kinds of
@@ -174,11 +174,11 @@ sources:
See [Source Replacement] for more information.
-### Spec
+## Spec
See [package ID specification](#package).
-### Target
+## Target
The meaning of the term *target* depends on the context:
@@ -216,7 +216,7 @@ The meaning of the term *target* depends on the context:
Some parameters may be omitted. Run `rustc --print target-list` for a list of
supported targets.
-### Test Targets
+## Test Targets
Cargo *test targets* generate binaries which help verify proper operation and
correctness of code. There are two types of test artifacts:
@@ -232,7 +232,7 @@ correctness of code. There are two types of test artifacts:
`Cargo.toml` [*manifest*](#manifest). It is intended to only test the public
API of a library, or execute a binary to verify its operation.
-### Workspace
+## Workspace
A [*workspace*][workspace] is a collection of one or more
[*packages*](#package) that share common dependency resolution (with a shared
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-add.md b/src/tools/cargo/src/doc/src/commands/cargo-add.md
index 132c09326..03485e121 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-add.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-add.md
@@ -1,8 +1,5 @@
# cargo-add(1)
-
-
-
## NAME
cargo-add --- Add dependencies to a Cargo.toml manifest file
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-bench.md b/src/tools/cargo/src/doc/src/commands/cargo-bench.md
index 70ae187a7..45584023e 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-bench.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-bench.md
@@ -1,8 +1,5 @@
# cargo-bench(1)
-
-
-
## NAME
cargo-bench --- Execute benchmarks of a package
@@ -481,13 +478,15 @@ a string <code>default</code> is provided, it sets the value back to defaults.
Should not be 0.</dd>
-<dt class="option-term" id="option-cargo-bench---keep-going"><a class="option-anchor" href="#option-cargo-bench---keep-going"></a><code>--keep-going</code></dt>
-<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+</dl>
+While `cargo bench` involves compilation, it does not provide a `--keep-going`
+flag. Use `--no-fail-fast` to run as many benchmarks as possible without
+stopping at the first failure. To "compile" as many benchmarks as possible, use
+`--benches` to build benchmark binaries separately. For example:
-</dl>
+ cargo build --benches --release --keep-going
+ cargo bench --no-fail-fast
## ENVIRONMENT
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-build.md b/src/tools/cargo/src/doc/src/commands/cargo-build.md
index 525ab14e5..8e517bd1f 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-build.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-build.md
@@ -1,7 +1,5 @@
# cargo-build(1)
-
-
## NAME
cargo-build --- Compile the current package
@@ -409,8 +407,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-build---keep-going"><a class="option-anchor" href="#option-cargo-build---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo build -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo build -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
<dt class="option-term" id="option-cargo-build---future-incompat-report"><a class="option-anchor" href="#option-cargo-build---future-incompat-report"></a><code>--future-incompat-report</code></dt>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-check.md b/src/tools/cargo/src/doc/src/commands/cargo-check.md
index 4dbc97ad8..3d7d0a490 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-check.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-check.md
@@ -1,7 +1,5 @@
# cargo-check(1)
-
-
## NAME
cargo-check --- Check the current package
@@ -390,8 +388,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-check---keep-going"><a class="option-anchor" href="#option-cargo-check---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo check -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo check -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
<dt class="option-term" id="option-cargo-check---future-incompat-report"><a class="option-anchor" href="#option-cargo-check---future-incompat-report"></a><code>--future-incompat-report</code></dt>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-clean.md b/src/tools/cargo/src/doc/src/commands/cargo-clean.md
index bdbcb86d4..b1415828b 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-clean.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-clean.md
@@ -1,7 +1,5 @@
# cargo-clean(1)
-
-
## NAME
cargo-clean --- Remove generated artifacts
@@ -36,6 +34,11 @@ multiple times. See <a href="cargo-pkgid.html">cargo-pkgid(1)</a> for the SPEC f
<dl>
+<dt class="option-term" id="option-cargo-clean---dry-run"><a class="option-anchor" href="#option-cargo-clean---dry-run"></a><code>--dry-run</code></dt>
+<dd class="option-desc">Displays a summary of what would be deleted without deleting anything.
+Use with <code>--verbose</code> to display the actual files that would be deleted.</dd>
+
+
<dt class="option-term" id="option-cargo-clean---doc"><a class="option-anchor" href="#option-cargo-clean---doc"></a><code>--doc</code></dt>
<dd class="option-desc">This option will cause <code>cargo clean</code> to remove only the <code>doc</code> directory in
the target directory.</dd>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-doc.md b/src/tools/cargo/src/doc/src/commands/cargo-doc.md
index d68bb84e7..92843838c 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-doc.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-doc.md
@@ -1,7 +1,5 @@
# cargo-doc(1)
-
-
## NAME
cargo-doc --- Build a package's documentation
@@ -364,8 +362,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-doc---keep-going"><a class="option-anchor" href="#option-cargo-doc---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo doc -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo doc -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
</dl>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-fetch.md b/src/tools/cargo/src/doc/src/commands/cargo-fetch.md
index e6a460795..54ce48d37 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-fetch.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-fetch.md
@@ -1,8 +1,5 @@
# cargo-fetch(1)
-
-
-
## NAME
cargo-fetch --- Fetch dependencies of a package from the network
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-fix.md b/src/tools/cargo/src/doc/src/commands/cargo-fix.md
index 2bf83fc2e..4dde83d96 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-fix.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-fix.md
@@ -1,7 +1,5 @@
# cargo-fix(1)
-
-
## NAME
cargo-fix --- Automatically fix lint warnings reported by rustc
@@ -470,8 +468,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-fix---keep-going"><a class="option-anchor" href="#option-cargo-fix---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo fix -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo fix -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
</dl>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-install.md b/src/tools/cargo/src/doc/src/commands/cargo-install.md
index af8efcae8..5640af87a 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-install.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-install.md
@@ -1,7 +1,5 @@
# cargo-install(1)
-
-
## NAME
cargo-install --- Build and install a Rust binary
@@ -319,8 +317,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-install---keep-going"><a class="option-anchor" href="#option-cargo-install---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo install -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo install -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
</dl>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-login.md b/src/tools/cargo/src/doc/src/commands/cargo-login.md
index e738dca06..e2efcfe4f 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-login.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-login.md
@@ -2,18 +2,25 @@
## NAME
-cargo-login --- Save an API token from the registry locally
+cargo-login --- Log in to a registry
## SYNOPSIS
-`cargo login` [_options_] [_token_]
+`cargo login` [_options_] [_token_] -- [_args_]
## DESCRIPTION
-This command will save the API token to disk so that commands that require
-authentication, such as [cargo-publish(1)](cargo-publish.html), will be automatically
-authenticated. The token is saved in `$CARGO_HOME/credentials.toml`. `CARGO_HOME`
-defaults to `.cargo` in your home directory.
+This command will run a credential provider to save a token so that commands
+that require authentication, such as [cargo-publish(1)](cargo-publish.html), will be
+automatically authenticated.
+
+For the default `cargo:token` credential provider, the token is saved
+in `$CARGO_HOME/credentials.toml`. `CARGO_HOME` defaults to `.cargo`
+in your home directory.
+
+If a registry has a credential-provider specified, it will be used. Otherwise,
+the providers from the config value `registry.global-credential-providers` will
+be attempted, starting from the end of the list.
If the _token_ argument is not specified, it will be read from stdin.
@@ -122,9 +129,13 @@ details on environment variables that Cargo reads.
## EXAMPLES
-1. Save the API token to disk:
+1. Save the token for the default registry:
cargo login
+2. Save the token for a specific registry:
+
+ cargo login --registry my-registry
+
## SEE ALSO
[cargo(1)](cargo.html), [cargo-logout(1)](cargo-logout.html), [cargo-publish(1)](cargo-publish.html)
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-logout.md b/src/tools/cargo/src/doc/src/commands/cargo-logout.md
index 16e393b02..3cc50f6e9 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-logout.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-logout.md
@@ -10,9 +10,15 @@ cargo-logout --- Remove an API token from the registry locally
## DESCRIPTION
-This command will remove the API token from the local credential storage.
-Credentials are stored in `$CARGO_HOME/credentials.toml` where `$CARGO_HOME`
-defaults to `.cargo` in your home directory.
+This command will run a credential provider to remove a saved token.
+
+For the default `cargo:token` credential provider, credentials are stored
+in `$CARGO_HOME/credentials.toml` where `$CARGO_HOME` defaults to `.cargo`
+in your home directory.
+
+If a registry has a credential-provider specified, it will be used. Otherwise,
+the providers from the config value `registry.global-credential-providers` will
+be attempted, starting from the end of the list.
If `--registry` is not specified, then the credentials for the default
registry will be removed (configured by
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-metadata.md b/src/tools/cargo/src/doc/src/commands/cargo-metadata.md
index 5be6992d7..24b68d283 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-metadata.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-metadata.md
@@ -27,7 +27,7 @@ for a Rust API for reading the metadata.
Within the same output format version, the compatibility is maintained, except
some scenarios. The following is a non-exhaustive list of changes that are not
-considersed as incompatibile:
+considersed as incompatible:
* **Adding new fields** — New fields will be added when needed. Reserving this
helps Cargo evolve without bumping the format version too often.
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-package.md b/src/tools/cargo/src/doc/src/commands/cargo-package.md
index f9c7c552d..12684aa3c 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-package.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-package.md
@@ -1,8 +1,5 @@
# cargo-package(1)
-
-
-
## NAME
cargo-package --- Assemble the local package into a distributable tarball
@@ -234,8 +231,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-package---keep-going"><a class="option-anchor" href="#option-cargo-package---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo package -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo package -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
</dl>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-publish.md b/src/tools/cargo/src/doc/src/commands/cargo-publish.md
index fe37d9f97..bc84e61c0 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-publish.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-publish.md
@@ -1,7 +1,5 @@
# cargo-publish(1)
-
-
## NAME
cargo-publish --- Upload a package to the registry
@@ -21,8 +19,11 @@ following steps:
- Checks the `package.publish` key in the manifest for restrictions on
which registries you are allowed to publish to.
2. Create a `.crate` file by following the steps in [cargo-package(1)](cargo-package.html).
-3. Upload the crate to the registry. Note that the server will perform
- additional checks on the crate.
+3. Upload the crate to the registry. The server will perform additional
+ checks on the crate.
+4. The client will poll waiting for the package to appear in the index,
+ and may timeout. In that case, you will need to check for completion
+ manually. This timeout does not affect the upload.
This command requires you to be authenticated with either the `--token` option
or using [cargo-login(1)](cargo-login.html).
@@ -200,8 +201,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-publish---keep-going"><a class="option-anchor" href="#option-cargo-publish---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo publish -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo publish -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
</dl>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-remove.md b/src/tools/cargo/src/doc/src/commands/cargo-remove.md
index 571c41075..9e97b533a 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-remove.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-remove.md
@@ -1,7 +1,5 @@
# cargo-remove(1)
-
-
## NAME
cargo-remove --- Remove dependencies from a Cargo.toml manifest file
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-run.md b/src/tools/cargo/src/doc/src/commands/cargo-run.md
index bd3e4724a..c14ad77dc 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-run.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-run.md
@@ -1,6 +1,5 @@
# cargo-run(1)
-
## NAME
cargo-run --- Run the current package
@@ -306,8 +305,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-run---keep-going"><a class="option-anchor" href="#option-cargo-run---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo run -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo run -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
</dl>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-rustc.md b/src/tools/cargo/src/doc/src/commands/cargo-rustc.md
index 2147d617c..6ae52d965 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-rustc.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-rustc.md
@@ -1,7 +1,5 @@
# cargo-rustc(1)
-
-
## NAME
cargo-rustc --- Compile the current package, and pass extra options to the compiler
@@ -403,8 +401,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-rustc---keep-going"><a class="option-anchor" href="#option-cargo-rustc---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo rustc -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo rustc -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
<dt class="option-term" id="option-cargo-rustc---future-incompat-report"><a class="option-anchor" href="#option-cargo-rustc---future-incompat-report"></a><code>--future-incompat-report</code></dt>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-rustdoc.md b/src/tools/cargo/src/doc/src/commands/cargo-rustdoc.md
index 22c1c8322..6635cded5 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-rustdoc.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-rustdoc.md
@@ -1,7 +1,5 @@
# cargo-rustdoc(1)
-
-
## NAME
cargo-rustdoc --- Build a package's documentation, using specified custom flags
@@ -383,8 +381,12 @@ Should not be 0.</dd>
<dt class="option-term" id="option-cargo-rustdoc---keep-going"><a class="option-anchor" href="#option-cargo-rustdoc---keep-going"></a><code>--keep-going</code></dt>
<dd class="option-desc">Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-<code>-Zunstable-options</code>.</dd>
+the build on the first one that fails to build.</p>
+<p>For example if the current package depends on dependencies <code>fails</code> and <code>works</code>,
+one of which fails to build, <code>cargo rustdoc -j1</code> may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas <code>cargo rustdoc -j1 --keep-going</code> would definitely run both
+builds, even if the one run first fails.</dd>
</dl>
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-test.md b/src/tools/cargo/src/doc/src/commands/cargo-test.md
index bcf46d601..6a6ae82d2 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-test.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-test.md
@@ -1,8 +1,5 @@
# cargo-test(1)
-
-
-
## NAME
cargo-test --- Execute unit and integration tests of a package
@@ -524,6 +521,14 @@ produced during execution of this command</p>
</dl>
+While `cargo test` involves compilation, it does not provide a `--keep-going`
+flag. Use `--no-fail-fast` to run as many tests as possible without stopping at
+the first failure. To "compile" as many tests as possible, use `--tests` to
+build test binaries separately. For example:
+
+ cargo build --tests --keep-going
+ cargo test --tests --no-fail-fast
+
## ENVIRONMENT
See [the reference](../reference/environment-variables.html) for
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-tree.md b/src/tools/cargo/src/doc/src/commands/cargo-tree.md
index 9a9aa9f0c..948c3581c 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-tree.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-tree.md
@@ -1,7 +1,5 @@
# cargo-tree(1)
-
-
## NAME
cargo-tree --- Display a tree visualization of a dependency graph
diff --git a/src/tools/cargo/src/doc/src/commands/cargo-update.md b/src/tools/cargo/src/doc/src/commands/cargo-update.md
index 3cfd69282..234998faa 100644
--- a/src/tools/cargo/src/doc/src/commands/cargo-update.md
+++ b/src/tools/cargo/src/doc/src/commands/cargo-update.md
@@ -6,7 +6,7 @@ cargo-update --- Update dependencies as recorded in the local lock file
## SYNOPSIS
-`cargo update` [_options_]
+`cargo update` [_options_] _spec_
## DESCRIPTION
@@ -20,25 +20,24 @@ latest available versions.
<dl>
-<dt class="option-term" id="option-cargo-update--p"><a class="option-anchor" href="#option-cargo-update--p"></a><code>-p</code> <em>spec</em>…</dt>
-<dt class="option-term" id="option-cargo-update---package"><a class="option-anchor" href="#option-cargo-update---package"></a><code>--package</code> <em>spec</em>…</dt>
+<dt class="option-term" id="option-cargo-update-spec…"><a class="option-anchor" href="#option-cargo-update-spec…"></a><em>spec</em>…</dt>
<dd class="option-desc">Update only the specified packages. This flag may be specified
multiple times. See <a href="cargo-pkgid.html">cargo-pkgid(1)</a> for the SPEC format.</p>
-<p>If packages are specified with the <code>-p</code> flag, then a conservative update of
+<p>If packages are specified with <em>spec</em>, then a conservative update of
the lockfile will be performed. This means that only the dependency specified
by SPEC will be updated. Its transitive dependencies will be updated only if
SPEC cannot be updated without updating dependencies. All other dependencies
will remain locked at their currently recorded versions.</p>
-<p>If <code>-p</code> is not specified, all dependencies are updated.</dd>
+<p>If <em>spec</em> is not specified, all dependencies are updated.</dd>
-<dt class="option-term" id="option-cargo-update---aggressive"><a class="option-anchor" href="#option-cargo-update---aggressive"></a><code>--aggressive</code></dt>
-<dd class="option-desc">When used with <code>-p</code>, dependencies of <em>spec</em> are forced to update as well.
+<dt class="option-term" id="option-cargo-update---recursive"><a class="option-anchor" href="#option-cargo-update---recursive"></a><code>--recursive</code></dt>
+<dd class="option-desc">When used with <em>spec</em>, dependencies of <em>spec</em> are forced to update as well.
Cannot be used with <code>--precise</code>.</dd>
<dt class="option-term" id="option-cargo-update---precise"><a class="option-anchor" href="#option-cargo-update---precise"></a><code>--precise</code> <em>precise</em></dt>
-<dd class="option-desc">When used with <code>-p</code>, allows you to specify a specific version number to set
+<dd class="option-desc">When used with <em>spec</em>, allows you to specify a specific version number to set
the package to. If the package comes from a git repository, this can be a git
revision (such as a SHA hash or tag).</dd>
@@ -187,11 +186,11 @@ details on environment variables that Cargo reads.
2. Update only specific dependencies:
- cargo update -p foo -p bar
+ cargo update foo bar
3. Set a specific dependency to a specific version:
- cargo update -p foo --precise 1.2.3
+ cargo update foo --precise 1.2.3
## SEE ALSO
[cargo(1)](cargo.html), [cargo-generate-lockfile(1)](cargo-generate-lockfile.html)
diff --git a/src/tools/cargo/src/doc/src/faq.md b/src/tools/cargo/src/doc/src/faq.md
index e4a753413..9d4a982d0 100644
--- a/src/tools/cargo/src/doc/src/faq.md
+++ b/src/tools/cargo/src/doc/src/faq.md
@@ -1,6 +1,6 @@
-## Frequently Asked Questions
+# Frequently Asked Questions
-### Is the plan to use GitHub as a package repository?
+## Is the plan to use GitHub as a package repository?
No. The plan for Cargo is to use [crates.io], like npm or Rubygems do with
[npmjs.com][1] and [rubygems.org][3].
@@ -9,7 +9,7 @@ We plan to support git repositories as a source of packages forever,
because they can be used for early development and temporary patches,
even when people use the registry as the primary source of packages.
-### Why build crates.io rather than use GitHub as a registry?
+## Why build crates.io rather than use GitHub as a registry?
We think that it’s very important to support multiple ways to download
packages, including downloading from GitHub and copying packages into
@@ -43,7 +43,7 @@ languages include:
down fast. Also remember that not everybody has a high-speed,
low-latency Internet connection.
-### Will Cargo work with C code (or other languages)?
+## Will Cargo work with C code (or other languages)?
Yes!
@@ -56,7 +56,7 @@ Our solution: Cargo allows a package to [specify a script](reference/build-scrip
implement platform-specific configuration and refactor out common build
functionality among packages.
-### Can Cargo be used inside of `make` (or `ninja`, or ...)
+## Can Cargo be used inside of `make` (or `ninja`, or ...)
Indeed. While we intend Cargo to be useful as a standalone way to
compile Rust packages at the top-level, we know that some people will
@@ -68,7 +68,7 @@ have some work to do on those fronts, but using Cargo in the context of
conventional scripts is something we designed for from the beginning and
will continue to prioritize.
-### Does Cargo handle multi-platform packages or cross-compilation?
+## Does Cargo handle multi-platform packages or cross-compilation?
Rust itself provides facilities for configuring sections of code based
on the platform. Cargo also supports [platform-specific
@@ -80,7 +80,7 @@ configuration in `Cargo.toml` in the future.
In the longer-term, we’re looking at ways to conveniently cross-compile
packages using Cargo.
-### Does Cargo support environments, like `production` or `test`?
+## Does Cargo support environments, like `production` or `test`?
We support environments through the use of [profiles] to support:
@@ -92,7 +92,7 @@ We support environments through the use of [profiles] to support:
* environment-specific `#[cfg]`
* a `cargo test` command
-### Does Cargo work on Windows?
+## Does Cargo work on Windows?
Yes!
@@ -102,35 +102,49 @@ issue][cargo-issues].
[cargo-issues]: https://github.com/rust-lang/cargo/issues
-### Why do binaries have `Cargo.lock` in version control, but not libraries?
+## Why have `Cargo.lock` in version control?
-The purpose of a `Cargo.lock` lockfile is to describe the state of the world at
-the time of a successful build. Cargo uses the lockfile to provide
-deterministic builds on different times and different systems, by ensuring that
-the exact same dependencies and versions are used as when the `Cargo.lock` file
-was originally generated.
-
-This property is most desirable from applications and packages which are at the
-very end of the dependency chain (binaries). As a result, it is recommended that
-all binaries check in their `Cargo.lock`.
-
-For libraries the situation is somewhat different. A library is not only used by
-the library developers, but also any downstream consumers of the library. Users
-dependent on the library will not inspect the library’s `Cargo.lock` (even if it
-exists). This is precisely because a library should **not** be deterministically
-recompiled for all users of the library.
+While [`cargo new`] defaults to tracking `Cargo.lock` in version control,
+whether you do is dependent on the needs of your package.
-If a library ends up being used transitively by several dependencies, it’s
-likely that just a single copy of the library is desired (based on semver
-compatibility). If Cargo used all of the dependencies' `Cargo.lock` files,
-then multiple copies of the library could be used, and perhaps even a version
-conflict.
-
-In other words, libraries specify SemVer requirements for their dependencies but
-cannot see the full picture. Only end products like binaries have a full
-picture to decide what versions of dependencies should be used.
-
-### Can libraries use `*` as a version for their dependencies?
+The purpose of a `Cargo.lock` lockfile is to describe the state of the world at
+the time of a successful build.
+Cargo uses the lockfile to provide deterministic builds at different times and
+on different systems,
+by ensuring that the exact same dependencies and versions are used as when the
+`Cargo.lock` file was originally generated.
+
+Deterministic builds help with
+- Running `git bisect` to find the root cause of a bug
+- Ensuring CI only fails due to new commits and not external factors
+- Reducing confusion when contributors see different behavior as compared to
+ other contributors or CI
+
+Having this snapshot of dependencies can also help when projects need to be
+verified against consistent versions of dependencies, like when
+- Verifying a minimum-supported Rust version (MSRV) that is less than the latest
+ version of a dependency supports
+- Verifying human readable output which won't have compatibility guarantees
+ (e.g. snapshot testing error messages to ensure they are "understandable", a
+ metric too fuzzy to automate)
+
+However, this determinism can give a false sense of security because
+`Cargo.lock` does not affect the consumers of your package, only `Cargo.toml` does that.
+For example:
+- [`cargo install`] will select the latest dependencies unless `--locked` is
+ passed in.
+- New dependencies, like those added with [`cargo add`], will be locked to the latest version
+
+The lockfile can also be a source of merge conflicts.
+
+For strategies to verify newer versions of dependencies via CI,
+see [Verifying Latest Dependencies](guide/continuous-integration.md#verifying-latest-dependencies).
+
+[`cargo new`]: commands/cargo-new.md
+[`cargo add`]: commands/cargo-add.md
+[`cargo install`]: commands/cargo-install.md
+
+## Can libraries use `*` as a version for their dependencies?
**As of January 22nd, 2016, [crates.io] rejects all packages (not just libraries)
with wildcard dependency constraints.**
@@ -140,7 +154,7 @@ of `*` says “This will work with every version ever”, which is never going
to be true. Libraries should always specify the range that they do work with,
even if it’s something as general as “every 1.x.y version”.
-### Why `Cargo.toml`?
+## Why `Cargo.toml`?
As one of the most frequent interactions with Cargo, the question of why the
configuration file is named `Cargo.toml` arises from time to time. The leading
@@ -158,7 +172,7 @@ but others were accidentally forgotten.
[crates.io]: https://crates.io/
-### How can Cargo work offline?
+## How can Cargo work offline?
Cargo is often used in situations with limited or no network access such as
airplanes, CI environments, or embedded in large production deployments. Users
@@ -202,7 +216,7 @@ replacement][replace].
[`cargo fetch`]: commands/cargo-fetch.md
[offline config]: reference/config.md#netoffline
-### Why is Cargo rebuilding my code?
+## Why is Cargo rebuilding my code?
Cargo is responsible for incrementally compiling crates in your project. This
means that if you type `cargo build` twice the second one shouldn't rebuild your
@@ -260,7 +274,7 @@ If after trying to debug your issue, however, you're still running into problems
then feel free to [open an
issue](https://github.com/rust-lang/cargo/issues/new)!
-### What does "version conflict" mean and how to resolve it?
+## What does "version conflict" mean and how to resolve it?
> failed to select a version for `x` which could resolve this conflict
diff --git a/src/tools/cargo/src/doc/src/getting-started/first-steps.md b/src/tools/cargo/src/doc/src/getting-started/first-steps.md
index 15bb4bdc7..e8ed21d15 100644
--- a/src/tools/cargo/src/doc/src/getting-started/first-steps.md
+++ b/src/tools/cargo/src/doc/src/getting-started/first-steps.md
@@ -1,4 +1,4 @@
-## First Steps with Cargo
+# First Steps with Cargo
This section provides a quick sense for the `cargo` command line tool. We
demonstrate its ability to generate a new [***package***][def-package] for us,
@@ -73,7 +73,7 @@ $ cargo run
Hello, world!
```
-### Going further
+## Going further
For more details on using Cargo, check out the [Cargo Guide](../guide/index.md)
diff --git a/src/tools/cargo/src/doc/src/getting-started/index.md b/src/tools/cargo/src/doc/src/getting-started/index.md
index 710e9943b..30eca72ef 100644
--- a/src/tools/cargo/src/doc/src/getting-started/index.md
+++ b/src/tools/cargo/src/doc/src/getting-started/index.md
@@ -1,4 +1,4 @@
-## Getting Started
+# Getting Started
To get started with Cargo, install Cargo (and Rust) and set up your first
[*crate*][def-crate].
diff --git a/src/tools/cargo/src/doc/src/getting-started/installation.md b/src/tools/cargo/src/doc/src/getting-started/installation.md
index 7cccf9ee5..21ba2fd4c 100644
--- a/src/tools/cargo/src/doc/src/getting-started/installation.md
+++ b/src/tools/cargo/src/doc/src/getting-started/installation.md
@@ -1,6 +1,6 @@
-## Installation
+# Installation
-### Install Rust and Cargo
+## Install Rust and Cargo
The easiest way to get Cargo is to install the current stable release of [Rust]
by using [rustup]. Installing Rust using `rustup` will also install `cargo`.
@@ -27,7 +27,7 @@ channels for Rust and Cargo.
For other installation options and information, visit the
[install][install-rust] page of the Rust website.
-### Build and Install Cargo from Source
+## Build and Install Cargo from Source
Alternatively, you can [build Cargo from source][compiling-from-source].
diff --git a/src/tools/cargo/src/doc/src/guide/build-cache.md b/src/tools/cargo/src/doc/src/guide/build-cache.md
index a79b41dba..d351fc158 100644
--- a/src/tools/cargo/src/doc/src/guide/build-cache.md
+++ b/src/tools/cargo/src/doc/src/guide/build-cache.md
@@ -1,4 +1,4 @@
-## Build cache
+# Build cache
Cargo stores the output of a build into the "target" directory. By default,
this is the directory named `target` in the root of your
@@ -63,7 +63,7 @@ Directory | Description
<code style="white-space: nowrap">target/debug/incremental/</code> | `rustc` [incremental output], a cache used to speed up subsequent builds.
<code style="white-space: nowrap">target/debug/build/</code> | Output from [build scripts].
-### Dep-info files
+## Dep-info files
Next to each compiled artifact is a file called a "dep info" file with a `.d`
suffix. This file is a Makefile-like syntax that indicates all of the file
@@ -77,7 +77,7 @@ re-executed. The paths in the file are absolute by default. See the
/path/to/myproj/target/debug/foo: /path/to/myproj/src/lib.rs /path/to/myproj/src/main.rs
```
-### Shared cache
+## Shared cache
A third party tool, [sccache], can be used to share built dependencies across
different workspaces.
diff --git a/src/tools/cargo/src/doc/src/guide/cargo-home.md b/src/tools/cargo/src/doc/src/guide/cargo-home.md
index 9e6740f10..33e3f00a1 100644
--- a/src/tools/cargo/src/doc/src/guide/cargo-home.md
+++ b/src/tools/cargo/src/doc/src/guide/cargo-home.md
@@ -1,4 +1,4 @@
-## Cargo Home
+# Cargo Home
The "Cargo home" functions as a download and source cache.
When building a [crate][def-crate], Cargo stores downloaded build dependencies in the Cargo home.
diff --git a/src/tools/cargo/src/doc/src/guide/cargo-toml-vs-cargo-lock.md b/src/tools/cargo/src/doc/src/guide/cargo-toml-vs-cargo-lock.md
index 84d697f66..21f52dca1 100644
--- a/src/tools/cargo/src/doc/src/guide/cargo-toml-vs-cargo-lock.md
+++ b/src/tools/cargo/src/doc/src/guide/cargo-toml-vs-cargo-lock.md
@@ -1,4 +1,4 @@
-## Cargo.toml vs Cargo.lock
+# Cargo.toml vs Cargo.lock
`Cargo.toml` and `Cargo.lock` serve two different purposes. Before we talk
about them, here’s a summary:
@@ -8,14 +8,11 @@ about them, here’s a summary:
* `Cargo.lock` contains exact information about your dependencies. It is
maintained by Cargo and should not be manually edited.
-If you’re building a non-end product, such as a rust library that other rust
-[packages][def-package] will depend on, put `Cargo.lock` in your
-`.gitignore`. If you’re building an end product, which are executable like
-command-line tool or an application, or a system library with crate-type of
-`staticlib` or `cdylib`, check `Cargo.lock` into `git`. If you're curious
-about why that is, see
-["Why do binaries have `Cargo.lock` in version control, but not libraries?" in the
-FAQ](../faq.md#why-do-binaries-have-cargolock-in-version-control-but-not-libraries).
+When in doubt, check `Cargo.lock` into the version control system (e.g. Git).
+For a better understanding of why and what the alternatives might be, see
+[“Why have Cargo.lock in version control?” in the FAQ](../faq.md#why-have-cargolock-in-version-control).
+We recommend pairing this with
+[Verifying Latest Dependencies](continuous-integration.md#verifying-latest-dependencies)
Let’s dig in a little bit more.
@@ -94,8 +91,8 @@ When we’re ready to opt in to a new version of the library, Cargo can
re-calculate the dependencies and update things for us:
```console
-$ cargo update # updates all dependencies
-$ cargo update -p regex # updates just “regex”
+$ cargo update # updates all dependencies
+$ cargo update regex # updates just “regex”
```
This will write out a new `Cargo.lock` with the new version information. Note
diff --git a/src/tools/cargo/src/doc/src/guide/continuous-integration.md b/src/tools/cargo/src/doc/src/guide/continuous-integration.md
index 38d8ae20e..0c3cec889 100644
--- a/src/tools/cargo/src/doc/src/guide/continuous-integration.md
+++ b/src/tools/cargo/src/doc/src/guide/continuous-integration.md
@@ -1,25 +1,8 @@
-## Continuous Integration
+# Continuous Integration
-### Travis CI
+## Getting Started
-To test your [package][def-package] on Travis CI, here is a sample
-`.travis.yml` file:
-
-```yaml
-language: rust
-rust:
- - stable
- - beta
- - nightly
-matrix:
- allow_failures:
- - rust: nightly
-```
-
-This will test all three release channels, but any breakage in nightly
-will not fail your overall build. Please see the [Travis CI Rust
-documentation](https://docs.travis-ci.com/user/languages/rust/) for more
-information.
+A basic CI will build and test your projects:
### GitHub Actions
@@ -122,4 +105,58 @@ channel, but any breakage in nightly will not fail your overall build. Please
see the [builds.sr.ht documentation](https://man.sr.ht/builds.sr.ht/) for more
information.
-[def-package]: ../appendix/glossary.md#package '"package" (glossary entry)'
+## Verifying Latest Dependencies
+
+When [specifying dependencies](../reference/specifying-dependencies.md) in
+`Cargo.toml`, they generally match a range of versions.
+Exhaustively testing all version combination would be unwieldy.
+Verifying the latest versions would at least test for users who run [`cargo
+add`] or [`cargo install`].
+
+When testing the latest versions some considerations are:
+- Minimizing external factors affecting local development or CI
+- Rate of new dependencies being published
+- Level of risk a project is willing to accept
+- CI costs, including indirect costs like if a CI service has a maximum for
+ parallel runners, causing new jobs to be serialized when at the maximum.
+
+Some potential solutions include:
+- [Not checking in the `Cargo.lock`](../faq.md#why-have-cargolock-in-version-control)
+ - Depending on PR velocity, many versions may go untested
+ - This comes at the cost of determinism
+- Have a CI job verify the latest dependencies but mark it to "continue on failure"
+ - Depending on the CI service, failures might not be obvious
+ - Depending on PR velocity, may use more resources than necessary
+- Have a scheduled CI job to verify latest dependencies
+ - A hosted CI service may disable scheduled jobs for repositories that
+ haven't been touched in a while, affecting passively maintained packages
+ - Depending on the CI service, notifications might not be routed to people
+ who can act on the failure
+ - If not balanced with dependency publish rate, may not test enough versions
+ or may do redundant testing
+- Regularly update dependencies through PRs, like with [Dependabot] or [RenovateBot]
+ - Can isolate dependencies to their own PR or roll them up into a single PR
+ - Only uses the resources necessary
+ - Can configure the frequency to balance CI resources and coverage of dependency versions
+
+An example CI job to verify latest dependencies, using GitHub Actions:
+```yaml
+jobs:
+ latest_deps:
+ name: Latest Dependencies
+ runs-on: ubuntu-latest
+ continue-on-error: true
+ steps:
+ - uses: actions/checkout@v3
+ - run: rustup update stable && rustup default stable
+ - run: cargo update --verbose
+ - run: cargo build --verbose
+ - run: cargo test --verbose
+```
+For projects with higher risks of per-platform or per-Rust version failures,
+more combinations may want to be tested.
+
+[`cargo add`]: ../commands/cargo-add.md
+[`cargo install`]: ../commands/cargo-install.md
+[Dependabot]: https://docs.github.com/en/code-security/dependabot/working-with-dependabot
+[RenovateBot]: https://renovatebot.com/
diff --git a/src/tools/cargo/src/doc/src/guide/creating-a-new-project.md b/src/tools/cargo/src/doc/src/guide/creating-a-new-project.md
index e0daefc6b..49fbc0880 100644
--- a/src/tools/cargo/src/doc/src/guide/creating-a-new-project.md
+++ b/src/tools/cargo/src/doc/src/guide/creating-a-new-project.md
@@ -1,4 +1,4 @@
-## Creating a New Package
+# Creating a New Package
To start a new [package][def-package] with Cargo, use `cargo new`:
diff --git a/src/tools/cargo/src/doc/src/guide/dependencies.md b/src/tools/cargo/src/doc/src/guide/dependencies.md
index 94419f15b..cbb3ba115 100644
--- a/src/tools/cargo/src/doc/src/guide/dependencies.md
+++ b/src/tools/cargo/src/doc/src/guide/dependencies.md
@@ -1,4 +1,4 @@
-## Dependencies
+# Dependencies
[crates.io] is the Rust community's central [*package registry*][def-package-registry]
that serves as a location to discover and download
@@ -9,7 +9,7 @@ To depend on a library hosted on [crates.io], add it to your `Cargo.toml`.
[crates.io]: https://crates.io/
-### Adding a dependency
+## Adding a dependency
If your `Cargo.toml` doesn't already have a `[dependencies]` section, add
that, then list the [crate][def-crate] name and version that you would like to
diff --git a/src/tools/cargo/src/doc/src/guide/index.md b/src/tools/cargo/src/doc/src/guide/index.md
index fe6d86a39..00fe2320c 100644
--- a/src/tools/cargo/src/doc/src/guide/index.md
+++ b/src/tools/cargo/src/doc/src/guide/index.md
@@ -1,4 +1,4 @@
-## Cargo Guide
+# Cargo Guide
This guide will give you all that you need to know about how to use Cargo to
develop Rust packages.
diff --git a/src/tools/cargo/src/doc/src/guide/project-layout.md b/src/tools/cargo/src/doc/src/guide/project-layout.md
index a3ce3f8a7..c4360af01 100644
--- a/src/tools/cargo/src/doc/src/guide/project-layout.md
+++ b/src/tools/cargo/src/doc/src/guide/project-layout.md
@@ -1,4 +1,4 @@
-## Package Layout
+# Package Layout
Cargo uses conventions for file placement to make it easy to dive into a new
Cargo [package][def-package]:
diff --git a/src/tools/cargo/src/doc/src/guide/tests.md b/src/tools/cargo/src/doc/src/guide/tests.md
index 402e8e35c..0148c9120 100644
--- a/src/tools/cargo/src/doc/src/guide/tests.md
+++ b/src/tools/cargo/src/doc/src/guide/tests.md
@@ -1,4 +1,4 @@
-## Tests
+# Tests
Cargo can run your tests with the `cargo test` command. Cargo looks for tests
to run in two places: in each of your `src` files and any tests in `tests/`.
diff --git a/src/tools/cargo/src/doc/src/guide/why-cargo-exists.md b/src/tools/cargo/src/doc/src/guide/why-cargo-exists.md
index 02b222f01..2081944f7 100644
--- a/src/tools/cargo/src/doc/src/guide/why-cargo-exists.md
+++ b/src/tools/cargo/src/doc/src/guide/why-cargo-exists.md
@@ -1,6 +1,6 @@
-## Why Cargo Exists
+# Why Cargo Exists
-### Preliminaries
+## Preliminaries
In Rust, as you may know, a library or executable program is called a
[*crate*][def-crate]. Crates are compiled using the Rust compiler,
@@ -31,7 +31,7 @@ involved with performing the above tasks by introducing a higher-level
["*package*"][def-package] abstraction and by using a
[*package manager*][def-package-manager].
-### Enter: Cargo
+## Enter: Cargo
*Cargo* is the Rust package manager. It is a tool that allows Rust
[*packages*][def-package] to declare their various dependencies and ensure
diff --git a/src/tools/cargo/src/doc/src/guide/working-on-an-existing-project.md b/src/tools/cargo/src/doc/src/guide/working-on-an-existing-project.md
index f9c26cd90..446248530 100644
--- a/src/tools/cargo/src/doc/src/guide/working-on-an-existing-project.md
+++ b/src/tools/cargo/src/doc/src/guide/working-on-an-existing-project.md
@@ -1,4 +1,4 @@
-## Working on an Existing Cargo Package
+# Working on an Existing Cargo Package
If you download an existing [package][def-package] that uses Cargo, it’s
really easy to get going.
diff --git a/src/tools/cargo/src/doc/src/index.md b/src/tools/cargo/src/doc/src/index.md
index 223600c8b..a7b01c60b 100644
--- a/src/tools/cargo/src/doc/src/index.md
+++ b/src/tools/cargo/src/doc/src/index.md
@@ -7,8 +7,7 @@ dependencies, compiles your packages, makes distributable packages, and uploads
[crates.io], the Rust community’s [*package registry*][def-package-registry]. You can contribute
to this book on [GitHub].
-
-### Sections
+## Sections
**[Getting Started](getting-started/index.md)**
diff --git a/src/tools/cargo/src/doc/src/reference/build-script-examples.md b/src/tools/cargo/src/doc/src/reference/build-script-examples.md
index 5e8fae5bb..e55d4704d 100644
--- a/src/tools/cargo/src/doc/src/reference/build-script-examples.md
+++ b/src/tools/cargo/src/doc/src/reference/build-script-examples.md
@@ -1,4 +1,4 @@
-## Build Script Examples
+# Build Script Examples
The following sections illustrate some examples of writing build scripts.
@@ -22,7 +22,7 @@ available. The following is a sample of some popular crates[^†]:
[^†]: This list is not an endorsement. Evaluate your dependencies to see which
is right for your project.
-### Code generation
+## Code generation
Some Cargo packages need to have code generated just before they are compiled
for various reasons. Here we’ll walk through a simple example which generates a
@@ -120,7 +120,7 @@ from the build script itself.
[concat-macro]: ../../std/macro.concat.html
[env-macro]: ../../std/macro.env.html
-### Building a native library
+## Building a native library
Sometimes it’s necessary to build some native C or C++ code as part of a
package. This is another excellent use case of leveraging the build script to
@@ -268,7 +268,7 @@ dependency purely for the build process and not for the crate itself at runtime.
[`cc` crate]: https://crates.io/crates/cc
-### Linking to system libraries
+## Linking to system libraries
This example demonstrates how to link a system library and how the build
script is used to support this use case.
@@ -363,7 +363,7 @@ source][libz-source] for a more complete example.
[`pkg-config` crate]: https://crates.io/crates/pkg-config
[libz-source]: https://github.com/rust-lang/libz-sys
-### Using another `sys` crate
+## Using another `sys` crate
When using the `links` key, crates may set metadata that can be read by other
crates that depend on it. This provides a mechanism to communicate information
@@ -424,7 +424,7 @@ already installed.
// … rest of code that makes use of zlib.
```
-### Conditional compilation
+## Conditional compilation
A build script may emit [`rustc-cfg` instructions] which can enable conditions
that can be checked at compile time. In this example, we'll take a look at how
diff --git a/src/tools/cargo/src/doc/src/reference/build-scripts.md b/src/tools/cargo/src/doc/src/reference/build-scripts.md
index e7560812b..451850388 100644
--- a/src/tools/cargo/src/doc/src/reference/build-scripts.md
+++ b/src/tools/cargo/src/doc/src/reference/build-scripts.md
@@ -1,4 +1,4 @@
-## Build Scripts
+# Build Scripts
Some packages need to compile third-party non-Rust code, for example C
libraries. Other packages need to link to C libraries which can either be
@@ -37,7 +37,7 @@ scripts.
> Note: The [`package.build` manifest key](manifest.md#the-build-field) can be
> used to change the name of the build script, or disable it entirely.
-### Life Cycle of a Build Script
+## Life Cycle of a Build Script
Just before a package is built, Cargo will compile a build script into an
executable (if it has not already been built). It will then run the script,
@@ -57,7 +57,7 @@ will be compiled. Scripts should exit with a non-zero exit code to halt the
build if there is an error, in which case the build script's output will be
displayed on the terminal.
-### Inputs to the Build Script
+## Inputs to the Build Script
When the build script is run, there are a number of inputs to the build script,
all passed in the form of [environment variables][build-env].
@@ -67,7 +67,7 @@ the source directory of the build script’s package.
[build-env]: environment-variables.md#environment-variables-cargo-sets-for-build-scripts
-### Outputs of the Build Script
+## Outputs of the Build Script
Build scripts may save any output files or intermediate artifacts in the
directory specified in the [`OUT_DIR` environment variable][build-env]. Scripts
@@ -132,7 +132,7 @@ one detailed below.
scripts.
-#### `cargo:rustc-link-arg=FLAG` {#rustc-link-arg}
+### `cargo:rustc-link-arg=FLAG` {#rustc-link-arg}
The `rustc-link-arg` instruction tells Cargo to pass the [`-C link-arg=FLAG`
option][link-arg] to the compiler, but only when building supported targets
@@ -142,7 +142,7 @@ linker script.
[link-arg]: ../../rustc/codegen-options/index.md#link-arg
-#### `cargo:rustc-link-arg-bin=BIN=FLAG` {#rustc-link-arg-bin}
+### `cargo:rustc-link-arg-bin=BIN=FLAG` {#rustc-link-arg-bin}
The `rustc-link-arg-bin` instruction tells Cargo to pass the [`-C
link-arg=FLAG` option][link-arg] to the compiler, but only when building
@@ -150,7 +150,7 @@ the binary target with name `BIN`. Its usage is highly platform specific. It is
to set a linker script or other linker options.
-#### `cargo:rustc-link-arg-bins=FLAG` {#rustc-link-arg-bins}
+### `cargo:rustc-link-arg-bins=FLAG` {#rustc-link-arg-bins}
The `rustc-link-arg-bins` instruction tells Cargo to pass the [`-C
link-arg=FLAG` option][link-arg] to the compiler, but only when building a
@@ -158,7 +158,7 @@ binary target. Its usage is highly platform specific. It is useful
to set a linker script or other linker options.
-#### `cargo:rustc-link-lib=LIB` {#rustc-link-lib}
+### `cargo:rustc-link-lib=LIB` {#rustc-link-lib}
The `rustc-link-lib` instruction tells Cargo to link the given library using
the compiler's [`-l` flag][option-link]. This is typically used to link a
@@ -183,26 +183,26 @@ The optional `KIND` may be one of `dylib`, `static`, or `framework`. See the
[FFI]: ../../nomicon/ffi.md
-#### `cargo:rustc-link-arg-tests=FLAG` {#rustc-link-arg-tests}
+### `cargo:rustc-link-arg-tests=FLAG` {#rustc-link-arg-tests}
The `rustc-link-arg-tests` instruction tells Cargo to pass the [`-C
link-arg=FLAG` option][link-arg] to the compiler, but only when building a
tests target.
-#### `cargo:rustc-link-arg-examples=FLAG` {#rustc-link-arg-examples}
+### `cargo:rustc-link-arg-examples=FLAG` {#rustc-link-arg-examples}
The `rustc-link-arg-examples` instruction tells Cargo to pass the [`-C
link-arg=FLAG` option][link-arg] to the compiler, but only when building an examples
target.
-#### `cargo:rustc-link-arg-benches=FLAG` {#rustc-link-arg-benches}
+### `cargo:rustc-link-arg-benches=FLAG` {#rustc-link-arg-benches}
The `rustc-link-arg-benches` instruction tells Cargo to pass the [`-C
link-arg=FLAG` option][link-arg] to the compiler, but only when building a benchmark
target.
-#### `cargo:rustc-link-search=[KIND=]PATH` {#rustc-link-search}
+### `cargo:rustc-link-search=[KIND=]PATH` {#rustc-link-search}
The `rustc-link-search` instruction tells Cargo to pass the [`-L`
flag][option-search] to the compiler to add a directory to the library search
@@ -220,14 +220,14 @@ is fine).
[option-search]: ../../rustc/command-line-arguments.md#option-l-search-path
-#### `cargo:rustc-flags=FLAGS` {#rustc-flags}
+### `cargo:rustc-flags=FLAGS` {#rustc-flags}
The `rustc-flags` instruction tells Cargo to pass the given space-separated
flags to the compiler. This only allows the `-l` and `-L` flags, and is
equivalent to using [`rustc-link-lib`](#rustc-link-lib) and
[`rustc-link-search`](#rustc-link-search).
-#### `cargo:rustc-cfg=KEY[="VALUE"]` {#rustc-cfg}
+### `cargo:rustc-cfg=KEY[="VALUE"]` {#rustc-cfg}
The `rustc-cfg` instruction tells Cargo to pass the given value to the
[`--cfg` flag][option-cfg] to the compiler. This may be used for compile-time
@@ -248,7 +248,7 @@ identifier, the value should be a string.
[conditional compilation]: ../../reference/conditional-compilation.md
[option-cfg]: ../../rustc/command-line-arguments.md#option-cfg
-#### `cargo:rustc-env=VAR=VALUE` {#rustc-env}
+### `cargo:rustc-env=VAR=VALUE` {#rustc-env}
The `rustc-env` instruction tells Cargo to set the given environment variable
when compiling the package. The value can be then retrieved by the [`env!`
@@ -268,7 +268,7 @@ Cargo][env-cargo].
[env-macro]: ../../std/macro.env.html
[env-cargo]: environment-variables.md#environment-variables-cargo-sets-for-crates
-#### `cargo:rustc-cdylib-link-arg=FLAG` {#rustc-cdylib-link-arg}
+### `cargo:rustc-cdylib-link-arg=FLAG` {#rustc-cdylib-link-arg}
The `rustc-cdylib-link-arg` instruction tells Cargo to pass the [`-C
link-arg=FLAG` option][link-arg] to the compiler, but only when building a
@@ -276,7 +276,7 @@ link-arg=FLAG` option][link-arg] to the compiler, but only when building a
to set the shared library version or the runtime-path.
-#### `cargo:warning=MESSAGE` {#cargo-warning}
+### `cargo:warning=MESSAGE` {#cargo-warning}
The `warning` instruction tells Cargo to display a warning after the build
script has finished running. Warnings are only shown for `path` dependencies
@@ -284,7 +284,7 @@ script has finished running. Warnings are only shown for `path` dependencies
out in [crates.io] crates are not emitted by default. The `-vv` "very verbose"
flag may be used to have Cargo display warnings for all crates.
-### Build Dependencies
+## Build Dependencies
Build scripts are also allowed to have dependencies on other Cargo-based crates.
Dependencies are declared through the `build-dependencies` section of the
@@ -306,7 +306,7 @@ attempt to reuse a dependency if it is shared between build dependencies and
normal dependencies. However, this is not always possible, for example when
cross-compiling, so keep that in consideration of the impact on compile time.
-### Change Detection
+## Change Detection
When rebuilding a package, Cargo does not necessarily know if the build script
needs to be run again. By default, it takes a conservative approach of always
@@ -321,7 +321,7 @@ FAQ](../faq.md#why-is-cargo-rebuilding-my-code).
[`exclude` and `include` fields]: manifest.md#the-exclude-and-include-fields
-#### `cargo:rerun-if-changed=PATH` {#rerun-if-changed}
+### `cargo:rerun-if-changed=PATH` {#rerun-if-changed}
The `rerun-if-changed` instruction tells Cargo to re-run the build script if
the file at the given path has changed. Currently, Cargo only uses the
@@ -340,7 +340,7 @@ automatically handles whether or not the script itself needs to be recompiled,
and of course the script will be re-run after it has been recompiled.
Otherwise, specifying `build.rs` is redundant and unnecessary.
-#### `cargo:rerun-if-env-changed=NAME` {#rerun-if-env-changed}
+### `cargo:rerun-if-env-changed=NAME` {#rerun-if-env-changed}
The `rerun-if-env-changed` instruction tells Cargo to re-run the build script
if the value of an environment variable of the given name has changed.
@@ -352,7 +352,7 @@ environment variables in use are those received by `cargo` invocations, not
those received by the executable of the build script.
-### The `links` Manifest Key
+## The `links` Manifest Key
The `package.links` key may be set in the `Cargo.toml` manifest to declare
that the package links with the given native library. The purpose of this
@@ -390,7 +390,7 @@ dependents.
[using-another-sys]: build-script-examples.md#using-another-sys-crate
-### `*-sys` Packages
+## `*-sys` Packages
Some Cargo packages that link to system libraries have a naming convention of
having a `-sys` suffix. Any package named `foo-sys` should provide two major
@@ -423,7 +423,7 @@ example, the [`git2` crate] provides a high-level interface to the
[`git2` crate]: https://crates.io/crates/git2
[`libgit2-sys` crate]: https://crates.io/crates/libgit2-sys
-### Overriding Build Scripts
+## Overriding Build Scripts
If a manifest contains a `links` key, then Cargo supports overriding the build
script specified with a custom library. The purpose of this functionality is to
@@ -451,7 +451,7 @@ be used instead.
The `warning`, `rerun-if-changed`, and `rerun-if-env-changed` keys should not
be used and will be ignored.
-### Jobserver
+## Jobserver
Cargo and `rustc` use the [jobserver protocol], developed for GNU make, to
coordinate concurrency across processes. It is essentially a semaphore that
diff --git a/src/tools/cargo/src/doc/src/reference/cargo-targets.md b/src/tools/cargo/src/doc/src/reference/cargo-targets.md
index 7aea15109..ef29a520f 100644
--- a/src/tools/cargo/src/doc/src/reference/cargo-targets.md
+++ b/src/tools/cargo/src/doc/src/reference/cargo-targets.md
@@ -1,4 +1,4 @@
-## Cargo Targets
+# Cargo Targets
Cargo packages consist of *targets* which correspond to source files which can
be compiled into a crate. Packages can have [library](#library),
@@ -10,7 +10,7 @@ by the [directory layout][package layout] of the source files.
See [Configuring a target](#configuring-a-target) below for details on
configuring the settings for a target.
-### Library
+## Library
The library target defines a "library" that can be used and linked by other
libraries and executables. The filename defaults to `src/lib.rs`, and the name
@@ -25,7 +25,7 @@ crate-type = ["cdylib"]
bench = false
```
-### Binaries
+## Binaries
Binary targets are executable programs that can be run after being compiled.
The default binary filename is `src/main.rs`, which defaults to the name of
@@ -52,7 +52,7 @@ name = "frobnicator"
required-features = ["frobnicate"]
```
-### Examples
+## Examples
Files located under the [`examples` directory][package layout] are example
uses of the functionality provided by the library. When compiled, they are
@@ -81,7 +81,7 @@ default to protect them from bit-rotting. Set [the `test`
field](#the-test-field) to `true` if you have `#[test]` functions in the
example that you want to run with [`cargo test`].
-### Tests
+## Tests
There are two styles of tests within a Cargo project:
@@ -108,7 +108,7 @@ strategy.
[libtest harness]: ../../rustc/tests/index.html
[cargo-test-documentation-tests]: ../commands/cargo-test.md#documentation-tests
-#### Integration tests
+### Integration tests
Files located under the [`tests` directory][package layout] are integration
tests. When you run [`cargo test`], Cargo will compile each of these files as
@@ -140,7 +140,7 @@ executable.
[environment variable]: environment-variables.md#environment-variables-cargo-sets-for-crates
[`env` macro]: ../../std/macro.env.html
-### Benchmarks
+## Benchmarks
Benchmarks provide a way to test the performance of your code using the
[`cargo bench`] command. They follow the same structure as [tests](#tests),
@@ -163,7 +163,7 @@ Similarly to tests:
> may help with running benchmarks on the stable channel, such as
> [Criterion](https://crates.io/crates/criterion).
-### Configuring a target
+## Configuring a target
All of the `[lib]`, `[[bin]]`, `[[example]]`, `[[test]]`, and `[[bench]]`
sections in `Cargo.toml` support similar configuration for specifying how a
@@ -192,7 +192,7 @@ crate-type = ["lib"] # The crate types to generate.
required-features = [] # Features required to build this target (N/A for lib).
```
-#### The `name` field
+### The `name` field
The `name` field specifies the name of the target, which corresponds to the
filename of the artifact that will be generated. For a library, this is the
@@ -205,7 +205,7 @@ directory or file name.
This is required for all targets except `[lib]`.
-#### The `path` field
+### The `path` field
The `path` field specifies where the source for the crate is located, relative
to the `Cargo.toml` file.
@@ -213,7 +213,7 @@ to the `Cargo.toml` file.
If not specified, the [inferred path](#target-auto-discovery) is used based on
the target name.
-#### The `test` field
+### The `test` field
The `test` field indicates whether or not the target is tested by default by
[`cargo test`]. The default is `true` for lib, bins, and tests.
@@ -223,19 +223,19 @@ The `test` field indicates whether or not the target is tested by default by
> true` for an example will also build it as a test and run any
> [`#[test]`][test-attribute] functions defined in the example.
-#### The `doctest` field
+### The `doctest` field
The `doctest` field indicates whether or not [documentation examples] are
tested by default by [`cargo test`]. This is only relevant for libraries, it
has no effect on other sections. The default is `true` for the library.
-#### The `bench` field
+### The `bench` field
The `bench` field indicates whether or not the target is benchmarked by
default by [`cargo bench`]. The default is `true` for lib, bins, and
benchmarks.
-#### The `doc` field
+### The `doc` field
The `doc` field indicates whether or not the target is included in the
documentation generated by [`cargo doc`] by default. The default is `true` for
@@ -244,17 +244,17 @@ libraries and binaries.
> **Note**: The binary will be skipped if its name is the same as the lib
> target.
-#### The `plugin` field
+### The `plugin` field
This field is used for `rustc` plugins, which are being deprecated.
-#### The `proc-macro` field
+### The `proc-macro` field
The `proc-macro` field indicates that the library is a [procedural macro]
([reference][proc-macro-reference]). This is only valid for the `[lib]`
target.
-#### The `harness` field
+### The `harness` field
The `harness` field indicates that the [`--test` flag] will be passed to
`rustc` which will automatically include the libtest library which is the
@@ -268,7 +268,7 @@ to run tests and benchmarks.
Tests have the [`cfg(test)` conditional expression][cfg-test] enabled whether
or not the harness is enabled.
-#### The `edition` field
+### The `edition` field
The `edition` field defines the [Rust edition] the target will use. If not
specified, it defaults to the [`edition` field][package-edition] for the
@@ -276,7 +276,7 @@ specified, it defaults to the [`edition` field][package-edition] for the
advanced scenarios such as incrementally transitioning a large package to a
new edition.
-#### The `crate-type` field
+### The `crate-type` field
The `crate-type` field defines the [crate types] that will be generated by the
target. It is an array of strings, allowing you to specify multiple crate
@@ -294,7 +294,7 @@ The available options are `bin`, `lib`, `rlib`, `dylib`, `cdylib`,
`staticlib`, and `proc-macro`. You can read more about the different crate
types in the [Rust Reference Manual][crate types].
-#### The `required-features` field
+### The `required-features` field
The `required-features` field specifies which [features] the target needs in
order to be built. If any of the required features are not enabled, the
@@ -314,7 +314,7 @@ required-features = ["postgres", "tools"]
```
-### Target auto-discovery
+## Target auto-discovery
By default, Cargo automatically determines the targets to build based on the
[layout of the files][package layout] on the filesystem. The target
diff --git a/src/tools/cargo/src/doc/src/reference/config.md b/src/tools/cargo/src/doc/src/reference/config.md
index d1f2b04d3..6a479b81b 100644
--- a/src/tools/cargo/src/doc/src/reference/config.md
+++ b/src/tools/cargo/src/doc/src/reference/config.md
@@ -1,10 +1,10 @@
-## Configuration
+# Configuration
This document explains how Cargo’s configuration system works, as well as
available keys or configuration. For configuration of a package through its
manifest, see the [manifest format](manifest.md).
-### Hierarchical structure
+## Hierarchical structure
Cargo allows local configuration for a particular package as well as global
configuration. It looks for configuration files in the current directory and
@@ -28,7 +28,8 @@ with a configuration file in your home directory.
If a key is specified in multiple config files, the values will get merged
together. Numbers, strings, and booleans will use the value in the deeper
config directory taking precedence over ancestor directories, where the
-home directory is the lowest priority. Arrays will be joined together.
+home directory is the lowest priority. Arrays will be joined together
+with higher precedence items being placed later in the merged array.
At present, when being invoked from a workspace, Cargo does not read config
files from crates within the workspace. i.e. if a workspace has two crates in
@@ -43,7 +44,7 @@ those configuration files if it is invoked from the workspace root
> and is the preferred form. If both files exist, Cargo will use the file
> without the extension.
-### Configuration format
+## Configuration format
Configuration files are written in the [TOML format][toml] (like the
manifest), with simple key-value pairs inside of sections (tables). The
@@ -183,7 +184,7 @@ progress.when = 'auto' # whether cargo shows progress bar
progress.width = 80 # width of progress bar
```
-### Environment variables
+## Environment variables
Cargo can also be configured through environment variables in addition to the
TOML configuration files. For each configuration key of the form `foo.bar` the
@@ -202,7 +203,7 @@ supported due to [technical issues](https://github.com/rust-lang/cargo/issues/54
In addition to the system above, Cargo recognizes a few other specific
[environment variables][env].
-### Command-line overrides
+## Command-line overrides
Cargo also accepts arbitrary configuration overrides through the
`--config` command-line option. The argument should be in TOML syntax of
@@ -242,7 +243,7 @@ configuration files that Cargo should use for a specific invocation.
Options from configuration files loaded this way follow the same
precedence rules as other options specified directly with `--config`.
-### Config-relative paths
+## Config-relative paths
Paths in config files may be absolute, relative, or a bare name without any path separators.
Paths for executables without a path separator will use the `PATH` environment variable to search for the executable.
@@ -279,7 +280,7 @@ runner = "foo" # Searches `PATH` for `foo`.
directory = "vendor"
```
-### Executable paths with arguments
+## Executable paths with arguments
Some Cargo commands invoke external programs, which can be configured as a path
and some number of arguments.
@@ -293,11 +294,13 @@ run, they will be passed after the last specified argument in the value of an
option of this format. If the specified program does not have path separators,
Cargo will search `PATH` for its executable.
-### Credentials
+## Credentials
Configuration values with sensitive information are stored in the
`$CARGO_HOME/credentials.toml` file. This file is automatically created and updated
-by [`cargo login`] and [`cargo logout`]. It follows the same format as Cargo config files.
+by [`cargo login`] and [`cargo logout`] when using the `cargo:token` credential provider.
+
+It follows the same format as Cargo config files.
```toml
[registry]
@@ -324,14 +327,14 @@ all capital letters.
> extension by default. However, for backward compatibility reason, when both
> files exist, Cargo will read and write the file without the extension.
-### Configuration keys
+## Configuration keys
This section documents all configuration keys. The description for keys with
variable parts are annotated with angled brackets like `target.<triple>` where
the `<triple>` part can be any [target triple] like
`target.x86_64-pc-windows-msvc`.
-#### `paths`
+### `paths`
* Type: array of strings (paths)
* Default: none
* Environment: not supported
@@ -340,7 +343,7 @@ An array of paths to local packages which are to be used as overrides for
dependencies. For more information see the [Overriding Dependencies
guide](overriding-dependencies.md#paths-overrides).
-#### `[alias]`
+### `[alias]`
* Type: string or array of strings
* Default: see below
* Environment: `CARGO_ALIAS_<name>`
@@ -372,11 +375,11 @@ rr = "run --release"
recursive_example = "rr --example recursions"
```
-#### `[build]`
+### `[build]`
The `[build]` table controls build-time operations and compiler settings.
-##### `build.jobs`
+#### `build.jobs`
* Type: integer or string
* Default: number of logical CPUs
* Environment: `CARGO_BUILD_JOBS`
@@ -388,14 +391,14 @@ the value back to defaults.
Can be overridden with the `--jobs` CLI option.
-##### `build.rustc`
+#### `build.rustc`
* Type: string (program path)
* Default: "rustc"
* Environment: `CARGO_BUILD_RUSTC` or `RUSTC`
Sets the executable to use for `rustc`.
-##### `build.rustc-wrapper`
+#### `build.rustc-wrapper`
* Type: string (program path)
* Default: none
* Environment: `CARGO_BUILD_RUSTC_WRAPPER` or `RUSTC_WRAPPER`
@@ -404,7 +407,7 @@ Sets a wrapper to execute instead of `rustc`. The first argument passed to the
wrapper is the path to the actual executable to use
(i.e., `build.rustc`, if that is set, or `"rustc"` otherwise).
-##### `build.rustc-workspace-wrapper`
+#### `build.rustc-workspace-wrapper`
* Type: string (program path)
* Default: none
* Environment: `CARGO_BUILD_RUSTC_WORKSPACE_WRAPPER` or `RUSTC_WORKSPACE_WRAPPER`
@@ -414,14 +417,14 @@ The first argument passed to the wrapper is the path to the actual
executable to use (i.e., `build.rustc`, if that is set, or `"rustc"` otherwise).
It affects the filename hash so that artifacts produced by the wrapper are cached separately.
-##### `build.rustdoc`
+#### `build.rustdoc`
* Type: string (program path)
* Default: "rustdoc"
* Environment: `CARGO_BUILD_RUSTDOC` or `RUSTDOC`
Sets the executable to use for `rustdoc`.
-##### `build.target`
+#### `build.target`
* Type: string or array of strings
* Default: host platform
* Environment: `CARGO_BUILD_TARGET`
@@ -441,7 +444,7 @@ Can be overridden with the `--target` CLI option.
target = ["x86_64-unknown-linux-gnu", "i686-unknown-linux-gnu"]
```
-##### `build.target-dir`
+#### `build.target-dir`
* Type: string (path)
* Default: "target"
* Environment: `CARGO_BUILD_TARGET_DIR` or `CARGO_TARGET_DIR`
@@ -451,7 +454,7 @@ is a directory named `target` located at the root of the workspace.
Can be overridden with the `--target-dir` CLI option.
-##### `build.rustflags`
+#### `build.rustflags`
* Type: string or array of strings
* Default: none
* Environment: `CARGO_BUILD_RUSTFLAGS` or `CARGO_ENCODED_RUSTFLAGS` or `RUSTFLAGS`
@@ -488,7 +491,7 @@ appropriate profile setting.
> flags you specify. This is an area where Cargo may not always be backwards
> compatible.
-##### `build.rustdocflags`
+#### `build.rustdocflags`
* Type: string or array of strings
* Default: none
* Environment: `CARGO_BUILD_RUSTDOCFLAGS` or `CARGO_ENCODED_RUSTDOCFLAGS` or `RUSTDOCFLAGS`
@@ -505,7 +508,7 @@ order, with the first one being used:
Additional flags may also be passed with the [`cargo rustdoc`] command.
-##### `build.incremental`
+#### `build.incremental`
* Type: bool
* Default: from profile
* Environment: `CARGO_BUILD_INCREMENTAL` or `CARGO_INCREMENTAL`
@@ -518,7 +521,7 @@ The `CARGO_INCREMENTAL` environment variable can be set to `1` to force enable
incremental compilation for all profiles, or `0` to disable it. This env var
overrides the config setting.
-##### `build.dep-info-basedir`
+#### `build.dep-info-basedir`
* Type: string (path)
* Default: none
* Environment: `CARGO_BUILD_DEP_INFO_BASEDIR`
@@ -532,15 +535,35 @@ The setting itself is a config-relative path. So, for example, a value of
`"."` would strip all paths starting with the parent directory of the `.cargo`
directory.
-##### `build.pipelining`
+#### `build.pipelining`
This option is deprecated and unused. Cargo always has pipelining enabled.
-#### `[doc]`
+### `[credential-alias]`
+* Type: string or array of strings
+* Default: empty
+* Environment: `CARGO_CREDENTIAL_ALIAS_<name>`
+
+The `[credential-alias]` table defines credential provider aliases.
+These aliases can be referenced as an element of the `registry.global-credential-providers`
+array, or as a credential provider for a specific registry
+under `registries.<NAME>.credential-provider`.
+
+If specified as a string, the value will be split on spaces into path and arguments.
+
+For example, to define an alias called `my-alias`:
+
+```toml
+[credential-alias]
+my-alias = ["/usr/bin/cargo-credential-example", "--argument", "value", "--flag"]
+```
+See [Registry Authentication](registry-authentication.md) for more information.
+
+### `[doc]`
The `[doc]` table defines options for the [`cargo doc`] command.
-##### `doc.browser`
+#### `doc.browser`
* Type: string or array of strings ([program path with args])
* Default: `BROWSER` environment variable, or, if that is missing,
@@ -550,19 +573,19 @@ This option sets the browser to be used by [`cargo doc`], overriding the
`BROWSER` environment variable when opening documentation with the `--open`
option.
-#### `[cargo-new]`
+### `[cargo-new]`
The `[cargo-new]` table defines defaults for the [`cargo new`] command.
-##### `cargo-new.name`
+#### `cargo-new.name`
This option is deprecated and unused.
-##### `cargo-new.email`
+#### `cargo-new.email`
This option is deprecated and unused.
-##### `cargo-new.vcs`
+#### `cargo-new.vcs`
* Type: string
* Default: "git" or "none"
* Environment: `CARGO_CARGO_NEW_VCS`
@@ -610,25 +633,25 @@ Controls how often we display a notification to the terminal when a future incom
* `always` (default): Always display a notification when a command (e.g. `cargo build`) produces a future incompat report
* `never`: Never display a notification
-#### `[http]`
+### `[http]`
The `[http]` table defines settings for HTTP behavior. This includes fetching
crate dependencies and accessing remote git repositories.
-##### `http.debug`
+#### `http.debug`
* Type: boolean
* Default: false
* Environment: `CARGO_HTTP_DEBUG`
If `true`, enables debugging of HTTP requests. The debug information can be
-seen by setting the `CARGO_LOG=cargo::ops::registry=debug` environment
-variable (or use `trace` for even more information).
+seen by setting the `CARGO_LOG=network=debug` environment
+variable (or use `network=trace` for even more information).
Be wary when posting logs from this output in a public location. The output
may include headers with authentication tokens which you don't want to leak!
Be sure to review logs before posting them.
-##### `http.proxy`
+#### `http.proxy`
* Type: string
* Default: none
* Environment: `CARGO_HTTP_PROXY` or `HTTPS_PROXY` or `https_proxy` or `http_proxy`
@@ -639,14 +662,14 @@ setting in your global git configuration. If none of those are set, the
`HTTPS_PROXY` or `https_proxy` environment variables set the proxy for HTTPS
requests, and `http_proxy` sets it for HTTP requests.
-##### `http.timeout`
+#### `http.timeout`
* Type: integer
* Default: 30
* Environment: `CARGO_HTTP_TIMEOUT` or `HTTP_TIMEOUT`
Sets the timeout for each HTTP request, in seconds.
-##### `http.cainfo`
+#### `http.cainfo`
* Type: string (path)
* Default: none
* Environment: `CARGO_HTTP_CAINFO`
@@ -654,7 +677,7 @@ Sets the timeout for each HTTP request, in seconds.
Path to a Certificate Authority (CA) bundle file, used to verify TLS
certificates. If not specified, Cargo attempts to use the system certificates.
-##### `http.check-revoke`
+#### `http.check-revoke`
* Type: boolean
* Default: true (Windows) false (all others)
* Environment: `CARGO_HTTP_CHECK_REVOKE`
@@ -662,7 +685,7 @@ certificates. If not specified, Cargo attempts to use the system certificates.
This determines whether or not TLS certificate revocation checks should be
performed. This only works on Windows.
-##### `http.ssl-version`
+#### `http.ssl-version`
* Type: string or min/max table
* Default: none
* Environment: `CARGO_HTTP_SSL_VERSION`
@@ -678,7 +701,7 @@ range of TLS versions to use.
The default is a minimum version of "tlsv1.0" and a max of the newest version
supported on your platform, typically "tlsv1.3".
-##### `http.low-speed-limit`
+#### `http.low-speed-limit`
* Type: integer
* Default: 10
* Environment: `CARGO_HTTP_LOW_SPEED_LIMIT`
@@ -688,7 +711,7 @@ transfer speed in bytes per second is below the given value for
[`http.timeout`](#httptimeout) seconds (default 30 seconds), then the
connection is considered too slow and Cargo will abort and retry.
-##### `http.multiplexing`
+#### `http.multiplexing`
* Type: boolean
* Default: true
* Environment: `CARGO_HTTP_MULTIPLEXING`
@@ -698,7 +721,7 @@ This allows multiple requests to use the same connection, usually improving
performance when fetching multiple files. If `false`, Cargo will use HTTP 1.1
without pipelining.
-##### `http.user-agent`
+#### `http.user-agent`
* Type: string
* Default: Cargo's version
* Environment: `CARGO_HTTP_USER_AGENT`
@@ -706,11 +729,11 @@ without pipelining.
Specifies a custom user-agent header to use. The default if not specified is a
string that includes Cargo's version.
-#### `[install]`
+### `[install]`
The `[install]` table defines defaults for the [`cargo install`] command.
-##### `install.root`
+#### `install.root`
* Type: string (path)
* Default: Cargo's home directory
* Environment: `CARGO_INSTALL_ROOT`
@@ -726,18 +749,18 @@ your home directory).
Can be overridden with the `--root` command-line option.
-#### `[net]`
+### `[net]`
The `[net]` table controls networking configuration.
-##### `net.retry`
+#### `net.retry`
* Type: integer
* Default: 3
* Environment: `CARGO_NET_RETRY`
Number of times to retry possibly spurious network errors.
-##### `net.git-fetch-with-cli`
+#### `net.git-fetch-with-cli`
* Type: boolean
* Default: false
* Environment: `CARGO_NET_GIT_FETCH_WITH_CLI`
@@ -751,7 +774,7 @@ requirements that Cargo does not support. See [Git
Authentication](../appendix/git-authentication.md) for more information about
setting up git authentication.
-##### `net.offline`
+#### `net.offline`
* Type: boolean
* Default: false
* Environment: `CARGO_NET_OFFLINE`
@@ -762,11 +785,11 @@ needed, and generate an error if it encounters a network error.
Can be overridden with the `--offline` command-line option.
-##### `net.ssh`
+#### `net.ssh`
The `[net.ssh]` table contains settings for SSH connections.
-##### `net.ssh.known-hosts`
+#### `net.ssh.known-hosts`
* Type: array of strings
* Default: see description
* Environment: not supported
@@ -797,7 +820,7 @@ for more details.
[github-keys]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
-#### `[patch]`
+### `[patch]`
Just as you can override dependencies using [`[patch]` in
`Cargo.toml`](overriding-dependencies.md#the-patch-section), you can
@@ -822,7 +845,7 @@ lowest precedence.
Relative `path` dependencies in such a `[patch]` section are resolved
relative to the configuration file they appear in.
-#### `[profile]`
+### `[profile]`
The `[profile]` table can be used to globally change profile settings, and
override settings specified in `Cargo.toml`. It has the same syntax and
@@ -831,91 +854,91 @@ details about the options.
[Profiles chapter]: profiles.md
-##### `[profile.<name>.build-override]`
+#### `[profile.<name>.build-override]`
* Environment: `CARGO_PROFILE_<name>_BUILD_OVERRIDE_<key>`
The build-override table overrides settings for build scripts, proc macros,
and their dependencies. It has the same keys as a normal profile. See the
[overrides section](profiles.md#overrides) for more details.
-##### `[profile.<name>.package.<name>]`
+#### `[profile.<name>.package.<name>]`
* Environment: not supported
The package table overrides settings for specific packages. It has the same
keys as a normal profile, minus the `panic`, `lto`, and `rpath` settings. See
the [overrides section](profiles.md#overrides) for more details.
-##### `profile.<name>.codegen-units`
+#### `profile.<name>.codegen-units`
* Type: integer
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_CODEGEN_UNITS`
See [codegen-units](profiles.md#codegen-units).
-##### `profile.<name>.debug`
+#### `profile.<name>.debug`
* Type: integer or boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_DEBUG`
See [debug](profiles.md#debug).
-##### `profile.<name>.split-debuginfo`
+#### `profile.<name>.split-debuginfo`
* Type: string
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_SPLIT_DEBUGINFO`
See [split-debuginfo](profiles.md#split-debuginfo).
-##### `profile.<name>.debug-assertions`
+#### `profile.<name>.debug-assertions`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_DEBUG_ASSERTIONS`
See [debug-assertions](profiles.md#debug-assertions).
-##### `profile.<name>.incremental`
+#### `profile.<name>.incremental`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_INCREMENTAL`
See [incremental](profiles.md#incremental).
-##### `profile.<name>.lto`
+#### `profile.<name>.lto`
* Type: string or boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_LTO`
See [lto](profiles.md#lto).
-##### `profile.<name>.overflow-checks`
+#### `profile.<name>.overflow-checks`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_OVERFLOW_CHECKS`
See [overflow-checks](profiles.md#overflow-checks).
-##### `profile.<name>.opt-level`
+#### `profile.<name>.opt-level`
* Type: integer or string
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_OPT_LEVEL`
See [opt-level](profiles.md#opt-level).
-##### `profile.<name>.panic`
+#### `profile.<name>.panic`
* Type: string
* default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_PANIC`
See [panic](profiles.md#panic).
-##### `profile.<name>.rpath`
+#### `profile.<name>.rpath`
* Type: boolean
* default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_RPATH`
See [rpath](profiles.md#rpath).
-##### `profile.<name>.strip`
+#### `profile.<name>.strip`
* Type: string
* default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_STRIP`
@@ -923,19 +946,19 @@ See [rpath](profiles.md#rpath).
See [strip](profiles.md#strip).
-#### `[registries]`
+### `[registries]`
The `[registries]` table is used for specifying additional [registries]. It
consists of a sub-table for each named registry.
-##### `registries.<name>.index`
+#### `registries.<name>.index`
* Type: string (url)
* Default: none
* Environment: `CARGO_REGISTRIES_<name>_INDEX`
Specifies the URL of the index for the registry.
-##### `registries.<name>.token`
+#### `registries.<name>.token`
* Type: string
* Default: none
* Environment: `CARGO_REGISTRIES_<name>_TOKEN`
@@ -946,7 +969,23 @@ commands like [`cargo publish`] that require authentication.
Can be overridden with the `--token` command-line option.
-##### `registries.crates-io.protocol`
+#### `registries.<name>.credential-provider`
+* Type: string or array of path and arguments
+* Default: none
+* Environment: `CARGO_REGISTRIES_<name>_CREDENTIAL_PROVIDER`
+
+Specifies the credential provider for the given registry. If not set, the
+providers in [`registry.global-credential-providers`](#registryglobal-credential-providers)
+will be used.
+
+If specified as a string, path and arguments will be split on spaces. For
+paths or arguments that contain spaces, use an array.
+
+If the value exists in the [`[credential-alias]`](#credential-alias) table, the alias will be used.
+
+See [Registry Authentication](registry-authentication.md) for more information.
+
+#### `registries.crates-io.protocol`
* Type: string
* Default: `sparse`
* Environment: `CARGO_REGISTRIES_CRATES_IO_PROTOCOL`
@@ -960,16 +999,16 @@ This can result in a significant performance improvement for resolving new depen
More information about registry protocols may be found in the [Registries chapter](registries.md).
-#### `[registry]`
+### `[registry]`
The `[registry]` table controls the default registry used when one is not
specified.
-##### `registry.index`
+#### `registry.index`
This value is no longer accepted and should not be used.
-##### `registry.default`
+#### `registry.default`
* Type: string
* Default: `"crates-io"`
* Environment: `CARGO_REGISTRY_DEFAULT`
@@ -979,7 +1018,23 @@ by default for registry commands like [`cargo publish`].
Can be overridden with the `--registry` command-line option.
-##### `registry.token`
+#### `registry.credential-provider`
+* Type: string or array of path and arguments
+* Default: none
+* Environment: `CARGO_REGISTRY_CREDENTIAL_PROVIDER`
+
+Specifies the credential provider for [crates.io]. If not set, the
+providers in [`registry.global-credential-providers`](#registryglobal-credential-providers)
+will be used.
+
+If specified as a string, path and arguments will be split on spaces. For
+paths or arguments that contain spaces, use an array.
+
+If the value exists in the `[credential-alias]` table, the alias will be used.
+
+See [Registry Authentication](registry-authentication.md) for more information.
+
+#### `registry.token`
* Type: string
* Default: none
* Environment: `CARGO_REGISTRY_TOKEN`
@@ -990,49 +1045,64 @@ commands like [`cargo publish`] that require authentication.
Can be overridden with the `--token` command-line option.
-#### `[source]`
+#### `registry.global-credential-providers`
+* Type: array
+* Default: `["cargo:token"]`
+* Environment: `CARGO_REGISTRY_GLOBAL_CREDENTIAL_PROVIDERS`
+
+Specifies the list of global credential providers. If credential provider is not set
+for a specific registry using `registries.<name>.credential-provider`, Cargo will use
+the credential providers in this list. Providers toward the end of the list have precedence.
+
+Path and arguments are split on spaces. If the path or arguments contains spaces, the credential
+provider should be defined in the [`[credential-alias]`](#credential-alias) table and
+referenced here by its alias.
+
+See [Registry Authentication](registry-authentication.md) for more information.
+
+### `[source]`
The `[source]` table defines the registry sources available. See [Source
Replacement] for more information. It consists of a sub-table for each named
source. A source should only define one kind (directory, registry,
local-registry, or git).
-##### `source.<name>.replace-with`
+#### `source.<name>.replace-with`
* Type: string
* Default: none
* Environment: not supported
If set, replace this source with the given named source or named registry.
-##### `source.<name>.directory`
+#### `source.<name>.directory`
* Type: string (path)
* Default: none
* Environment: not supported
Sets the path to a directory to use as a directory source.
-##### `source.<name>.registry`
+#### `source.<name>.registry`
* Type: string (url)
* Default: none
* Environment: not supported
Sets the URL to use for a registry source.
-##### `source.<name>.local-registry`
+#### `source.<name>.local-registry`
* Type: string (path)
* Default: none
* Environment: not supported
Sets the path to a directory to use as a local registry source.
-##### `source.<name>.git`
+#### `source.<name>.git`
* Type: string (url)
* Default: none
* Environment: not supported
Sets the URL to use for a git repository source.
-##### `source.<name>.branch`
+#### `source.<name>.branch`
* Type: string
* Default: none
* Environment: not supported
@@ -1041,7 +1111,7 @@ Sets the branch name to use for a git repository.
If none of `branch`, `tag`, or `rev` is set, defaults to the `master` branch.
-##### `source.<name>.tag`
+#### `source.<name>.tag`
* Type: string
* Default: none
* Environment: not supported
@@ -1050,7 +1120,7 @@ Sets the tag name to use for a git repository.
If none of `branch`, `tag`, or `rev` is set, defaults to the `master` branch.
-##### `source.<name>.rev`
+#### `source.<name>.rev`
* Type: string
* Default: none
* Environment: not supported
@@ -1060,7 +1130,7 @@ Sets the [revision] to use for a git repository.
If none of `branch`, `tag`, or `rev` is set, defaults to the `master` branch.
-#### `[target]`
+### `[target]`
The `[target]` table is used for specifying settings for specific platform
targets. It consists of a sub-table which is either a [platform triple][target triple]
@@ -1086,11 +1156,11 @@ to view), values set by [build scripts], and extra `--cfg` flags passed to
If using a target spec JSON file, the [`<triple>`] value is the filename stem.
For example `--target foo/bar.json` would match `[target.bar]`.
-##### `target.<triple>.ar`
+#### `target.<triple>.ar`
This option is deprecated and unused.
-##### `target.<triple>.linker`
+#### `target.<triple>.linker`
* Type: string (program path)
* Default: none
* Environment: `CARGO_TARGET_<triple>_LINKER`
@@ -1098,7 +1168,13 @@ This option is deprecated and unused.
Specifies the linker which is passed to `rustc` (via [`-C linker`]) when the
[`<triple>`] is being compiled for. By default, the linker is not overridden.
-##### `target.<triple>.runner`
+#### `target.<cfg>.linker`
+This is similar to the [target linker](#targettriplelinker), but using
+a [`cfg()` expression]. If both a [`<triple>`] and `<cfg>` runner match,
+the `<triple>` will take precedence. It is an error if more than one
+`<cfg>` runner matches the current target.
+
+#### `target.<triple>.runner`
* Type: string or array of strings ([program path with args])
* Default: none
* Environment: `CARGO_TARGET_<triple>_RUNNER`
@@ -1108,14 +1184,14 @@ executed by invoking the specified runner with the actual executable passed as
an argument. This applies to [`cargo run`], [`cargo test`] and [`cargo bench`]
commands. By default, compiled executables are executed directly.
-##### `target.<cfg>.runner`
+#### `target.<cfg>.runner`
This is similar to the [target runner](#targettriplerunner), but using
a [`cfg()` expression]. If both a [`<triple>`] and `<cfg>` runner match,
the `<triple>` will take precedence. It is an error if more than one
`<cfg>` runner matches the current target.
-##### `target.<triple>.rustflags`
+#### `target.<triple>.rustflags`
* Type: string or array of strings
* Default: none
* Environment: `CARGO_TARGET_<triple>_RUSTFLAGS`
@@ -1126,13 +1202,13 @@ The value may be an array of strings or a space-separated string.
See [`build.rustflags`](#buildrustflags) for more details on the different
ways to specific extra flags.
-##### `target.<cfg>.rustflags`
+#### `target.<cfg>.rustflags`
This is similar to the [target rustflags](#targettriplerustflags), but
using a [`cfg()` expression]. If several `<cfg>` and [`<triple>`] entries
match the current target, the flags are joined together.
-##### `target.<triple>.<links>`
+#### `target.<triple>.<links>`
The links sub-table provides a way to [override a build script]. When
specified, the build script for the given `links` library will not be
@@ -1150,11 +1226,11 @@ metadata_key1 = "value"
metadata_key2 = "value"
```
-#### `[term]`
+### `[term]`
The `[term]` table controls terminal output and interaction.
-##### `term.quiet`
+#### `term.quiet`
* Type: boolean
* Default: false
* Environment: `CARGO_TERM_QUIET`
@@ -1164,7 +1240,7 @@ Controls whether or not log messages are displayed by Cargo.
Specifying the `--quiet` flag will override and force quiet output.
Specifying the `--verbose` flag will override and disable quiet output.
-##### `term.verbose`
+#### `term.verbose`
* Type: boolean
* Default: false
* Environment: `CARGO_TERM_VERBOSE`
@@ -1174,7 +1250,7 @@ Controls whether or not extra detailed messages are displayed by Cargo.
Specifying the `--quiet` flag will override and disable verbose output.
Specifying the `--verbose` flag will override and force verbose output.
-##### `term.color`
+#### `term.color`
* Type: string
* Default: "auto"
* Environment: `CARGO_TERM_COLOR`
@@ -1188,7 +1264,7 @@ Controls whether or not colored output is used in the terminal. Possible values:
Can be overridden with the `--color` command-line option.
-##### `term.progress.when`
+#### `term.progress.when`
* Type: string
* Default: "auto"
* Environment: `CARGO_TERM_PROGRESS_WHEN`
@@ -1199,7 +1275,7 @@ Controls whether or not progress bar is shown in the terminal. Possible values:
* `always`: Always show progress bar.
* `never`: Never show progress bar.
-##### `term.progress.width`
+#### `term.progress.width`
* Type: integer
* Default: none
* Environment: `CARGO_TERM_PROGRESS_WIDTH`
diff --git a/src/tools/cargo/src/doc/src/reference/credential-provider-protocol.md b/src/tools/cargo/src/doc/src/reference/credential-provider-protocol.md
new file mode 100644
index 000000000..31006abee
--- /dev/null
+++ b/src/tools/cargo/src/doc/src/reference/credential-provider-protocol.md
@@ -0,0 +1,237 @@
+# Credential Provider Protocol
+This document describes information for building a Cargo credential provider. For information on
+setting up or using a credential provider, see [Registry Authentication](registry-authentication.md).
+
+When using an external credential provider, Cargo communicates with the credential
+provider using stdin/stdout messages passed as single lines of JSON.
+
+Cargo will always execute the credential provider with the `--cargo-plugin` argument.
+This enables a credential provider executable to have additional functionality beyond
+what Cargo needs. Additional arguments are included in the JSON via the `args` field.
+
+## JSON messages
+The JSON messages in this document have newlines added for readability.
+Actual messages must not contain newlines.
+
+### Credential hello
+* Sent by: credential provider
+* Purpose: used to identify the supported protocols on process startup
+```javascript
+{
+ "v":[1]
+}
+```
+
+Requests sent by Cargo will include a `v` field set to one of the versions listed here.
+If Cargo does not support any of the versions offered by the credential provider, it will issue an
+error and shut down the credential process.
+
+### Registry information
+* Sent by: Cargo
+Not a message by itself. Included in all messages sent by Cargo as the `registry` field.
+```javascript
+{
+ // Index URL of the registry
+ "index-url":"https://github.com/rust-lang/crates.io-index",
+ // Name of the registry in configuration (optional)
+ "name": "crates-io",
+ // HTTP headers received from attempting to access an authenticated registry (optional)
+ "headers": ["WWW-Authenticate: cargo"]
+}
+```
+
+### Login request
+* Sent by: Cargo
+* Purpose: collect and store credentials
+```javascript
+{
+ // Protocol version
+ "v":1,
+ // Action to perform: login
+ "kind":"login",
+ // Registry information (see Registry information)
+ "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"},
+ // User-specified token from stdin or command line (optional)
+ "token": "<the token value>",
+ // URL that the user could visit to get a token (optional)
+ "login-url": "http://registry-url/login",
+ // Additional command-line args (optional)
+ "args":[]
+}
+```
+
+If the `token` field is set, then the credential provider should use the token provided. If
+the `token` is not set, then the credential provider should prompt the user for a token.
+
+In addition to the arguments that may be passed to the credential provider in
+configuration, `cargo login` also supports passing additional command line args
+via `cargo login -- <additional args>`. These additional arguments will be included
+in the `args` field after any args from Cargo configuration.
+
+### Read request
+* Sent by: Cargo
+* Purpose: Get the credential for reading crate information
+```javascript
+{
+ // Protocol version
+ "v":1,
+ // Request kind: get credentials
+ "kind":"get",
+ // Action to perform: read crate information
+ "operation":"read",
+ // Registry information (see Registry information)
+ "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"},
+ // Additional command-line args (optional)
+ "args":[]
+}
+```
+
+### Publish request
+* Sent by: Cargo
+* Purpose: Get the credential for publishing a crate
+```javascript
+{
+ // Protocol version
+ "v":1,
+ // Request kind: get credentials
+ "kind":"get",
+ // Action to perform: publish crate
+ "operation":"publish",
+ // Crate name
+ "name":"sample",
+ // Crate version
+ "vers":"0.1.0",
+ // Crate checksum
+ "cksum":"...",
+ // Registry information (see Registry information)
+ "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"},
+ // Additional command-line args (optional)
+ "args":[]
+}
+```
+
+### Get success response
+* Sent by: credential provider
+* Purpose: Gives the credential to Cargo
+```javascript
+{"Ok":{
+ // Response kind: this was a get request
+ "kind":"get",
+ // Token to send to the registry
+ "token":"...",
+ // Cache control. Can be one of the following:
+ // * "never": do not cache
+ // * "session": cache for the current cargo session
+ // * "expires": cache for the current cargo session until expiration
+ "cache":"expires",
+ // Unix timestamp (only for "cache": "expires")
+ "expiration":1693942857,
+ // Is the token operation independent?
+ "operation_independent":true
+}}
+```
+
+The `token` will be sent to the registry as the value of the `Authorization` HTTP header.
+
+`operation_independent` indicates whether the token can be cached across different
+operations (such as publishing or fetching). In general, this should be `true` unless
+the provider wants to generate tokens that are scoped to specific operations.
+
+### Login success response
+* Sent by: credential provider
+* Purpose: Indicates the login was successful
+```javascript
+{"Ok":{
+ // Response kind: this was a login request
+ "kind":"login"
+}}
+```
+
+### Logout success response
+* Sent by: credential provider
+* Purpose: Indicates the logout was successful
+```javascript
+{"Ok":{
+ // Response kind: this was a logout request
+ "kind":"logout"
+}}
+```
+
+### Failure response (URL not supported)
+* Sent by: credential provider
+* Purpose: Gives error information to Cargo
+```javascript
+{"Err":{
+ "kind":"url-not-supported"
+}}
+```
+Sent if the credential provider is designed
+to only handle specific registry URLs and the given URL
+is not supported. Cargo will attempt another provider if
+available.
+
+### Failure response (not found)
+* Sent by: credential provider
+* Purpose: Gives error information to Cargo
+```javascript
+{"Err":{
+ // Error: The credential could not be found in the provider.
+ "kind":"not-found"
+}}
+```
+Sent if the credential could not be found. This is expected for
+`get` requests where the credential is not available, or `logout`
+requests where there is nothing found to erase.
+
+### Failure response (operation not supported)
+* Sent by: credential provider
+* Purpose: Gives error information to Cargo
+```javascript
+{"Err":{
+ // Error: The credential could not be found in the provider.
+ "kind":"operation-not-supported"
+}}
+```
+Sent if the credential provider does not support the requested operation.
+If a provider only supports `get` and a `login` is requested, the
+provider should respond with this error.
+
+### Failure response (other)
+* Sent by: credential provider
+* Purpose: Gives error information to Cargo
+```javascript
+{"Err":{
+ // Error: something else has failed
+ "kind":"other",
+ // Error message string to be displayed
+ "message": "free form string error message",
+ // Detailed cause chain for the error (optional)
+ "caused-by": ["cause 1", "cause 2"]
+}}
+```
+
+## Example communication to request a token for reading:
+1. Cargo spawns the credential process, capturing stdin and stdout.
+2. Credential process sends the Hello message to Cargo
+ ```javascript
+ { "v": [1] }
+ ```
+3. Cargo sends the CredentialRequest message to the credential process (newlines added for readability).
+ ```javascript
+ {
+ "v": 1,
+ "kind": "get",
+ "operation": "read",
+ "registry":{"index-url":"sparse+https://registry-url/index/"}
+ }
+ ```
+4. Credential process sends the CredentialResponse to Cargo (newlines added for readability).
+ ```javascript
+ {
+ "token": "...",
+ "cache": "session",
+ "operation_independent": true
+ }
+ ```
+5. Cargo closes the stdin pipe to the credential provider and it exits.
+6. Cargo uses the token for the remainder of the session (until Cargo exits) when interacting with this registry.
diff --git a/src/tools/cargo/src/doc/src/reference/environment-variables.md b/src/tools/cargo/src/doc/src/reference/environment-variables.md
index 25881d138..37c788f8d 100644
--- a/src/tools/cargo/src/doc/src/reference/environment-variables.md
+++ b/src/tools/cargo/src/doc/src/reference/environment-variables.md
@@ -1,10 +1,10 @@
-## Environment Variables
+# Environment Variables
Cargo sets and reads a number of environment variables which your code can detect
or override. Here is a list of the variables Cargo sets, organized by when it interacts
with them:
-### Environment variables Cargo reads
+## Environment variables Cargo reads
You can override these environment variables to change Cargo's behavior on your
system:
@@ -79,7 +79,7 @@ system:
[`cargo fmt`](https://github.com/rust-lang/rustfmt) will execute this specified
`rustfmt` instance instead.
-#### Configuration environment variables
+### Configuration environment variables
Cargo reads environment variables for some configuration values.
See the [configuration chapter][config-env] for more details.
@@ -124,9 +124,12 @@ In summary, the supported environment variables are:
* `CARGO_PROFILE_<name>_RPATH` --- The rpath linking option, see [`profile.<name>.rpath`].
* `CARGO_PROFILE_<name>_SPLIT_DEBUGINFO` --- Controls debug file output behavior, see [`profile.<name>.split-debuginfo`].
* `CARGO_PROFILE_<name>_STRIP` --- Controls stripping of symbols and/or debuginfos, see [`profile.<name>.strip`].
+* `CARGO_REGISTRIES_<name>_CREDENTIAL_PROVIDER` --- Credential provider for a registry, see [`registries.<name>.credential-provider`].
* `CARGO_REGISTRIES_<name>_INDEX` --- URL of a registry index, see [`registries.<name>.index`].
* `CARGO_REGISTRIES_<name>_TOKEN` --- Authentication token of a registry, see [`registries.<name>.token`].
+* `CARGO_REGISTRY_CREDENTIAL_PROVIDER` --- Credential provider for [crates.io], see [`registry.credential-provider`].
* `CARGO_REGISTRY_DEFAULT` --- Default registry for the `--registry` flag, see [`registry.default`].
+* `CARGO_REGISTRY_GLOBAL_CREDENTIAL_PROVIDERS` --- Credential providers for registries that do not have a specific provider defined. See [`registry.global-credential-providers`].
* `CARGO_REGISTRY_TOKEN` --- Authentication token for [crates.io], see [`registry.token`].
* `CARGO_TARGET_<triple>_LINKER` --- The linker to use, see [`target.<triple>.linker`]. The triple must be [converted to uppercase and underscores](config.md#environment-variables).
* `CARGO_TARGET_<triple>_RUNNER` --- The executable runner, see [`target.<triple>.runner`].
@@ -187,9 +190,12 @@ In summary, the supported environment variables are:
[`profile.<name>.rpath`]: config.md#profilenamerpath
[`profile.<name>.split-debuginfo`]: config.md#profilenamesplit-debuginfo
[`profile.<name>.strip`]: config.md#profilenamestrip
+[`registries.<name>.credential-provider`]: config.md#registriesnamecredential-provider
[`registries.<name>.index`]: config.md#registriesnameindex
[`registries.<name>.token`]: config.md#registriesnametoken
+[`registry.credential-provider`]: config.md#registrycredential-provider
[`registry.default`]: config.md#registrydefault
+[`registry.global-credential-providers`]: config.md#registryglobal-credential-providers
[`registry.token`]: config.md#registrytoken
[`target.<triple>.linker`]: config.md#targettriplelinker
[`target.<triple>.runner`]: config.md#targettriplerunner
@@ -200,7 +206,7 @@ In summary, the supported environment variables are:
[`term.progress.when`]: config.md#termprogresswhen
[`term.progress.width`]: config.md#termprogresswidth
-### Environment variables Cargo sets for crates
+## Environment variables Cargo sets for crates
Cargo exposes these environment variables to your crate when it is compiled.
Note that this applies for running binaries with `cargo run` and `cargo test`
@@ -266,7 +272,7 @@ corresponding environment variable is set to the empty string, `""`.
[integration test]: cargo-targets.md#integration-tests
[`env` macro]: ../../std/macro.env.html
-#### Dynamic library paths
+### Dynamic library paths
Cargo also sets the dynamic library path when compiling and running binaries
with commands like `cargo run` and `cargo test`. This helps with locating
@@ -294,7 +300,7 @@ Cargo includes the following paths:
* The rustc sysroot library path. This generally is not important to most
users.
-### Environment variables Cargo sets for build scripts
+## Environment variables Cargo sets for build scripts
Cargo sets several environment variables when build scripts are run. Because these variables
are not yet set when the build script is compiled, the above example using `env!` won't work
@@ -411,7 +417,7 @@ let out_dir = env::var("OUT_DIR").unwrap();
[`dev`]: profiles.md#dev
[`release`]: profiles.md#release
-### Environment variables Cargo sets for 3rd party subcommands
+## Environment variables Cargo sets for 3rd party subcommands
Cargo exposes this environment variable to 3rd party subcommands
(ie. programs named `cargo-foobar` placed in `$PATH`):
diff --git a/src/tools/cargo/src/doc/src/reference/external-tools.md b/src/tools/cargo/src/doc/src/reference/external-tools.md
index b2f37ca0b..e835ea3ee 100644
--- a/src/tools/cargo/src/doc/src/reference/external-tools.md
+++ b/src/tools/cargo/src/doc/src/reference/external-tools.md
@@ -1,4 +1,4 @@
-## External tools
+# External tools
One of the goals of Cargo is simple integration with third-party tools, like
IDEs and other build systems. To make integration easier, Cargo has several
@@ -13,7 +13,7 @@ facilities:
* support for custom subcommands.
-### Information about package structure
+## Information about package structure
You can use [`cargo metadata`] command to get information about package
structure and dependencies. See the [`cargo metadata`] documentation
@@ -29,7 +29,7 @@ output.
[cargo_metadata]: https://crates.io/crates/cargo_metadata
[`cargo metadata`]: ../commands/cargo-metadata.md
-### JSON messages
+## JSON messages
When passing `--message-format=json`, Cargo will output the following
information during the build:
@@ -54,7 +54,7 @@ messages.
[build command documentation]: ../commands/cargo-build.md
[cargo_metadata]: https://crates.io/crates/cargo_metadata
-#### Compiler messages
+### Compiler messages
The "compiler-message" message includes output from the compiler, such as
warnings and errors. See the [rustc JSON chapter](../../rustc/json.md) for
@@ -125,7 +125,7 @@ structure:
}
```
-#### Artifact messages
+### Artifact messages
For every compilation step, a "compiler-artifact" message is emitted with the
following structure:
@@ -192,7 +192,7 @@ following structure:
```
-#### Build script output
+### Build script output
The "build-script-executed" message includes the parsed output of a build
script. Note that this is emitted even if the build script is not run; it will
@@ -233,7 +233,7 @@ may be found in [the chapter on build scripts](build-scripts.md).
}
```
-#### Build finished
+### Build finished
The "build-finished" message is emitted at the end of the build.
@@ -257,7 +257,7 @@ executed by `cargo run`).
> so additional test-specific JSON messages may begin arriving after the
> "build-finished" message if that is enabled.
-### Custom subcommands
+## Custom subcommands
Cargo is designed to be extensible with new subcommands without having to modify
Cargo itself. This is achieved by translating a cargo invocation of the form
diff --git a/src/tools/cargo/src/doc/src/reference/features-examples.md b/src/tools/cargo/src/doc/src/reference/features-examples.md
index ac9636fcb..810288dda 100644
--- a/src/tools/cargo/src/doc/src/reference/features-examples.md
+++ b/src/tools/cargo/src/doc/src/reference/features-examples.md
@@ -1,8 +1,8 @@
-## Features Examples
+# Features Examples
The following illustrates some real-world examples of features in action.
-### Minimizing build times and file sizes
+## Minimizing build times and file sizes
Some packages use features so that if the features are not enabled, it reduces
the size of the crate and reduces compile time. Some examples are:
@@ -30,7 +30,7 @@ the size of the crate and reduces compile time. Some examples are:
[`web-sys`]: https://crates.io/crates/web-sys
[web-sys-features]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/crates/web-sys/Cargo.toml#L32-L1395
-### Extending behavior
+## Extending behavior
The [`serde_json`] package has a [`preserve_order` feature][serde_json-preserve_order]
which [changes the behavior][serde_json-code] of JSON maps to preserve the
@@ -47,7 +47,7 @@ usually builds with the feature off.
[serde_json-code]: https://github.com/serde-rs/json/blob/v1.0.60/src/map.rs#L23-L26
[`indexmap`]: https://crates.io/crates/indexmap
-### `no_std` support
+## `no_std` support
Some packages want to support both [`no_std`] and `std` environments. This is
useful for supporting embedded and resource-constrained platforms, but still
@@ -71,7 +71,7 @@ to conditionally enable extra functionality that requires `std`.
[wasm-bindgen-cfg1]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L270-L273
[wasm-bindgen-cfg2]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L67-L75
-### Re-exporting dependency features
+## Re-exporting dependency features
It can be convenient to re-export the features from a dependency. This allows
the user depending on the crate to control those features without needing to
@@ -83,7 +83,7 @@ but they can still access the features it contains.
[regex-re-export]: https://github.com/rust-lang/regex/blob/1.4.2/Cargo.toml#L65-L89
[regex_syntax-features]: https://github.com/rust-lang/regex/blob/1.4.2/regex-syntax/Cargo.toml#L17-L32
-### Vendoring of C libraries
+## Vendoring of C libraries
Some packages provide bindings to common C libraries (sometimes referred to as
["sys" crates][sys]). Sometimes these packages give you the choice to use the
@@ -111,7 +111,7 @@ static-curl setting.
[curl-sys-macos]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/Cargo.toml#L52
[curl-sys-macos-code]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/build.rs#L15-L20
-### Feature precedence
+## Feature precedence
Some packages may have mutually-exclusive features. One option to handle this
is to prefer one feature over another. The [`log`] package is an example. It
@@ -126,7 +126,7 @@ levels will be preferred over the lower levels.
[log-cfg-if]: https://github.com/rust-lang/log/blob/0.4.11/src/lib.rs#L1422-L1448
[`cfg-if`]: https://crates.io/crates/cfg-if
-### Proc-macro companion package
+## Proc-macro companion package
Some packages have a proc-macro that is intimately tied with it. However, not
all users will need to use the proc-macro. By making the proc-macro an
@@ -145,7 +145,7 @@ requirement][serde-equals] to ensure they stay in sync.
[serde-derive]: https://github.com/serde-rs/serde/blob/v1.0.118/serde/Cargo.toml#L34-L35
[serde-equals]: https://github.com/serde-rs/serde/blob/v1.0.118/serde/Cargo.toml#L17
-### Nightly-only features
+## Nightly-only features
Some packages want to experiment with APIs or language features that are only
available on the Rust [nightly channel]. However, they may not want to require
@@ -172,7 +172,7 @@ which relies on a dependency that only builds on the nightly channel.
[`rand`]: https://crates.io/crates/rand
[rand-simd_support]: https://github.com/rust-random/rand/blob/0.7.3/Cargo.toml#L40
-### Experimental features
+## Experimental features
Some packages have new functionality that they may want to experiment with,
without having to commit to the stability of those APIs. The features are
diff --git a/src/tools/cargo/src/doc/src/reference/features.md b/src/tools/cargo/src/doc/src/reference/features.md
index 40eb32c41..9e521049c 100644
--- a/src/tools/cargo/src/doc/src/reference/features.md
+++ b/src/tools/cargo/src/doc/src/reference/features.md
@@ -1,4 +1,4 @@
-## Features
+# Features
Cargo "features" provide a mechanism to express [conditional compilation] and
[optional dependencies](#optional-dependencies). A package defines a set of
@@ -13,7 +13,7 @@ be used.
[conditional compilation]: ../../reference/conditional-compilation.md
[Features Examples]: features-examples.md
-### The `[features]` section
+## The `[features]` section
Features are defined in the `[features]` table in `Cargo.toml`. Each feature
specifies an array of other features or optional dependencies that it enables.
@@ -68,7 +68,7 @@ includes most letters), and additionally allows starting with `_` or digits
[`cfg` attribute]: ../../reference/conditional-compilation.md#the-cfg-attribute
[`cfg` macro]: ../../std/macro.cfg.html
-### The `default` feature
+## The `default` feature
By default, all features are disabled unless explicitly enabled. This can be
changed by specifying the `default` feature:
@@ -105,7 +105,7 @@ enables the listed features. This behavior can be changed by:
> change](#semver-compatibility) to remove a feature from the default set, so
> you should be confident that you will keep those features.
-### Optional dependencies
+## Optional dependencies
Dependencies can be marked "optional", which means they will not be compiled
by default. For example, let's say that our 2D image processing library uses
@@ -164,7 +164,7 @@ our crate.
[platform-specific dependencies]: specifying-dependencies.md#platform-specific-dependencies
-### Dependency features
+## Dependency features
Features of dependencies can be enabled within the dependency declaration. The
`features` key indicates which features to enable:
@@ -226,7 +226,7 @@ dependency.
It will also enable the `serde` feature for the `rgb` dependency, but only if
something else has enabled the `rgb` dependency.
-### Command-line feature options
+## Command-line feature options
The following command-line flags can be used to control which features are
enabled:
@@ -246,7 +246,7 @@ enabled:
[workspace]: workspaces.md
-### Feature unification
+## Feature unification
Features are unique to the package that defines them. Enabling a feature on a
package does not enable a feature of the same name on other packages.
@@ -291,7 +291,7 @@ pub fn function_that_requires_std() {
[`no_std`]: ../../reference/names/preludes.html#the-no_std-attribute
[features section]: resolver.md#features
-#### Mutually exclusive features
+### Mutually exclusive features
There are rare cases where features may be mutually incompatible with one
another. This should be avoided if at all possible, because it requires
@@ -318,7 +318,7 @@ Instead of using mutually exclusive features, consider some other options:
[`cfg-if`]: https://crates.io/crates/cfg-if
[feature-precedence]: features-examples.md#feature-precedence
-#### Inspecting resolved features
+### Inspecting resolved features
In complex dependency graphs, it can sometimes be difficult to understand how
different features get enabled on various packages. The [`cargo tree`] command
@@ -338,7 +338,7 @@ enabled. Some options to try:
[`cargo tree`]: ../commands/cargo-tree.md
-### Feature resolver version 2
+## Feature resolver version 2
A different feature resolver can be specified with the `resolver` field in
`Cargo.toml`, like this:
@@ -386,7 +386,7 @@ the resolved features. For build dependencies, this is not necessary if you
are cross-compiling with the `--target` flag because build dependencies are
always built separately from normal dependencies in that scenario.
-#### Resolver version 2 command-line flags
+### Resolver version 2 command-line flags
The `resolver = "2"` setting also changes the behavior of the `--features` and
`--no-default-features` [command-line options](#command-line-feature-options).
@@ -419,7 +419,7 @@ version "2", it will disable the default features for all workspace members.
[dev-dependencies]: specifying-dependencies.md#development-dependencies
[resolver-v2]: resolver.md#feature-resolver-version-2
-### Build scripts
+## Build scripts
[Build scripts] can detect which features are enabled on the package by
inspecting the `CARGO_FEATURE_<name>` environment variable, where `<name>` is
@@ -427,7 +427,7 @@ the feature name converted to uppercase and `-` converted to `_`.
[build scripts]: build-scripts.md
-### Required features
+## Required features
The [`required-features` field] can be used to disable specific [Cargo
targets] if a feature is not enabled. See the linked documentation for more
@@ -436,7 +436,7 @@ details.
[`required-features` field]: cargo-targets.md#the-required-features-field
[Cargo targets]: cargo-targets.md
-### SemVer compatibility
+## SemVer compatibility
Enabling a feature should not introduce a SemVer-incompatible change. For
example, the feature shouldn't change an existing API in a way that could
@@ -466,7 +466,7 @@ See the links for caveats and examples.
[cargo-remove-opt-dep]: semver.md#cargo-remove-opt-dep
[cargo-feature-remove-another]: semver.md#cargo-feature-remove-another
-### Feature documentation and discovery
+## Feature documentation and discovery
You are encouraged to document which features are available in your package.
This can be done by adding [doc comments] at the top of `lib.rs`. As an
@@ -501,7 +501,7 @@ control which features are enabled when the documentation is built. See
[`doc_cfg`]: ../../unstable-book/language-features/doc-cfg.html
[`syn` documentation]: https://docs.rs/syn/1.0.54/syn/#modules
-#### Discovering features
+### Discovering features
When features are documented in the library API, this can make it easier for
your users to discover which features are available and what they do. If the
@@ -514,7 +514,7 @@ source and inspect it.
[`cargo vendor`]: ../commands/cargo-vendor.md
[cargo-clone-crate]: https://crates.io/crates/cargo-clone-crate
-### Feature combinations
+## Feature combinations
Because features are a form of conditional compilation, they require an exponential number of configurations and test cases to be 100% covered. By default, tests, docs, and other tooling such as [Clippy](https://github.com/rust-lang/rust-clippy) will only run with the default set of features.
diff --git a/src/tools/cargo/src/doc/src/reference/future-incompat-report.md b/src/tools/cargo/src/doc/src/reference/future-incompat-report.md
index b72f11757..ab394572f 100644
--- a/src/tools/cargo/src/doc/src/reference/future-incompat-report.md
+++ b/src/tools/cargo/src/doc/src/reference/future-incompat-report.md
@@ -1,4 +1,4 @@
-### Future incompat report
+# Future incompat report
Cargo checks for future-incompatible warnings in all dependencies. These are warnings for
changes that may become hard errors in the future, causing the dependency to
diff --git a/src/tools/cargo/src/doc/src/reference/index.md b/src/tools/cargo/src/doc/src/reference/index.md
index b931306c2..afff4fa89 100644
--- a/src/tools/cargo/src/doc/src/reference/index.md
+++ b/src/tools/cargo/src/doc/src/reference/index.md
@@ -1,4 +1,4 @@
-## Cargo Reference
+# Cargo Reference
The reference covers the details of various areas of Cargo.
diff --git a/src/tools/cargo/src/doc/src/reference/manifest.md b/src/tools/cargo/src/doc/src/reference/manifest.md
index 5f9d29ff6..5ecbe5117 100644
--- a/src/tools/cargo/src/doc/src/reference/manifest.md
+++ b/src/tools/cargo/src/doc/src/reference/manifest.md
@@ -1,4 +1,4 @@
-## The Manifest Format
+# The Manifest Format
The `Cargo.toml` file for each package is called its *manifest*. It is written
in the [TOML] format. It contains metadata that is needed to compile the package. Checkout
@@ -48,12 +48,13 @@ Every manifest file consists of the following sections:
* [`[target]`](specifying-dependencies.md#platform-specific-dependencies) --- Platform-specific dependencies.
* [`[badges]`](#the-badges-section) --- Badges to display on a registry.
* [`[features]`](features.md) --- Conditional compilation features.
+* [`[lints]`](#the-lints-section) --- Configure linters for this package.
* [`[patch]`](overriding-dependencies.md#the-patch-section) --- Override dependencies.
* [`[replace]`](overriding-dependencies.md#the-replace-section) --- Override dependencies (deprecated).
* [`[profile]`](profiles.md) --- Compiler settings and optimizations.
* [`[workspace]`](workspaces.md) --- The workspace definition.
-### The `[package]` section
+## The `[package]` section
The first section in a `Cargo.toml` is `[package]`.
@@ -69,7 +70,7 @@ The only fields required by Cargo are [`name`](#the-name-field) and
require additional fields. See the notes below and [the publishing
chapter][publishing] for requirements for publishing to [crates.io].
-#### The `name` field
+### The `name` field
The package name is an identifier used to refer to the package. It is used
when listed as a dependency in another package, and as the default name of
@@ -88,7 +89,7 @@ a keyword. [crates.io] imposes even more restrictions, such as:
[alphanumeric]: ../../std/primitive.char.html#method.is_alphanumeric
-#### The `version` field
+### The `version` field
Cargo bakes in the concept of [Semantic
Versioning](https://semver.org/), so make sure you follow some basic rules:
@@ -111,7 +112,7 @@ breaking change.
[Resolver]: resolver.md
[SemVer compatibility]: semver.md
-#### The `authors` field
+### The `authors` field
The optional `authors` field lists in an array the people or organizations that are considered
the "authors" of the package. The exact meaning is open to interpretation --- it
@@ -133,7 +134,7 @@ user interface.
> field cannot be changed or removed in already-published versions of a
> package.
-#### The `edition` field
+### The `edition` field
The `edition` key is an optional key that affects which [Rust Edition] your package
is compiled with. Setting the `edition` key in `[package]` will affect all
@@ -155,7 +156,7 @@ assumed for backwards compatibility. Note that all manifests
created with [`cargo new`] will not use this historical fallback because they
will have `edition` explicitly specified to a newer value.
-#### The `rust-version` field
+### The `rust-version` field
The `rust-version` field is an optional key that tells cargo what version of the
Rust language and compiler your package can be compiled with. If the currently
@@ -182,7 +183,7 @@ The `rust-version` may be ignored using the `--ignore-rust-version` option.
Setting the `rust-version` key in `[package]` will affect all targets/crates in
the package, including test suites, benchmarks, binaries, examples, etc.
-#### The `description` field
+### The `description` field
The description is a short blurb about the package. [crates.io] will display
this with your package. This should be plain text (not Markdown).
@@ -195,7 +196,7 @@ description = "A short description of my package"
> **Note**: [crates.io] requires the `description` to be set.
-#### The `documentation` field
+### The `documentation` field
The `documentation` field specifies a URL to a website hosting the crate's
documentation. If no URL is specified in the manifest file, [crates.io] will
@@ -210,7 +211,7 @@ documentation = "https://docs.rs/bitflags"
[docs.rs queue]: https://docs.rs/releases/queue
-#### The `readme` field
+### The `readme` field
The `readme` field should be the path to a file in the package root (relative
to this `Cargo.toml`) that contains general information about the package.
@@ -229,7 +230,7 @@ file will be used. You can suppress this behavior by setting this field to
`false`. If the field is set to `true`, a default value of `README.md` will
be assumed.
-#### The `homepage` field
+### The `homepage` field
The `homepage` field should be a URL to a site that is the home page for your
package.
@@ -240,7 +241,7 @@ package.
homepage = "https://serde.rs/"
```
-#### The `repository` field
+### The `repository` field
The `repository` field should be a URL to the source repository for your
package.
@@ -251,7 +252,7 @@ package.
repository = "https://github.com/rust-lang/cargo/"
```
-#### The `license` and `license-file` fields
+### The `license` and `license-file` fields
The `license` field contains the name of the software license that the package
is released under. The `license-file` field contains the path to a file
@@ -293,7 +294,7 @@ license-file = "LICENSE.txt"
[^slash]: Previously multiple licenses could be separated with a `/`, but that
usage is deprecated.
-#### The `keywords` field
+### The `keywords` field
The `keywords` field is an array of strings that describe this package. This
can help when searching for the package on a registry, and you may choose any
@@ -305,11 +306,11 @@ words that would help someone find this crate.
keywords = ["gamedev", "graphics"]
```
-> **Note**: [crates.io] has a maximum of 5 keywords. Each keyword must be
-> ASCII text, start with a letter, and only contain letters, numbers, `_` or
-> `-`, and have at most 20 characters.
+> **Note**: [crates.io] allows a maximum of 5 keywords. Each keyword must be
+> ASCII text, have at most 20 characters, start with an alphanumeric character,
+> and only contain letters, numbers, `_`, `-` or `+`.
-#### The `categories` field
+### The `categories` field
The `categories` field is an array of strings of the categories this package
belongs to.
@@ -322,7 +323,7 @@ categories = ["command-line-utilities", "development-tools::cargo-plugins"]
> match one of the strings available at <https://crates.io/category_slugs>, and
> must match exactly.
-#### The `workspace` field
+### The `workspace` field
The `workspace` field can be used to configure the workspace that this package
will be a member of. If not specified this will be inferred as the first
@@ -342,7 +343,7 @@ table defined. That is, a crate cannot both be a root crate in a workspace
For more information, see the [workspaces chapter](workspaces.md).
-#### The `build` field
+### The `build` field
The `build` field specifies a file in the package root which is a [build
script] for building native code. More information can be found in the [build
@@ -361,7 +362,7 @@ The default is `"build.rs"`, which loads the script from a file named
specify a path to a different file or `build = false` to disable automatic
detection of the build script.
-#### The `links` field
+### The `links` field
The `links` field specifies the name of a native library that is being linked
to. More information can be found in the [`links`][links] section of the build
@@ -378,7 +379,7 @@ on Linux) may specify:
links = "git2"
```
-#### The `exclude` and `include` fields
+### The `exclude` and `include` fields
The `exclude` and `include` fields can be used to explicitly specify which
files are included when packaging a project to be [published][publishing],
@@ -467,7 +468,7 @@ if any of those files change.
[gitignore]: https://git-scm.com/docs/gitignore
-#### The `publish` field
+### The `publish` field
The `publish` field can be used to prevent a package from being published to a
package registry (like *crates.io*) by mistake, for instance to keep a package
@@ -491,7 +492,7 @@ publish = ["some-registry-name"]
If publish array contains a single registry, `cargo publish` command will use
it when `--registry` flag is not specified.
-#### The `metadata` table
+### The `metadata` table
Cargo by default will warn about unused keys in `Cargo.toml` to assist in
detecting typos and such. The `package.metadata` table, however, is completely
@@ -519,7 +520,7 @@ if that makes sense for the tool in question.
[workspace-metadata]: workspaces.md#the-metadata-table
-#### The `default-run` field
+### The `default-run` field
The `default-run` field in the `[package]` section of the manifest can be used
to specify a default binary picked by [`cargo run`]. For example, when there is
@@ -530,7 +531,47 @@ both `src/bin/a.rs` and `src/bin/b.rs`:
default-run = "a"
```
-### The `[badges]` section
+#### The `lints` section
+
+Override the default level of lints from different tools by assigning them to a new level in a
+table, for example:
+```toml
+[lints.rust]
+unsafe_code = "forbid"
+```
+
+This is short-hand for:
+```toml
+[lints.rust]
+unsafe_code = { level = "forbid", priority = 0 }
+```
+
+`level` corresponds to the lint levels in `rustc`:
+- `forbid`
+- `deny`
+- `warn`
+- `allow`
+
+`priority` is a signed integer that controls which lints or lint groups override other lint groups:
+- lower (particularly negative) numbers have lower priority, being overridden
+ by higher numbers, and show up first on the command-line to tools like
+ `rustc`
+
+To know which table under `[lints]` a particular lint belongs under, it is the part before `::` in the lint
+name. If there isn't a `::`, then the tool is `rust`. For example a warning
+about `unsafe_code` would be `lints.rust.unsafe_code` but a lint about
+`clippy::enum_glob_use` would be `lints.clippy.enum_glob_use`.
+
+For example:
+```toml
+[lints.rust]
+unsafe_code = "forbid"
+
+[lints.clippy]
+enum_glob_use = "deny"
+```
+
+## The `[badges]` section
The `[badges]` section is for specifying status badges that can be displayed
on a registry website when the package is published.
@@ -565,13 +606,13 @@ on a registry website when the package is published.
maintenance = { status = "..." }
```
-### Dependency sections
+## Dependency sections
See the [specifying dependencies page](specifying-dependencies.md) for
information on the `[dependencies]`, `[dev-dependencies]`,
`[build-dependencies]`, and target-specific `[target.*.dependencies]` sections.
-### The `[profile.*]` sections
+## The `[profile.*]` sections
The `[profile]` tables provide a way to customize compiler settings such as
optimizations and debug settings. See [the Profiles chapter](profiles.md) for
diff --git a/src/tools/cargo/src/doc/src/reference/overriding-dependencies.md b/src/tools/cargo/src/doc/src/reference/overriding-dependencies.md
index c04a7929d..6d80df198 100644
--- a/src/tools/cargo/src/doc/src/reference/overriding-dependencies.md
+++ b/src/tools/cargo/src/doc/src/reference/overriding-dependencies.md
@@ -1,4 +1,4 @@
-## Overriding Dependencies
+# Overriding Dependencies
The desire to override a dependency can arise through a number of scenarios.
Most of them, however, boil down to the ability to work with a crate before
@@ -37,7 +37,7 @@ on the different ways to override a dependency.
> can be used to override the source for a single dependency declaration in a
> local package.
-### Testing a bugfix
+## Testing a bugfix
Let's say you're working with the [`uuid` crate] but while you're working on it
you discover a bug. You are, however, quite enterprising so you decide to also
@@ -97,7 +97,7 @@ $ cargo build
And that's it! You're now building with the local version of `uuid` (note the
path in parentheses in the build output). If you don't see the local path version getting
-built then you may need to run `cargo update -p uuid --precise $version` where
+built then you may need to run `cargo update uuid --precise $version` where
`$version` is the version of the locally checked out copy of `uuid`.
Once you've fixed the bug you originally found the next thing you'll want to do
@@ -113,7 +113,7 @@ uuid = { git = 'https://github.com/uuid-rs/uuid.git' }
[uuid-repository]: https://github.com/uuid-rs/uuid
-### Working with an unpublished minor version
+## Working with an unpublished minor version
Let's now shift gears a bit from bug fixes to adding features. While working on
`my-library` you discover that a whole new feature is needed in the `uuid`
@@ -171,7 +171,7 @@ if necessary. Here, though, the new `uuid` crate applies to *both* our dependenc
one version for this entire crate graph, 1.0.1, and it'll be pulled from the git
repository.
-#### Overriding repository URL
+### Overriding repository URL
In case the dependency you want to override isn't loaded from `crates.io`,
you'll have to change a bit how you use `[patch]`. For example, if the
@@ -184,7 +184,7 @@ my-library = { path = "../my-library/path" }
And that's it!
-### Prepublishing a breaking change
+## Prepublishing a breaking change
Let's take a look at working with a new major version of a crate, typically
accompanied with breaking changes. Sticking with our previous crates, this
@@ -224,7 +224,7 @@ the `my-library` crate will use the `2.0.0` version of `uuid`. This will allow y
to gradually roll out breaking changes to a crate through a dependency graph
without being forced to update everything all at once.
-### Using `[patch]` with multiple versions
+## Using `[patch]` with multiple versions
You can patch in multiple versions of the same crate with the `package` key
used to rename dependencies. For example let's say that the `serde` crate has
@@ -248,7 +248,7 @@ Note that when using the `package` key the `serde2` identifier here is actually
ignored. We simply need a unique name which doesn't conflict with other patched
crates.
-### The `[patch]` section
+## The `[patch]` section
The `[patch]` section of `Cargo.toml` can be used to override dependencies
with other copies. The syntax is similar to the
@@ -295,7 +295,7 @@ Cargo only looks at the patch settings in the `Cargo.toml` manifest at the
root of the workspace. Patch settings defined in dependencies will be
ignored.
-### The `[replace]` section
+## The `[replace]` section
> **Note**: `[replace]` is deprecated. You should use the
> [`[patch]`](#the-patch-section) table instead.
@@ -321,7 +321,7 @@ Cargo only looks at the replace settings in the `Cargo.toml` manifest at the
root of the workspace. Replace settings defined in dependencies will be
ignored.
-### `paths` overrides
+## `paths` overrides
Sometimes you're only temporarily working on a crate and you don't want to have
to modify `Cargo.toml` like with the `[patch]` section above. For this use
diff --git a/src/tools/cargo/src/doc/src/reference/pkgid-spec.md b/src/tools/cargo/src/doc/src/reference/pkgid-spec.md
index 6c11b4b3d..7f20973b5 100644
--- a/src/tools/cargo/src/doc/src/reference/pkgid-spec.md
+++ b/src/tools/cargo/src/doc/src/reference/pkgid-spec.md
@@ -1,6 +1,6 @@
-## Package ID Specifications
+# Package ID Specifications
-### Package ID specifications
+## Package ID specifications
Subcommands of Cargo frequently need to refer to a particular package within a
dependency graph for various operations like updating, cleaning, building, etc.
@@ -16,7 +16,7 @@ ambiguity, additional qualifiers can be added to make it unique. For example,
if there are two versions of the `regex` package in the graph, then it can be
qualified with a version to make it unique, such as `regex@1.4.3`.
-#### Specification grammar
+### Specification grammar
The formal grammar for a Package Id Specification is:
@@ -24,6 +24,7 @@ The formal grammar for a Package Id Specification is:
spec := pkgname
| proto "://" hostname-and-path [ "#" ( pkgname | semver ) ]
pkgname := name [ ("@" | ":" ) semver ]
+semver := digits [ "." digits [ "." digits [ "-" prerelease ] [ "+" build ]]]
proto := "http" | "git" | ...
```
@@ -33,13 +34,14 @@ Here, brackets indicate that the contents are optional.
The URL form can be used for git dependencies, or to differentiate packages
that come from different sources such as different registries.
-#### Example specifications
+### Example specifications
The following are references to the `regex` package on `crates.io`:
| Spec | Name | Version |
|:------------------------------------------------------------|:-------:|:-------:|
| `regex` | `regex` | `*` |
+| `regex@1.4` | `regex` | `1.4.*` |
| `regex@1.4.3` | `regex` | `1.4.3` |
| `https://github.com/rust-lang/crates.io-index#regex` | `regex` | `*` |
| `https://github.com/rust-lang/crates.io-index#regex@1.4.3` | `regex` | `1.4.3` |
@@ -59,7 +61,7 @@ Local packages on the filesystem can use `file://` URLs to reference them:
| `file:///path/to/my/project/foo` | `foo` | `*` |
| `file:///path/to/my/project/foo#1.1.8` | `foo` | `1.1.8` |
-#### Brevity of specifications
+### Brevity of specifications
The goal of this is to enable both succinct and exhaustive syntaxes for
referring to packages in a dependency graph. Ambiguous references may refer to
diff --git a/src/tools/cargo/src/doc/src/reference/profiles.md b/src/tools/cargo/src/doc/src/reference/profiles.md
index c094aa815..15ca8953c 100644
--- a/src/tools/cargo/src/doc/src/reference/profiles.md
+++ b/src/tools/cargo/src/doc/src/reference/profiles.md
@@ -1,4 +1,4 @@
-## Profiles
+# Profiles
Profiles provide a way to alter the compiler settings, influencing things like
optimizations and debugging symbols.
@@ -28,11 +28,11 @@ the settings from `Cargo.toml`.
[config]: config.md
-### Profile settings
+## Profile settings
The following is a list of settings that can be controlled in a profile.
-#### opt-level
+### opt-level
The `opt-level` setting controls the [`-C opt-level` flag] which controls the level
of optimization. Higher optimization levels may produce faster runtime code at
@@ -60,7 +60,7 @@ techniques.
[`-C opt-level` flag]: ../../rustc/codegen-options/index.html#opt-level
[Profile Guided Optimization]: ../../rustc/profile-guided-optimization.html
-#### debug
+### debug
The `debug` setting controls the [`-C debuginfo` flag] which controls the
amount of debug information included in the compiled binary.
@@ -82,7 +82,7 @@ depending on your needs as well.
[debuginfo]: ../../rustc/codegen-options/index.html#debuginfo
[profiling]: https://reviews.llvm.org/D46061
-#### split-debuginfo
+### split-debuginfo
The `split-debuginfo` setting controls the [`-C split-debuginfo` flag] which
controls whether debug information, if generated, is either placed in the
@@ -96,10 +96,14 @@ split-debuginfo` flag] and is platform-specific. Some options are only
available on the [nightly channel]. The Cargo default may change in the future
once more testing has been performed, and support for DWARF is stabilized.
+Be aware that Cargo and rustc have different defaults for this option. This
+option exists to allow Cargo to experiment on different combinations of flags
+thus providing better debugging and developer experience.
+
[nightly channel]: ../../book/appendix-07-nightly-rust.html
[`-C split-debuginfo` flag]: ../../rustc/codegen-options/index.html#split-debuginfo
-#### strip
+### strip
The `strip` option controls the [`-C strip` flag], which directs rustc to
strip either symbols or debuginfo from a binary. This can be enabled like so:
@@ -121,7 +125,7 @@ equivalent to `strip = "none"` and disables `strip` completely.
[`-C strip` flag]: ../../rustc/codegen-options/index.html#strip
-#### debug-assertions
+### debug-assertions
The `debug-assertions` setting controls the [`-C debug-assertions` flag] which
turns `cfg(debug_assertions)` [conditional compilation] on or off. Debug
@@ -139,7 +143,7 @@ The valid options are:
[conditional compilation]: ../../reference/conditional-compilation.md#debug_assertions
[`debug_assert!` macro]: ../../std/macro.debug_assert.html
-#### overflow-checks
+### overflow-checks
The `overflow-checks` setting controls the [`-C overflow-checks` flag] which
controls the behavior of [runtime integer overflow]. When overflow-checks are
@@ -153,7 +157,7 @@ The valid options are:
[`-C overflow-checks` flag]: ../../rustc/codegen-options/index.html#overflow-checks
[runtime integer overflow]: ../../reference/expressions/operator-expr.md#overflow
-#### lto
+### lto
The `lto` setting controls `rustc`'s [`-C lto`], [`-C linker-plugin-lto`], and
[`-C embed-bitcode`] options, which control LLVM's [link time optimizations].
@@ -183,7 +187,7 @@ This is not yet supported natively in Cargo, but can be performed via
[linker-plugin-lto chapter]: ../../rustc/linker-plugin-lto.html
["thin" LTO]: http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html
-#### panic
+### panic
The `panic` setting controls the [`-C panic` flag] which controls which panic
strategy to use.
@@ -207,7 +211,7 @@ dependencies will also be forced to build with the `unwind` strategy.
[`-C panic` flag]: ../../rustc/codegen-options/index.html#panic
[`panic-abort-tests`]: unstable.md#panic-abort-tests
-#### incremental
+### incremental
The `incremental` setting controls the [`-C incremental` flag] which controls
whether or not incremental compilation is enabled. Incremental compilation
@@ -230,7 +234,7 @@ The incremental value can be overridden globally with the `CARGO_INCREMENTAL`
[environment variable]: environment-variables.md
[`build.incremental`]: config.md#buildincremental
-#### codegen-units
+### codegen-units
The `codegen-units` setting controls the [`-C codegen-units` flag] which
controls how many "code generation units" a crate will be split into. More
@@ -244,7 +248,7 @@ non-incremental builds.
[`-C codegen-units` flag]: ../../rustc/codegen-options/index.html#codegen-units
-#### rpath
+### rpath
The `rpath` setting controls the [`-C rpath` flag] which controls
whether or not [`rpath`] is enabled.
@@ -252,9 +256,9 @@ whether or not [`rpath`] is enabled.
[`-C rpath` flag]: ../../rustc/codegen-options/index.html#rpath
[`rpath`]: https://en.wikipedia.org/wiki/Rpath
-### Default profiles
+## Default profiles
-#### dev
+### dev
The `dev` profile is used for normal development and debugging. It is the
default for build commands like [`cargo build`], and is used for `cargo install --debug`.
@@ -266,6 +270,7 @@ The default settings for the `dev` profile are:
opt-level = 0
debug = true
split-debuginfo = '...' # Platform-specific.
+strip = false
debug-assertions = true
overflow-checks = true
lto = false
@@ -275,7 +280,7 @@ codegen-units = 256
rpath = false
```
-#### release
+### release
The `release` profile is intended for optimized artifacts used for releases
and in production. This profile is used when the `--release` flag is used, and
@@ -288,6 +293,7 @@ The default settings for the `release` profile are:
opt-level = 3
debug = false
split-debuginfo = '...' # Platform-specific.
+strip = false
debug-assertions = false
overflow-checks = false
lto = false
@@ -297,17 +303,17 @@ codegen-units = 16
rpath = false
```
-#### test
+### test
The `test` profile is the default profile used by [`cargo test`].
The `test` profile inherits the settings from the [`dev`](#dev) profile.
-#### bench
+### bench
The `bench` profile is the default profile used by [`cargo bench`].
The `bench` profile inherits the settings from the [`release`](#release) profile.
-#### Build Dependencies
+### Build Dependencies
To compile quickly, all profiles, by default, do not optimize build
dependencies (build scripts, proc macros, and their dependencies), and avoid
@@ -335,7 +341,7 @@ debug = true
Build dependencies otherwise inherit settings from the active profile in use, as
described in [Profile selection](#profile-selection).
-### Custom profiles
+## Custom profiles
In addition to the built-in profiles, additional custom profiles can be
defined. These may be useful for setting up multiple workflows and build
@@ -365,7 +371,7 @@ output would go into the `target/release-lto` directory.
[`target` directory]: ../guide/build-cache.md
-### Profile selection
+## Profile selection
The profile used depends on the command, the command-line flags like
`--release` or `--profile`, and the package (in the case of
@@ -399,7 +405,7 @@ The profile for specific packages can be specified with
[`cargo rustc`]: ../commands/cargo-rustc.md
[`cargo test`]: ../commands/cargo-test.md
-### Overrides
+## Overrides
Profile settings can be overridden for specific packages and build-time
crates. To override the settings for a specific package, use the `package`
@@ -451,7 +457,7 @@ match wins):
Overrides cannot specify the `panic`, `lto`, or `rpath` settings.
-#### Overrides and generics
+### Overrides and generics
The location where generic code is instantiated will influence the
optimization settings used for that generic code. This can cause subtle
diff --git a/src/tools/cargo/src/doc/src/reference/publishing.md b/src/tools/cargo/src/doc/src/reference/publishing.md
index 564dfb34e..54a8635fb 100644
--- a/src/tools/cargo/src/doc/src/reference/publishing.md
+++ b/src/tools/cargo/src/doc/src/reference/publishing.md
@@ -1,4 +1,4 @@
-## Publishing on crates.io
+# Publishing on crates.io
Once you've got a library that you'd like to share with the world, it's time to
publish it on [crates.io]! Publishing a crate is when a specific
@@ -8,7 +8,7 @@ Take care when publishing a crate, because a publish is **permanent**. The
version can never be overwritten, and the code cannot be deleted. There is no
limit to the number of versions which can be published, however.
-### Before your first publish
+## Before your first publish
First things first, you’ll need an account on [crates.io] to acquire
an API token. To do so, [visit the home page][crates.io] and log in via a GitHub
@@ -38,7 +38,7 @@ immediately.
> `credentials.toml`. This can be useful if you no longer need it stored on
> the local machine.
-### Before publishing a new crate
+## Before publishing a new crate
Keep in mind that crate names on [crates.io] are allocated on a first-come-first-serve
basis. Once a crate name is taken, it cannot be used for another crate.
@@ -60,7 +60,7 @@ though they are not required.
If you are publishing a library, you may also want to consult the [Rust API
Guidelines].
-#### Packaging a crate
+### Packaging a crate
The next step is to package up your crate and upload it to [crates.io]. For
this we’ll use the [`cargo publish`] subcommand. This command performs the following
@@ -119,7 +119,7 @@ include = [
]
```
-### Uploading the crate
+## Uploading the crate
When you are ready to publish, use the [`cargo publish`] command
to upload to [crates.io]:
@@ -130,19 +130,32 @@ $ cargo publish
And that’s it, you’ve now published your first crate!
-### Publishing a new version of an existing crate
+## Publishing a new version of an existing crate
In order to release a new version, change [the `version` value](manifest.md#the-version-field) specified in your `Cargo.toml` manifest.
Keep in mind [the SemVer rules](semver.md) which provide guidelines on what is a compatible change.
Then run [`cargo publish`] as described above to upload the new version.
-### Managing a crates.io-based crate
+> **Recommendation:** Consider the full release process and automate what you can.
+>
+> Each version should include:
+> - A changelog entry, preferrably [manually curated](https://keepachangelog.com/en/1.0.0/) though a generated one is better than nothing
+> - A [git tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) pointing to the published commit
+>
+> Examples of third-party tools that are representative of different workflows include (in alphabetical order):
+> - [cargo-release](https://crates.io/crates/cargo-release)
+> - [cargo-smart-release](https://crates.io/crates/cargo-smart-release)
+> - [release-plz](https://crates.io/crates/release-plz)
+>
+> For more, see [crates.io](https://crates.io/search?q=cargo%20release).
+
+## Managing a crates.io-based crate
Management of crates is primarily done through the command line `cargo` tool
rather than the [crates.io] web interface. For this, there are a few subcommands
to manage a crate.
-#### `cargo yank`
+### `cargo yank`
Occasions may arise where you publish a version of a crate that actually ends up
being broken for one reason or another (syntax error, forgot to include a file,
@@ -166,7 +179,7 @@ goal. Essentially a yank means that all packages with a `Cargo.lock` will not
break, while any future `Cargo.lock` files generated will not list the yanked
version.
-#### `cargo owner`
+### `cargo owner`
A crate is often developed by more than one person, or the primary maintainer
may change over time! The owner of a crate is the only person allowed to publish
@@ -198,7 +211,7 @@ The syntax for teams is currently `github:org:team` (see examples above).
In order to invite a team as an owner one must be a member of that team. No
such restriction applies to removing a team as an owner.
-### GitHub permissions
+## GitHub permissions
Team membership is not something GitHub provides simple public access to, and it
is likely for you to encounter the following message when working with them:
@@ -250,7 +263,7 @@ the “Grant Access” button next to its name:
![Authentication Access Control](../images/auth-level-acl.png)
-#### Troubleshooting GitHub team access errors
+### Troubleshooting GitHub team access errors
When trying to add a GitHub team as crate owner, you may see an error like:
diff --git a/src/tools/cargo/src/doc/src/reference/registries.md b/src/tools/cargo/src/doc/src/reference/registries.md
index 7714a36cd..f0554be98 100644
--- a/src/tools/cargo/src/doc/src/reference/registries.md
+++ b/src/tools/cargo/src/doc/src/reference/registries.md
@@ -1,4 +1,4 @@
-## Registries
+# Registries
Cargo installs crates and fetches dependencies from a "registry". The default
registry is [crates.io]. A registry contains an "index" which contains a
@@ -11,7 +11,11 @@ support publishing new crates directly from Cargo.
If you are implementing a registry server, see [Running a Registry] for more
details about the protocol between Cargo and a registry.
-### Using an Alternate Registry
+If you're using a registry that requires authentication, see [Registry Authentication].
+If you are implementing a credential provider, see [Credential Provider Protocol]
+for details.
+
+## Using an Alternate Registry
To use a registry other than [crates.io], the name and index URL of the
registry must be added to a [`.cargo/config.toml` file][config]. The `registries`
@@ -51,7 +55,7 @@ CARGO_REGISTRIES_MY_REGISTRY_INDEX=https://my-intranet:8080/git/index
> Note: [crates.io] does not accept packages that depend on crates from other
> registries.
-### Publishing to an Alternate Registry
+## Publishing to an Alternate Registry
If the registry supports web API access, then packages can be published
directly to the registry from Cargo. Several of Cargo's commands such as
@@ -100,7 +104,7 @@ has a separate table for each registry, for example:
token = "854DvwSlUwEHtIo3kWy6x7UCPKHfzCmy"
```
-### Registry Protocols
+## Registry Protocols
Cargo supports two remote registry protocols: `git` and `sparse`. If the registry
index URL starts with `sparse+`, Cargo uses the sparse protocol. Otherwise
Cargo uses the `git` protocol.
@@ -117,6 +121,8 @@ controlled via the [`registries.crates-io.protocol`] config key.
[Source Replacement]: source-replacement.md
[Running a Registry]: running-a-registry.md
+[Credential Provider Protocol]: credential-provider-protocol.md
+[Registry Authentication]: registry-authentication.md
[`cargo publish`]: ../commands/cargo-publish.md
[`cargo package`]: ../commands/cargo-package.md
[`cargo login`]: ../commands/cargo-login.md
diff --git a/src/tools/cargo/src/doc/src/reference/registry-authentication.md b/src/tools/cargo/src/doc/src/reference/registry-authentication.md
new file mode 100644
index 000000000..9f8f7e979
--- /dev/null
+++ b/src/tools/cargo/src/doc/src/reference/registry-authentication.md
@@ -0,0 +1,111 @@
+# Registry Authentication
+Cargo authenticates to registries with credential providers. These
+credential providers are external executables or built-in providers that Cargo
+uses to store and retrieve credentials.
+
+Using alternative registries with authentication *requires* a credential provider to be configured
+to avoid unknowingly storing unencrypted credentials on disk. For historical reasons, public
+(non-authenticated) registries do not require credential provider configuration, and the `cargo:token`
+provider is used if no providers are configured.
+
+Cargo also includes platform-specific providers that use the operating system to securely store
+tokens. The `cargo:token` provider is also included which stores credentials in unencrypted plain
+text in the [credentials](config.md#credentials) file.
+
+## Recommended configuration
+It's recommended to configure a global credential provider list in `$CARGO_HOME/config.toml`
+which defaults to:
+* Windows: `%USERPROFILE%\.cargo\config.toml`
+* Unix: `~/.cargo/config.toml`
+
+This recommended configuration uses the operating system provider, with a fallback to `cargo:token`
+to look in Cargo's [credentials](config.md#credentials) file or environment variables.
+
+Some private registries may also recommend a registry-specific credential-provider. Check your
+registry's documentation to see if this is the case.
+
+### macOS configuration
+```toml
+# ~/.cargo/config.toml
+[registry]
+global-credential-providers = ["cargo:token", "cargo:macos-keychain"]
+```
+
+### Linux (libsecret) configuration
+```toml
+# ~/.cargo/config.toml
+[registry]
+global-credential-providers = ["cargo:token", "cargo:libsecret"]
+```
+
+### Windows configuration
+```toml
+# %USERPROFILE%\.cargo\config.toml
+[registry]
+global-credential-providers = ["cargo:token", "cargo:wincred"]
+```
+
+See [`registry.global-credential-providers`](config.md#registryglobal-credential-providers)
+for more details.
+
+## Built-in providers
+Cargo includes several built-in credential providers. The available built-in providers
+may change in future Cargo releases (though there are currently no plans to do so).
+
+### `cargo:token`
+Uses Cargo's [credentials](config.md#credentials) file to store tokens unencrypted in plain text.
+When retrieving tokens, checks the `CARGO_REGISTRIES_<NAME>_TOKEN` environment variable.
+If this credential provider is not listed, then the `*_TOKEN` environment variables will not work.
+
+### `cargo:wincred`
+Uses the Windows Credential Manager to store tokens.
+
+The credentials are stored as `cargo-registry:<index-url>` in the Credential Manager
+under "Windows Credentials".
+
+### `cargo:macos-keychain`
+Uses the macOS Keychain to store tokens.
+
+The Keychain Access app can be used to view stored tokens.
+
+### `cargo:libsecret`
+Uses [libsecret](https://wiki.gnome.org/Projects/Libsecret) to store tokens.
+
+On GNOME, credentials can be viewed using [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring)
+applications.
+
+### `cargo:token-from-stdout <command> <args>`
+Launch a subprocess that returns a token on stdout. Newlines will be trimmed.
+* The process inherits the user's stdin and stderr.
+* It should exit 0 on success, and nonzero on error.
+* [`cargo login`] and [`cargo logout`] are not supported and return an error if used.
+
+The following environment variables will be provided to the executed command:
+
+* `CARGO` --- Path to the `cargo` binary executing the command.
+* `CARGO_REGISTRY_INDEX_URL` --- The URL of the registry index.
+* `CARGO_REGISTRY_NAME_OPT` --- Optional name of the registry. Should not be used as a lookup key.
+
+Arguments will be passed on to the subcommand.
+
+[`cargo login`]: ../commands/cargo-login.md
+[`cargo logout`]: ../commands/cargo-logout.md
+
+## Credential plugins
+For credential provider plugins that follow Cargo's [credential provider protocol](credential-provider-protocol.md),
+the configuration value should be a string with the path to the executable (or the executable name if on the `PATH`).
+
+For example, to install [cargo-credential-1password](https://crates.io/crates/cargo-credential-1password)
+from crates.io do the following:
+
+Install the provider with `cargo install cargo-credential-1password`
+
+In the config, add to (or create) `registry.global-credential-providers`:
+```toml
+[registry]
+global-credential-providers = ["cargo:token", "cargo-credential-1password --email you@example.com"]
+```
+
+The values in `global-credential-providers` are split on spaces into path and command-line arguments. To
+define a global credential provider where the path or arguments contain spaces, use
+the [`[credential-alias]` table](config.md#credential-alias).
diff --git a/src/tools/cargo/src/doc/src/reference/registry-index.md b/src/tools/cargo/src/doc/src/reference/registry-index.md
index 3eed6ef39..67af8d3cd 100644
--- a/src/tools/cargo/src/doc/src/reference/registry-index.md
+++ b/src/tools/cargo/src/doc/src/reference/registry-index.md
@@ -1,4 +1,4 @@
-## Index Format
+# Index Format
The following defines the format of the index. New features are occasionally
added, which are only understood starting with the version of Cargo that
@@ -6,7 +6,7 @@ introduced them. Older versions of Cargo may not be able to use packages that
make use of new features. However, the format for older packages should not
change, so older versions of Cargo should be able to use them.
-### Index Configuration
+## Index Configuration
The root of the index contains a file named `config.json` which contains JSON
information used by Cargo for accessing the registry. This is an example of
what the [crates.io] config file looks like:
@@ -35,16 +35,21 @@ The keys are:
- `api`: This is the base URL for the web API. This key is optional, but if it
is not specified, commands such as [`cargo publish`] will not work. The web
API is described below.
+- `auth-required`: indicates whether this is a private registry that requires
+ all operations to be authenticated including API requests, crate downloads
+ and sparse index updates.
-### Download Endpoint
+## Download Endpoint
The download endpoint should send the `.crate` file for the requested package.
Cargo supports https, http, and file URLs, HTTP redirects, HTTP1 and HTTP2.
The exact specifics of TLS support depend on the platform that Cargo is
running on, the version of Cargo, and how it was compiled.
+If `auth-required: true` is set in `config.json`, the `Authorization` header
+will be included with http(s) download requests.
-### Index files
+## Index files
The rest of the index repository contains one file for each package, where the
filename is the name of the package in lowercase. Each version of the package
has a separate line in the file. The files are organized in a tier of
@@ -80,7 +85,7 @@ harder to support older versions of Cargo that lack `{prefix}`/`{lowerprefix}`.
For example, nginx rewrite rules can easily construct `{prefix}` but can't
perform case-conversion to construct `{lowerprefix}`.
-### Name restrictions
+## Name restrictions
Registries should consider enforcing limitations on package names added to
their index. Cargo itself allows names with any [alphanumeric], `-`, or `_`
@@ -100,13 +105,13 @@ attacks](https://en.wikipedia.org/wiki/IDN_homograph_attack) and other
concerns in [UTR36](https://www.unicode.org/reports/tr36/) and
[UTS39](https://www.unicode.org/reports/tr39/).
-### Version uniqueness
+## Version uniqueness
Indexes *must* ensure that each version only appears once for each package.
This includes ignoring SemVer build metadata.
For example, the index must *not* contain two entries with a version `1.0.7` and `1.0.7+extra`.
-### JSON schema
+## JSON schema
Each line in a package file contains a JSON object that describes a published
version of the package. The following is a pretty-printed example with comments
@@ -254,19 +259,19 @@ The JSON objects should not be modified after they are added except for the
[Publish API]: registry-web-api.md#publish
[`cargo metadata`]: ../commands/cargo-metadata.md
-### Index Protocols
+## Index Protocols
Cargo supports two remote registry protocols: `git` and `sparse`. The `git` protocol
stores index files in a git repository and the `sparse` protocol fetches individual
files over HTTP.
-#### Git Protocol
+### Git Protocol
The git protocol has no protocol prefix in the index url. For example the git index URL
for [crates.io] is `https://github.com/rust-lang/crates.io-index`.
Cargo caches the git repository on disk so that it can efficiently incrementally fetch
updates.
-#### Sparse Protocol
+### Sparse Protocol
The sparse protocol uses the `sparse+` protocol prefix in the registry URL. For example,
the sparse index URL for [crates.io] is `sparse+https://index.crates.io/`.
@@ -274,24 +279,36 @@ The sparse protocol downloads each index file using an individual HTTP request.
this results in a large number of small HTTP requests, performance is significantly
improved with a server that supports pipelining and HTTP/2.
-##### Caching
+#### Sparse authentication
+Cargo will attempt to fetch the `config.json` file before
+fetching any other files. If the server responds with an HTTP 401, then Cargo will assume
+that the registry requires authentication and re-attempt the request for `config.json`
+with the authentication token included.
+
+On authentication failure (or a missing authentication token) the server may include a
+`www-authenticate` header with a `Cargo login_url="<URL>"` challenge to indicate where the user
+can go to get a token.
+
+Registries that require authentication must set `auth-required: true` in `config.json`.
+
+#### Caching
Cargo caches the crate metadata files, and captures the `ETag` or `Last-Modified`
HTTP header from the server for each entry. When refreshing crate metadata, Cargo
sends the `If-None-Match` or `If-Modified-Since` header to allow the server to respond
with HTTP 304 "Not Modified" if the local cache is valid, saving time and bandwidth.
If both `ETag` and `Last-Modified` headers are present, Cargo uses the `ETag` only.
-##### Cache Invalidation
+#### Cache Invalidation
If a registry is using some kind of CDN or proxy which caches access to the index files,
then it is recommended that registries implement some form of cache invalidation when
the files are updated. If these caches are not updated, then users may not be able to
access new crates until the cache is cleared.
-##### Nonexistent Crates
+#### Nonexistent Crates
For crates that do not exist, the registry should respond with a 404 "Not Found", 410 "Gone"
or 451 "Unavailable For Legal Reasons" code.
-##### Sparse Limitations
+#### Sparse Limitations
Since the URL of the registry is stored in the lockfile, it's not recommended to offer
a registry with both protocols. Discussion about a transition plan is ongoing in issue
[#10964]. The [crates.io] registry is an exception, since Cargo internally substitutes
diff --git a/src/tools/cargo/src/doc/src/reference/registry-web-api.md b/src/tools/cargo/src/doc/src/reference/registry-web-api.md
index 8260028c0..7b0f3511b 100644
--- a/src/tools/cargo/src/doc/src/reference/registry-web-api.md
+++ b/src/tools/cargo/src/doc/src/reference/registry-web-api.md
@@ -1,5 +1,4 @@
-
-## Web API
+# Web API
A registry may host a web API at the location defined in `config.json` to
support any of the actions listed below.
@@ -47,7 +46,7 @@ Cargo sets the following headers for all requests:
2019-01-02)`. This may be modified by the user in a configuration value.
Added in 1.29.
-### Publish
+## Publish
- Endpoint: `/api/v1/crates/new`
- Method: PUT
@@ -184,7 +183,7 @@ A successful response includes the JSON object:
}
```
-### Yank
+## Yank
- Endpoint: `/api/v1/crates/{crate_name}/{version}/yank`
- Method: DELETE
@@ -197,12 +196,12 @@ A successful response includes the JSON object:
```javascript
{
- // Indicates the delete succeeded, always true.
+ // Indicates the yank succeeded, always true.
"ok": true,
}
```
-### Unyank
+## Unyank
- Endpoint: `/api/v1/crates/{crate_name}/{version}/unyank`
- Method: PUT
@@ -215,12 +214,12 @@ A successful response includes the JSON object:
```javascript
{
- // Indicates the delete succeeded, always true.
+ // Indicates the unyank succeeded, always true.
"ok": true,
}
```
-### Owners
+## Owners
Cargo does not have an inherent notion of users and owners, but it does
provide the `owner` command to assist managing who has authorization to
@@ -228,7 +227,7 @@ control a crate. It is up to the registry to decide exactly how users and
owners are handled. See the [publishing documentation] for a description of
how [crates.io] handles owners via GitHub users and teams.
-#### Owners: List
+### Owners: List
- Endpoint: `/api/v1/crates/{crate_name}/owners`
- Method: GET
@@ -255,7 +254,7 @@ A successful response includes the JSON object:
}
```
-#### Owners: Add
+### Owners: Add
- Endpoint: `/api/v1/crates/{crate_name}/owners`
- Method: PUT
@@ -286,7 +285,7 @@ A successful response includes the JSON object:
}
```
-#### Owners: Remove
+### Owners: Remove
- Endpoint: `/api/v1/crates/{crate_name}/owners`
- Method: DELETE
@@ -313,7 +312,7 @@ A successful response includes the JSON object:
}
```
-### Search
+## Search
- Endpoint: `/api/v1/crates`
- Method: GET
@@ -346,7 +345,7 @@ A successful response includes the JSON object:
}
```
-### Login
+## Login
- Endpoint: `/me`
diff --git a/src/tools/cargo/src/doc/src/reference/resolver.md b/src/tools/cargo/src/doc/src/reference/resolver.md
index ffb194c5e..7d01fb167 100644
--- a/src/tools/cargo/src/doc/src/reference/resolver.md
+++ b/src/tools/cargo/src/doc/src/reference/resolver.md
@@ -342,7 +342,7 @@ instead.
[`cargo update`] can be used to update the entries in `Cargo.lock` when new
versions are published. Without any options, it will attempt to update all
packages in the lock file. The `-p` flag can be used to target the update for
-a specific package, and other flags such as `--aggressive` or `--precise` can
+a specific package, and other flags such as `--recursive` or `--precise` can
be used to control how versions are selected.
[`cargo build`]: ../commands/cargo-build.md
@@ -464,10 +464,10 @@ situations may require specifying unusual requirements.
If you fail to do this, it may not be immediately obvious because Cargo can
opportunistically choose the newest version when you run a blanket `cargo
update`. However, if another user depends on your library, and runs `cargo
- update -p your-library`, it will *not* automatically update "bar" if it is
+ update your-library`, it will *not* automatically update "bar" if it is
locked in their `Cargo.lock`. It will only update "bar" in that situation if
the dependency declaration is also updated. Failure to do so can cause
- confusing build errors for the user using `cargo update -p`.
+ confusing build errors for the user using `cargo update your-library`.
* If two packages are tightly coupled, then an `=` dependency requirement may
help ensure that they stay in sync. For example, a library with a companion
proc-macro library will sometimes make assumptions between the two libraries
diff --git a/src/tools/cargo/src/doc/src/reference/running-a-registry.md b/src/tools/cargo/src/doc/src/reference/running-a-registry.md
index 144f1ee6a..87ab08ede 100644
--- a/src/tools/cargo/src/doc/src/reference/running-a-registry.md
+++ b/src/tools/cargo/src/doc/src/reference/running-a-registry.md
@@ -1,4 +1,4 @@
-## Running a Registry
+# Running a Registry
A minimal registry can be implemented by having a git repository that contains
an index, and a server that contains the compressed `.crate` files created by
diff --git a/src/tools/cargo/src/doc/src/reference/semver.md b/src/tools/cargo/src/doc/src/reference/semver.md
index 69d983078..f09250f1a 100644
--- a/src/tools/cargo/src/doc/src/reference/semver.md
+++ b/src/tools/cargo/src/doc/src/reference/semver.md
@@ -2135,9 +2135,16 @@ std = []
#### Possibly-breaking: removing an optional dependency {#cargo-remove-opt-dep}
-Removing an optional dependency can break a project using your library because
+Removing an [optional dependency][opt-dep] can break a project using your library because
another project may be enabling that dependency via [Cargo features].
+When there is an optional dependency, cargo implicitly defines a feature of
+the same name to provide a mechanism to enable the dependency and to check
+when it is enabled. This problem can be avoided by using the `dep:` syntax in
+the `[features]` table, which disables this implicit feature. Using `dep:`
+makes it possible to hide the existence of optional dependencies under more
+semantically-relevant names which can be more safely modified.
+
```toml
# Breaking change example
@@ -2152,7 +2159,33 @@ curl = { version = "0.4.31", optional = true }
# ..curl removed
```
+```toml
+# MINOR CHANGE
+#
+# This example shows how to avoid breaking changes with optional dependencies.
+
+###########################################################
+# Before
+[dependencies]
+curl = { version = "0.4.31", optional = true }
+
+[features]
+networking = ["dep:curl"]
+
+###########################################################
+# After
+[dependencies]
+# Here, one optional dependency was replaced with another.
+hyper = { version = "0.14.27", optional = true }
+
+[features]
+networking = ["dep:hyper"]
+```
+
Mitigation strategies:
+* Use the `dep:` syntax in the `[features]` table to avoid exposing optional
+ dependencies in the first place. See [optional dependencies][opt-dep] for
+ more information.
* Clearly document your features. If the optional dependency is not included
in the documented list of features, then you may decide to consider it safe
to change undocumented entries.
@@ -2166,6 +2199,8 @@ Mitigation strategies:
optional dependencies necessary to implement "networking". Then document the
"networking" feature.
+[opt-dep]: features.md#optional-dependencies
+
#### Minor: changing dependency features {#cargo-change-dep-feature}
It is usually safe to change the features on a dependency, as long as the
diff --git a/src/tools/cargo/src/doc/src/reference/source-replacement.md b/src/tools/cargo/src/doc/src/reference/source-replacement.md
index b8bcdc7ae..520604e5c 100644
--- a/src/tools/cargo/src/doc/src/reference/source-replacement.md
+++ b/src/tools/cargo/src/doc/src/reference/source-replacement.md
@@ -1,4 +1,4 @@
-## Source Replacement
+# Source Replacement
This document is about replacing the crate index. You can read about overriding
dependencies in the [overriding dependencies] section of this
@@ -34,7 +34,7 @@ token for the specified registry.
[overriding dependencies]: overriding-dependencies.md
[registries]: registries.md
-### Configuration
+## Configuration
Configuration of replacement sources is done through [`.cargo/config.toml`][config]
and the full set of available keys are:
@@ -82,7 +82,7 @@ git = "https://example.com/path/to/repo"
[config]: config.md
-### Registry Sources
+## Registry Sources
A "registry source" is one that is the same as crates.io itself. That is, it has
an index served in a git repository which matches the format of the
@@ -92,7 +92,7 @@ then has configuration indicating where to download crates from.
Currently there is not an already-available project for setting up a mirror of
crates.io. Stay tuned though!
-### Local Registry Sources
+## Local Registry Sources
A "local registry source" is intended to be a subset of another registry
source, but available on the local filesystem (aka vendoring). Local registries
@@ -111,7 +111,7 @@ Local registries are contained within one directory and contain a number of
the same format as the crates.io-index project (populated with just entries for
the crates that are present).
-### Directory Sources
+## Directory Sources
A "directory source" is similar to a local registry source where it contains a
number of crates available on the local filesystem, suitable for vendoring
diff --git a/src/tools/cargo/src/doc/src/reference/specifying-dependencies.md b/src/tools/cargo/src/doc/src/reference/specifying-dependencies.md
index f044af95b..746b5fcb2 100644
--- a/src/tools/cargo/src/doc/src/reference/specifying-dependencies.md
+++ b/src/tools/cargo/src/doc/src/reference/specifying-dependencies.md
@@ -1,4 +1,4 @@
-## Specifying Dependencies
+# Specifying Dependencies
Your crates can depend on other libraries from [crates.io] or other
registries, `git` repositories, or subdirectories on your local file system.
@@ -8,7 +8,7 @@ locally. You can have different dependencies for different platforms, and
dependencies that are only used during development. Let's take a look at how
to do each of these.
-### Specifying dependencies from crates.io
+## Specifying dependencies from crates.io
Cargo is configured to look for dependencies on [crates.io] by default. Only
the name and a version string are required in this case. In [the cargo
@@ -23,7 +23,7 @@ The string `"0.1.12"` is a version requirement. Although it looks like a
specific *version* of the `time` crate, it actually specifies a *range* of
versions and allows [SemVer] compatible updates. An update is allowed if the new
version number does not modify the left-most non-zero number in the major, minor,
-patch grouping. In this case, if we ran `cargo update -p time`, cargo should
+patch grouping. In this case, if we ran `cargo update time`, cargo should
update us to version `0.1.13` if it is the latest `0.1.z` release, but would not
update us to `0.2.0`. If instead we had specified the version string as `1.0`,
cargo should update to `1.1` if it is the latest `1.y` release, but not `2.0`.
@@ -53,10 +53,21 @@ and `x > 0`.
It is possible to further tweak the logic for selecting compatible versions
using special operators, though it shouldn't be necessary most of the time.
+## Version requirement syntax
+
### Caret requirements
-**Caret requirements** are an alternative syntax for the default strategy,
-`^1.2.3` is exactly equivalent to `1.2.3`.
+**Caret requirements** are the default version requirement strategy.
+This version strategy allows [SemVer] compatible updates.
+They are specified as version requirements with a leading caret (`^`).
+
+`^1.2.3` is an example of a caret requirement.
+
+Leaving off the caret is a simplified equivalent syntax to using caret requirements.
+While caret requirements are the default, it is recommended to use the
+simplified syntax when possible.
+
+`log = "^1.2.3"` is exactly equivalent to `log = "1.2.3"`.
### Tilde requirements
@@ -102,7 +113,7 @@ Here are some examples of comparison requirements:
= 1.2.3
```
-### Multiple requirements
+### Multiple version requirements
As shown in the examples above, multiple version requirements can be
separated with a comma, e.g., `>= 1.2, < 1.5`.
@@ -144,7 +155,7 @@ separated with a comma, e.g., `>= 1.2, < 1.5`.
[#6584]: https://github.com/rust-lang/cargo/issues/6584
[#10599]: https://github.com/rust-lang/cargo/issues/10599
-### Specifying dependencies from other registries
+## Specifying dependencies from other registries
To specify a dependency from a registry other than [crates.io], first the
registry must be configured in a `.cargo/config.toml` file. See the [registries
@@ -157,11 +168,11 @@ some-crate = { version = "1.0", registry = "my-registry" }
```
> **Note**: [crates.io] does not allow packages to be published with
-> dependencies on other registries.
+> dependencies on code published outside of [crates.io].
[registries documentation]: registries.md
-### Specifying dependencies from `git` repositories
+## Specifying dependencies from `git` repositories
To depend on a library located in a `git` repository, the minimum information
you need to specify is the location of the repository with the `git` key:
@@ -177,8 +188,8 @@ Cargo will fetch the `git` repository at this location then look for a
of a workspace and setting `git` to the repository containing the workspace).
Since we haven’t specified any other information, Cargo assumes that
-we intend to use the latest commit on the default branch branch
-to build our package, which may not necessarily be the main branch.
+we intend to use the latest commit on the default branch to build
+our package, which may not necessarily be the main branch.
You can combine the `git` key with the `rev`, `tag`, or `branch` keys to
specify something else. Here's an example of specifying that you want to use
the latest commit on a branch named `next`:
@@ -202,13 +213,24 @@ once the lock is in place. However, they can be pulled down manually with
See [Git Authentication] for help with git authentication for private repos.
-> **Note**: [crates.io] does not allow packages to be published with `git`
-> dependencies (`git` [dev-dependencies] are ignored). See the [Multiple
-> locations](#multiple-locations) section for a fallback alternative.
+> **Note**: Neither the `git` key nor the `path` key changes the meaning of the
+> `version` key: the `version` key always implies that the package is available
+> in a registry. `version`, `git`, and `path` keys are considered [separate
+> locations](#multiple-locations) for resolving the dependency.
+>
+> When the dependency is retrieved from `git`, the `version` key will _not_
+> affect which commit is used, but the version information in the dependency's
+> `Cargo.toml` file will still be validated against the `version` requirement.
+
+> **Note**: [crates.io] does not allow packages to be published with
+> dependencies on code published outside of [crates.io] itself
+> ([dev-dependencies] are ignored). See the [Multiple
+> locations](#multiple-locations) section for a fallback alternative for `git`
+> and `path` dependencies.
[Git Authentication]: ../appendix/git-authentication.md
-### Specifying path dependencies
+## Specifying path dependencies
Over time, our `hello_world` package from [the guide](../guide/index.md) has
grown significantly in size! It’s gotten to the point that we probably want to
@@ -245,11 +267,18 @@ and specify its version in the dependencies line as well:
hello_utils = { path = "hello_utils", version = "0.1.0" }
```
-> **Note**: [crates.io] does not allow packages to be published with `path`
-> dependencies (`path` [dev-dependencies] are ignored). See the [Multiple
-> locations](#multiple-locations) section for a fallback alternative.
+> **Note**: Neither the `git` key nor the `path` key changes the meaning of the
+> `version` key: the `version` key always implies that the package is available
+> in a registry. `version`, `git`, and `path` keys are considered [separate
+> locations](#multiple-locations) for resolving the dependency.
+
+> **Note**: [crates.io] does not allow packages to be published with
+> dependencies on code published outside of [crates.io] itself
+> ([dev-dependencies] are ignored). See the [Multiple
+> locations](#multiple-locations) section for a fallback alternative for `git`
+> and `path` dependencies.
-### Multiple locations
+## Multiple locations
It is possible to specify both a registry version and a `git` or `path`
location. The `git` or `path` dependency will be used locally (in which case
@@ -278,7 +307,7 @@ is published. This is similar to specifying an
[override](overriding-dependencies.md), but only applies to this one
dependency declaration.
-### Platform specific dependencies
+## Platform specific dependencies
Platform-specific dependencies take the same format, but are listed under a
`target` section. Normally Rust-like [`#[cfg]`
@@ -337,7 +366,7 @@ winhttp = "0.4.0"
openssl = "1.0.1"
```
-#### Custom target specifications
+### Custom target specifications
If you’re using a custom target specification (such as `--target
foo/bar.json`), use the base filename without the `.json` extension:
@@ -353,7 +382,7 @@ native = { path = "native/i686" }
> **Note**: Custom target specifications are not usable on the stable channel.
-### Development dependencies
+## Development dependencies
You can add a `[dev-dependencies]` section to your `Cargo.toml` whose format
is equivalent to `[dependencies]`:
@@ -385,7 +414,7 @@ mio = "0.0.1"
> packagers) may want to run tests within a crate, so providing a `version` if
> possible can still be beneficial.
-### Build dependencies
+## Build dependencies
You can depend on other Cargo-based crates for use in your build scripts.
Dependencies are declared through the `build-dependencies` section of the
@@ -417,7 +446,7 @@ itself and its build script are built separately, so their
dependencies need not coincide. Cargo is kept simpler and cleaner by
using independent dependencies for independent purposes.
-### Choosing features
+## Choosing features
If a package you depend on offers conditional features, you can
specify which to use:
@@ -433,7 +462,7 @@ features = ["secure-password", "civet"]
More information about features can be found in the [features
chapter](features.md#dependency-features).
-### Renaming dependencies in `Cargo.toml`
+## Renaming dependencies in `Cargo.toml`
When writing a `[dependencies]` section in `Cargo.toml` the key you write for a
dependency typically matches up to the name of the crate you import from in the
@@ -492,7 +521,7 @@ following to the above manifest:
log-debug = ['bar/log-debug'] # using 'foo/log-debug' would be an error!
```
-### Inheriting a dependency from a workspace
+## Inheriting a dependency from a workspace
Dependencies can be inherited from a workspace by specifying the
dependency in the workspace's [`[workspace.dependencies]`][workspace.dependencies] table.
diff --git a/src/tools/cargo/src/doc/src/reference/timings.md b/src/tools/cargo/src/doc/src/reference/timings.md
index b978d52cd..e8ff751ca 100644
--- a/src/tools/cargo/src/doc/src/reference/timings.md
+++ b/src/tools/cargo/src/doc/src/reference/timings.md
@@ -10,7 +10,7 @@ This writes an HTML report in `target/cargo-timings/cargo-timing.html`. This
also writes a copy of the report to the same directory with a timestamp in the
filename, if you want to look at older runs.
-#### Reading the graphs
+## Reading the graphs
There are two tables and two graphs in the output.
diff --git a/src/tools/cargo/src/doc/src/reference/unstable.md b/src/tools/cargo/src/doc/src/reference/unstable.md
index 55084f88e..c8047de90 100644
--- a/src/tools/cargo/src/doc/src/reference/unstable.md
+++ b/src/tools/cargo/src/doc/src/reference/unstable.md
@@ -1,4 +1,4 @@
-## Unstable Features
+# Unstable Features
Experimental Cargo features are only available on the [nightly channel]. You
are encouraged to experiment with these features to see if they meet your
@@ -59,7 +59,7 @@ For the latest nightly, see the [nightly version] of this page.
[stabilized]: https://doc.crates.io/contrib/process/unstable.html#stabilization
[nightly version]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#script
-### List of unstable features
+## List of unstable features
* Unstable-specific features
* [-Z allow-features](#allow-features) --- Provides a way to restrict which unstable features are used.
@@ -82,7 +82,6 @@ For the latest nightly, see the [nightly version] of this page.
* [build-std-features](#build-std-features) --- Sets features to use with the standard library.
* [binary-dep-depinfo](#binary-dep-depinfo) --- Causes the dep-info file to track binary dependencies.
* [panic-abort-tests](#panic-abort-tests) --- Allows running tests with the "abort" panic strategy.
- * [keep-going](#keep-going) --- Build as much as possible rather than aborting on the first error.
* [check-cfg](#check-cfg) --- Compile-time validation of `cfg` expressions.
* [host-config](#host-config) --- Allows setting `[target]`-like configuration settings for host build targets.
* [target-applies-to-host](#target-applies-to-host) --- Alters whether certain flags will be passed to host build targets.
@@ -94,7 +93,6 @@ For the latest nightly, see the [nightly version] of this page.
* [codegen-backend](#codegen-backend) --- Select the codegen backend used by rustc.
* [per-package-target](#per-package-target) --- Sets the `--target` to use for each individual package.
* [artifact dependencies](#artifact-dependencies) --- Allow build artifacts to be included into other build artifacts and build them for different targets.
- * [`[lints]`](#lints) --- Configure lint levels for various linter tools.
* Information and metadata
* [Build-plan](#build-plan) --- Emits JSON information on which commands will be run.
* [unit-graph](#unit-graph) --- Emits JSON for Cargo's internal graph structure.
@@ -103,14 +101,13 @@ For the latest nightly, see the [nightly version] of this page.
* [config-include](#config-include) --- Adds the ability for config files to include other files.
* [`cargo config`](#cargo-config) --- Adds a new subcommand for viewing config files.
* Registries
- * [credential-process](#credential-process) --- Adds support for fetching registry tokens from an external authentication program.
* [publish-timeout](#publish-timeout) --- Controls the timeout between uploading the crate and being available in the index
- * [registry-auth](#registry-auth) --- Adds support for authenticated registries, and generate registry authentication tokens using asymmetric cryptography.
+ * [asymmetric-token](#asymmetric-token) --- Adds support for authentication tokens using asymmetric cryptography (`cargo:paseto` provider).
* Other
* [gitoxide](#gitoxide) --- Use `gitoxide` instead of `git2` for a set of operations.
* [script](#script) --- Enable support for single-file `.rs` packages.
-### allow-features
+## allow-features
This permanently-unstable flag makes it so that only a listed set of
unstable features can be used. Specifically, if you pass
@@ -136,7 +133,7 @@ to any Rust tools that cargo ends up calling (like `rustc` or
`rustdoc`). Thus, if you run `cargo -Zallow-features=`, no unstable
Cargo _or_ Rust features can be used.
-### no-index-update
+## no-index-update
* Original Issue: [#3479](https://github.com/rust-lang/cargo/issues/3479)
* Tracking Issue: [#7404](https://github.com/rust-lang/cargo/issues/7404)
@@ -145,7 +142,7 @@ the registry index. This is intended for tools such as Crater that issue many
Cargo commands, and you want to avoid the network latency for updating the
index each time.
-### mtime-on-use
+## mtime-on-use
* Original Issue: [#6477](https://github.com/rust-lang/cargo/pull/6477)
* Cache usage meta tracking issue: [#7150](https://github.com/rust-lang/cargo/issues/7150)
@@ -156,7 +153,7 @@ To make this more practical setting the `unstable.mtime_on_use` flag in `.cargo/
or the corresponding ENV variable will apply the `-Z mtime-on-use` to all
invocations of nightly cargo. (the config flag is ignored by stable)
-### avoid-dev-deps
+## avoid-dev-deps
* Original Issue: [#4988](https://github.com/rust-lang/cargo/issues/4988)
* Tracking Issue: [#5133](https://github.com/rust-lang/cargo/issues/5133)
@@ -166,7 +163,7 @@ used. The `-Z avoid-dev-deps` flag allows Cargo to avoid downloading
dev-dependencies if they are not needed. The `Cargo.lock` file will not be
generated if dev-dependencies are skipped.
-### minimal-versions
+## minimal-versions
* Original Issue: [#4100](https://github.com/rust-lang/cargo/issues/4100)
* Tracking Issue: [#5657](https://github.com/rust-lang/cargo/issues/5657)
@@ -186,7 +183,7 @@ minimum versions that you are actually using. That is, if Cargo.toml says
`foo = "1.0.0"` that you don't accidentally depend on features added only in
`foo 1.5.0`.
-### direct-minimal-versions
+## direct-minimal-versions
* Original Issue: [#4100](https://github.com/rust-lang/cargo/issues/4100)
* Tracking Issue: [#5657](https://github.com/rust-lang/cargo/issues/5657)
@@ -203,7 +200,7 @@ minimum versions that you are actually using. That is, if Cargo.toml says
Indirect dependencies are resolved as normal so as not to be blocked on their
minimal version validation.
-### out-dir
+## out-dir
* Original Issue: [#4875](https://github.com/rust-lang/cargo/issues/4875)
* Tracking Issue: [#6790](https://github.com/rust-lang/cargo/issues/6790)
@@ -226,7 +223,7 @@ This can also be specified in `.cargo/config.toml` files.
out-dir = "out"
```
-### doctest-xcompile
+## doctest-xcompile
* Tracking Issue: [#7040](https://github.com/rust-lang/cargo/issues/7040)
* Tracking Rustc Issue: [#64245](https://github.com/rust-lang/rust/issues/64245)
@@ -242,7 +239,7 @@ information from `.cargo/config.toml`. See the rustc issue for more information.
cargo test --target foo -Zdoctest-xcompile
```
-### Build-plan
+## Build-plan
* Tracking Issue: [#5579](https://github.com/rust-lang/cargo/issues/5579)
The `--build-plan` argument for the `build` command will output JSON with
@@ -254,7 +251,7 @@ Example:
cargo +nightly build --build-plan -Z unstable-options
```
-### Metabuild
+## Metabuild
* Tracking Issue: [rust-lang/rust#49803](https://github.com/rust-lang/rust/issues/49803)
* RFC: [#2196](https://github.com/rust-lang/rfcs/blob/master/text/2196-metabuild.md)
@@ -287,7 +284,7 @@ extra-info = "qwerty"
Metabuild packages should have a public function called `metabuild` that
performs the same actions as a regular `build.rs` script would perform.
-### public-dependency
+## public-dependency
* Tracking Issue: [#44663](https://github.com/rust-lang/rust/issues/44663)
The 'public-dependency' feature allows marking dependencies as 'public'
@@ -304,7 +301,7 @@ my_dep = { version = "1.2.3", public = true }
private_dep = "2.0.0" # Will be 'private' by default
```
-### msrv-policy
+## msrv-policy
- [#9930](https://github.com/rust-lang/cargo/issues/9930) (MSRV-aware resolver)
- [#10653](https://github.com/rust-lang/cargo/issues/10653) (MSRV-aware cargo-add)
- [#10903](https://github.com/rust-lang/cargo/issues/10903) (MSRV-aware cargo-install)
@@ -312,7 +309,7 @@ private_dep = "2.0.0" # Will be 'private' by default
The `msrv-policy` feature enables experiments in MSRV-aware policy for cargo in
preparation for an upcoming RFC.
-### build-std
+## build-std
* Tracking Repository: <https://github.com/rust-lang/wg-cargo-std-aware>
The `build-std` feature enables Cargo to compile the standard library itself as
@@ -367,7 +364,7 @@ $ cargo +nightly build -Z build-std=core,alloc
The value here is a comma-separated list of standard library crates to build.
-#### Requirements
+### Requirements
As a summary, a list of requirements today to use `-Z build-std` are:
@@ -376,7 +373,7 @@ As a summary, a list of requirements today to use `-Z build-std` are:
* You must use both a nightly Cargo and a nightly rustc
* The `-Z build-std` flag must be passed to all `cargo` invocations.
-#### Reporting bugs and helping out
+### Reporting bugs and helping out
The `-Z build-std` feature is in the very early stages of development! This
feature for Cargo has an extremely long history and is very large in scope, and
@@ -393,7 +390,7 @@ something doesn't quite work the way you'd like it to, feel free to check out
the [issue tracker](https://github.com/rust-lang/wg-cargo-std-aware/issues) of
the tracking repository, and if it's not there please file a new issue!
-### build-std-features
+## build-std-features
* Tracking Repository: <https://github.com/rust-lang/wg-cargo-std-aware>
This flag is a sibling to the `-Zbuild-std` feature flag. This will configure
@@ -402,7 +399,7 @@ library. The default enabled features, at this time, are `backtrace` and
`panic-unwind`. This flag expects a comma-separated list and, if provided, will
override the default list of features enabled.
-### binary-dep-depinfo
+## binary-dep-depinfo
* Tracking rustc issue: [#63012](https://github.com/rust-lang/rust/issues/63012)
The `-Z binary-dep-depinfo` flag causes Cargo to forward the same flag to
@@ -413,7 +410,7 @@ the crate will be rebuilt). The primary use case is for building the compiler
itself, which has implicit dependencies on the standard library that would
otherwise be untracked for change-detection.
-### panic-abort-tests
+## panic-abort-tests
* Tracking Issue: [#67650](https://github.com/rust-lang/rust/issues/67650)
* Original Pull Request: [#7460](https://github.com/rust-lang/cargo/pull/7460)
@@ -429,37 +426,7 @@ like to stabilize it somehow!
[rust-lang/rust#64158]: https://github.com/rust-lang/rust/pull/64158
-### keep-going
-* Tracking Issue: [#10496](https://github.com/rust-lang/cargo/issues/10496)
-
-`cargo build --keep-going` (and similarly for every command involving compilation, like `check` and `doc`)
-will build as many crates in the dependency graph as possible,
-rather than aborting the build at the first one that fails to build.
-
-For example if the current package depends on dependencies `fails` and `works`,
-one of which fails to build, `cargo check -j1` may or may not build the one that
-succeeds (depending on which one of the two builds Cargo picked to run first),
-whereas `cargo check -j1 --keep-going` would definitely run both builds, even if
-the one run first fails.
-
-The `-Z unstable-options` command-line option must be used in order to use
-`--keep-going` while it is not yet stable:
-
-```console
-cargo check --keep-going -Z unstable-options
-```
-
-While `cargo test` and `cargo bench` commands involve compilation, they do not provide a `--keep-going` flag.
-Both commands already include a similar `--no-fail-fast` flag, allowing running as many tests as possible without stopping at the first failure.
-To "compile" as many tests as possible, use target selection flags like `--tests` to build test binaries separately.
-For example,
-
-```console
-cargo build --tests --keep-going -Zunstable-options
-cargo test --tests --no-fail-fast
-```
-
-### config-include
+## config-include
* Tracking Issue: [#7723](https://github.com/rust-lang/cargo/issues/7723)
This feature requires the `-Zconfig-include` command-line option.
@@ -487,7 +454,7 @@ different. When a config file contains an `include` key:
2. Then, the config file's own values are merged on top of the config
from the `include` path.
-### target-applies-to-host
+## target-applies-to-host
* Original Pull Request: [#9322](https://github.com/rust-lang/cargo/pull/9322)
* Tracking Issue: [#9453](https://github.com/rust-lang/cargo/issues/9453)
@@ -529,7 +496,7 @@ target-applies-to-host = false
cargo +nightly -Ztarget-applies-to-host build --target x86_64-unknown-linux-gnu
```
-### host-config
+## host-config
* Original Pull Request: [#9322](https://github.com/rust-lang/cargo/pull/9322)
* Tracking Issue: [#9452](https://github.com/rust-lang/cargo/issues/9452)
@@ -564,7 +531,7 @@ Setting `-Zhost-config` changes the default for `target-applies-to-host` to
cargo +nightly -Ztarget-applies-to-host -Zhost-config build --target x86_64-unknown-linux-gnu
```
-### unit-graph
+## unit-graph
* Tracking Issue: [#8002](https://github.com/rust-lang/cargo/issues/8002)
The `--unit-graph` flag can be passed to any build command (`build`, `check`,
@@ -698,7 +665,7 @@ The following is a description of the JSON structure:
}
```
-### Profile `rustflags` option
+## Profile `rustflags` option
* Original Issue: [rust-lang/cargo#7878](https://github.com/rust-lang/cargo/issues/7878)
* Tracking Issue: [rust-lang/cargo#10271](https://github.com/rust-lang/cargo/issues/10271)
@@ -728,7 +695,7 @@ profile-rustflags = true
rustflags = [ "-C", "..." ]
```
-### rustdoc-map
+## rustdoc-map
* Tracking Issue: [#8296](https://github.com/rust-lang/cargo/issues/8296)
This feature adds configuration settings that are passed to `rustdoc` so that
@@ -769,7 +736,7 @@ The default value is `"remote"`.
The value may also take a URL for a custom location.
-### per-package-target
+## per-package-target
* Tracking Issue: [#9406](https://github.com/rust-lang/cargo/pull/9406)
* Original Pull Request: [#9030](https://github.com/rust-lang/cargo/pull/9030)
* Original Issue: [#7004](https://github.com/rust-lang/cargo/pull/7004)
@@ -792,7 +759,7 @@ In this example, the crate is always built for
as a plugin for a main program that runs on the host (or provided on
the command line) target.
-### artifact-dependencies
+## artifact-dependencies
* Tracking Issue: [#9096](https://github.com/rust-lang/cargo/pull/9096)
* Original Pull Request: [#9992](https://github.com/rust-lang/cargo/pull/9992)
@@ -802,7 +769,7 @@ and use the artifacts built by those crates at compile time.
Run `cargo` with `-Z bindeps` to enable this functionality.
-#### artifact-dependencies: Dependency declarations
+### artifact-dependencies: Dependency declarations
Artifact-dependencies adds the following keys to a dependency declaration in `Cargo.toml`:
@@ -854,7 +821,7 @@ Artifact-dependencies adds the following keys to a dependency declaration in `Ca
same-target = { version = "1.0", artifact = "bin", target = "target" }
```
-#### artifact-dependencies: Environment variables
+### artifact-dependencies: Environment variables
After building an artifact dependency, Cargo provides the following environment variables that you can use to access the artifact:
@@ -883,9 +850,9 @@ For each kind of dependency, these variables are supplied to the same part of th
[`env!`]: https://doc.rust-lang.org/std/macro.env.html
-#### artifact-dependencies: Examples
+### artifact-dependencies: Examples
-##### Example: use a binary executable from a build script
+#### Example: use a binary executable from a build script
In the `Cargo.toml` file, you can specify a dependency on a binary to make available for a build script:
@@ -910,7 +877,7 @@ fn main() {
}
```
-##### Example: use _cdylib_ artifact in build script
+#### Example: use _cdylib_ artifact in build script
The `Cargo.toml` in the consuming package, building the `bar` library as `cdylib`
for a specific build target…
@@ -928,7 +895,7 @@ fn main() {
}
```
-##### Example: use _binary_ artifact and its library in a binary
+#### Example: use _binary_ artifact and its library in a binary
The `Cargo.toml` in the consuming package, building the `bar` binary for inclusion
as artifact while making it available as library as well…
@@ -947,7 +914,7 @@ fn main() {
}
```
-### publish-timeout
+## publish-timeout
* Tracking Issue: [11222](https://github.com/rust-lang/cargo/issues/11222)
The `publish.timeout` key in a config file can be used to control how long
@@ -965,35 +932,11 @@ It requires the `-Zpublish-timeout` command-line options to be set.
timeout = 300 # in seconds
```
-### registry-auth
-* Tracking Issue: [10474](https://github.com/rust-lang/cargo/issues/10474)
-* RFC: [#3139](https://github.com/rust-lang/rfcs/pull/3139)
-
-Enables Cargo to include the authorization token for API requests, crate downloads
-and sparse index updates by adding a configuration option to config.json
-in the registry index.
-
-To use this feature, the registry server must include `"auth-required": true` in
-`config.json`, and you must pass the `-Z registry-auth` flag on the Cargo command line.
-
-When using the sparse protocol, Cargo will attempt to fetch the `config.json` file before
-fetching any other files. If the server responds with an HTTP 401, then Cargo will assume
-that the registry requires authentication and re-attempt the request for `config.json`
-with the authentication token included.
-
-On authentication failure (or missing authentication token) the server MAY include a
-`WWW-Authenticate` header with a `Cargo login_url` challenge to indicate where the user
-can go to get a token.
-
-```
-WWW-Authenticate: Cargo login_url="https://test-registry-login/me
-```
-
-This same flag is also used to enable asymmetric authentication tokens.
+## asymmetric-token
* Tracking Issue: [10519](https://github.com/rust-lang/cargo/issues/10519)
* RFC: [#3231](https://github.com/rust-lang/rfcs/pull/3231)
-Add support for Cargo to authenticate the user to registries without sending secrets over the network.
+The `-Z asymmetric-token` flag enables the `cargo:paseto` credential provider which allows Cargo to authenticate to registries without sending secrets over the network.
In [`config.toml`](config.md) and `credentials.toml` files there is a field called `private-key`, which is a private key formatted in the secret [subset of `PASERK`](https://github.com/paseto-standard/paserk/blob/master/types/secret.md) and is used to sign asymmetric tokens
@@ -1029,266 +972,7 @@ The "footer" (which is part of the signature) will be a JSON string in UTF-8 and
PASETO includes the message that was signed, so the server does not have to reconstruct the exact string from the request in order to check the signature. The server does need to check that the signature is valid for the string in the PASETO and that the contents of that string matches the request.
If a claim should be expected for the request but is missing in the PASETO then the request must be rejected.
-### credential-process
-* Tracking Issue: [#8933](https://github.com/rust-lang/cargo/issues/8933)
-* RFC: [#2730](https://github.com/rust-lang/rfcs/pull/2730)
-
-The `credential-process` feature adds a config setting to fetch registry
-authentication tokens by calling an external process.
-
-To use this feature, you must pass the `-Z credential-process` flag on the
-command-line.
-
-#### `credential-process` Configuration
-
-To configure which process to run to fetch the token, specify the process in
-the `registry` table in a [config file] with spaces separating arguments. If the
-path to the provider or its arguments contain spaces, then it mused be defined in
-the `credential-alias` table and referenced instead.
-
-```toml
-[registry]
-global-credential-providers = ["/usr/bin/cargo-creds"]
-```
-
-The provider at the end of the list will be attempted first. This ensures
-that when config files are merged, files closer to the project (and ultimatly
-environment variables) have precedence.
-
-In this example, the `my-provider` provider will be attempted first, and if
-it cannot provide credentials, then the `cargo:token` provider will be used.
-
-```toml
-[registry]
-global-credential-providers = ['cargo:token', 'my-provider']
-```
-
-If you want to use a different provider for a specific registry, it can be
-specified in the `registries` table:
-
-```toml
-[registries.my-registry]
-credential-provider = "/usr/bin/cargo-creds"
-```
-
-The credential provider for crates.io can be specified as:
-
-```toml
-[registry]
-credential-provider = "/usr/bin/cargo-creds"
-```
-
-The value can be a string with spaces separating arguments or it can be a TOML
-array of strings.
-
-For commonly-used providers, or providers that need to contain spaces in the arguments
-or path, the `credential-alias` table can be used. These aliases can be referenced
-in `credential-provider` or `global-credential-providers`.
-
-```toml
-[credential-alias]
-my-alias = ["/usr/bin/cargo-creds", "--argument"]
-
-[registry]
-global-credential-providers = ["cargo:token", "my-alias"]
-```
-
-#### Built-in providers
-
-Cargo now includes several built-in credential providers. These providers are
-executed within the Cargo process. They are identified with the `cargo:` prefix.
-
-* `cargo:token` - Uses Cargo's config and `credentials.toml` to store the token (default).
-* `cargo:wincred` - Uses the Windows Credential Manager to store the token.
-* `cargo:macos-keychain` - Uses the macOS Keychain to store the token.
-* `cargo:libsecret` - Uses [libsecret](https://wiki.gnome.org/Projects/Libsecret) to store tokens on Linux systems.
-* `cargo:token-from-stdout <command>` - Launch a subprocess that returns a token
- on stdout. Newlines will be trimmed. The process inherits the user's stdin and stderr.
- It should exit 0 on success, and nonzero on error.
-
- With this form, [`cargo login`] and [`cargo logout`] are not supported and
- return an error if used.
-
- The following environment variables will be provided to the executed command:
-
- * `CARGO` --- Path to the `cargo` binary executing the command.
- * `CARGO_REGISTRY_INDEX_URL` --- The URL of the registry index.
- * `CARGO_REGISTRY_NAME_OPT` --- Optional name of the registry. Should not be used as a storage key. Not always available.
-
-* `cargo:paseto` - implements asymmetric token support (RFC3231) as a credential provider.
-
-
-`cargo-credential-1password` uses the 1password `op` CLI to store the token. You must
-install the `op` CLI from the [1password
-website](https://1password.com/downloads/command-line/). You must run `op
-signin` at least once with the appropriate arguments (such as `op signin
-my.1password.com user@example.com`), unless you provide the sign-in-address
-and email arguments. The master password will be required on each request
-unless the appropriate `OP_SESSION` environment variable is set. It supports
-the following command-line arguments:
-* `--account`: The account shorthand name to use.
-* `--vault`: The vault name to use.
-* `--sign-in-address`: The sign-in-address, which is a web address such as `my.1password.com`.
-* `--email`: The email address to sign in with.
-
-Install the provider with `cargo install cargo-credential-1password`
-In the config, add it to `global-credential-providers`:
-```toml
-[registry]
-global-credential-providers = ["cargo-credential-1password"]
-```
-
-#### JSON Interface
-When using an external credential provider, Cargo communicates with the credential
-provider using stdin/stdout messages passed as a single line of JSON.
-
-Cargo will always execute the credential provider with the `--cargo-plugin` argument.
-This enables a credential provider executable to have additional functionality beyond
-how Cargo uses it.
-
-The messages here have additional newlines added for readability.
-Actual messages must not contain newlines.
-
-##### Credential hello
-* Sent by: credential provider
-* Purpose: used to identify the supported protocols on process startup
-```javascript
-{
- "v":[1]
-}
-```
-
-##### Login request
-* Sent by: Cargo
-* Purpose: collect and store credentials
-```javascript
-{
- // Protocol version
- "v":1,
- // Action to perform: login
- "kind":"login",
- // Registry information
- "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"},
-}
-```
-
-##### Read request
-* Sent by: Cargo
-* Purpose: Get the credential for reading crate information
-```javascript
-{
- // Protocol version
- "v":1,
- // Request kind: get credentials
- "kind":"get",
- // Action to perform: read crate information
- "operation":"read",
- // Registry information
- "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"},
- // Additional command-line args
- "args":[]
-}
-```
-
-##### Publish request
-* Sent by: Cargo
-* Purpose: Get the credential for publishing a crate
-```javascript
-{
- // Protocol version
- "v":1,
- // Request kind: get credentials
- "kind":"get",
- // Action to perform: publish crate
- "operation":"publish",
- // Crate name
- "name":"sample",
- // Crate version
- "vers":"0.1.0",
- // Crate checksum
- "cksum":"...",
- // Registry information
- "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"},
- // Additional command-line args
- "args":[]
-}
-```
-
-##### Success response
-* Sent by: credential process
-* Purpose: Gives the credential to Cargo
-```javascript
-{"Ok":{
- // Response kind: this was a get request kind
- "kind":"get",
- // Token to send to the registry
- "token":"...",
- // Cache control. Can be one of the following:
- // * "never"
- // * "session"
- // * { "expires": UNIX timestamp }
- "cache":{"expires":1684251794},
- // Is the token operation independent?
- "operation_independent":true
-}}
-```
-
-##### Failure response
-* Sent by: credential process
-* Purpose: Gives error information to Cargo
-```javascript
-{"Err":{
- // Error: the credential provider does not support the
- // registry
- "kind":"url-not-supported",
-
- // Error: The credential could not be found in the provider.
- // using `cargo login --registry ...`.
- "kind":"not-found",
-
- // Error: something else has failed
- "kind":"other",
- "detail": "free form string error message"
-}}
-```
-
-##### Example communication to request a token for reading:
-1. Cargo spawns the credential process, capturing stdin and stdout.
-2. Credential process sends the Hello message to Cargo
- ```javascript
- { "v": [1] }
- ```
-3. Cargo sends the CredentialRequest message to the credential process (newlines added for readability).
- ```javascript
- {
- "v": 1,
- "kind": "get",
- "operation": "read",
- "registry":{"index-url":"sparse+https://registry-url/index/", "name":"ado2"},
- "args":[]
- }
- ```
-4. Credential process sends the CredentialResponse to Cargo (newlines added for readability).
- ```javascript
- {
- "token": "...",
- "cache": "session",
- "operation_independent": false
- }
- ```
-5. Credential process exits
-6. Cargo uses the token for the remainder of the session (until Cargo exits) when interacting with this registry.
-
-[`cargo login`]: ../commands/cargo-login.md
-[`cargo logout`]: ../commands/cargo-logout.md
-[`cargo publish`]: ../commands/cargo-publish.md
-[`cargo owner`]: ../commands/cargo-owner.md
-[`cargo yank`]: ../commands/cargo-yank.md
-[`credentials.toml` file]: config.md#credentials
-[crates.io]: https://crates.io/
-[config file]: config.md
-
-### `cargo config`
+## `cargo config`
* Original Issue: [#2362](https://github.com/rust-lang/cargo/issues/2362)
* Tracking Issue: [#9301](https://github.com/rust-lang/cargo/issues/9301)
@@ -1304,7 +988,7 @@ cargo +nightly -Zunstable-options config get build.rustflags
If no config value is included, it will display all config values. See the
`--help` output for more options available.
-### rustc `--print`
+## rustc `--print`
* Tracking Issue: [#9357](https://github.com/rust-lang/cargo/issues/9357)
@@ -1319,7 +1003,7 @@ The primary use case is to run `cargo rustc --print=cfg` to get config values
for the appropriate target and influenced by any other RUSTFLAGS.
-### Different binary name
+## Different binary name
* Tracking Issue: [#9778](https://github.com/rust-lang/cargo/issues/9778)
* PR: [#9627](https://github.com/rust-lang/cargo/pull/9627)
@@ -1346,7 +1030,7 @@ filename = "007bar"
path = "src/main.rs"
```
-### scrape-examples
+## scrape-examples
* RFC: [#3123](https://github.com/rust-lang/rfcs/pull/3123)
* Tracking Issue: [#9910](https://github.com/rust-lang/cargo/issues/9910)
@@ -1390,7 +1074,7 @@ For example, you can set `doc-scrape-examples` to true for one example target, a
you are ok with dev-deps being build for `cargo doc`.
-### check-cfg
+## check-cfg
* RFC: [#3013](https://github.com/rust-lang/rfcs/pull/3013)
* Tracking Issue: [#10554](https://github.com/rust-lang/cargo/issues/10554)
@@ -1425,7 +1109,7 @@ println!("cargo:rustc-check-cfg=names(foo, bar)");
cargo check -Z unstable-options -Z check-cfg=output
```
-#### `cargo:rustc-check-cfg=CHECK_CFG`
+### `cargo:rustc-check-cfg=CHECK_CFG`
The `rustc-check-cfg` instruction tells Cargo to pass the given value to the
`--check-cfg` flag to the compiler. This may be used for compile-time
@@ -1437,7 +1121,7 @@ with a warning.
If you want to integrate with Cargo features, use `-Zcheck-cfg=features` instead of
trying to do it manually with this option.
-### codegen-backend
+## codegen-backend
The `codegen-backend` feature makes it possible to select the codegen backend used by rustc using a profile.
@@ -1466,7 +1150,7 @@ codegen-backend = true
codegen-backend = "cranelift"
```
-### gitoxide
+## gitoxide
* Tracking Issue: [#11813](https://github.com/rust-lang/cargo/issues/11813)
@@ -1493,7 +1177,7 @@ Valid operations are the following:
* When the unstable feature is on, fetching/cloning a git repository is always a shallow fetch. This roughly equals to `git fetch --depth 1` everywhere.
* Even with the presence of `Cargo.lock` or specifying a commit `{ rev = "…" }`, gitoxide is still smart enough to shallow fetch without unshallowing the existing repository.
-### script
+## script
* Tracking Issue: [#12207](https://github.com/rust-lang/cargo/issues/12207)
@@ -1507,13 +1191,12 @@ fn main() {}
```
A user may optionally specify a manifest in a `cargo` code fence in a module-level comment, like:
-```rust
+````rust
#!/usr/bin/env -S cargo +nightly -Zscript
-
-//! ```cargo
-//! [dependencies]
-//! clap = { version = "4.2", features = ["derive"] }
-//! ```
+```cargo
+[dependencies]
+clap = { version = "4.2", features = ["derive"] }
+```
use clap::Parser;
@@ -1528,9 +1211,9 @@ fn main() {
let args = Args::parse();
println!("{:?}", args);
}
-```
+````
-#### Single-file packages
+### Single-file packages
In addition to today's multi-file packages (`Cargo.toml` file with other `.rs`
files), we are adding the concept of single-file packages which may contain an
@@ -1541,22 +1224,8 @@ Single-file packages may be selected via `--manifest-path`, like
`cargo test --manifest-path foo.rs`. Unlike `Cargo.toml`, these files cannot be auto-discovered.
A single-file package may contain an embedded manifest. An embedded manifest
-is stored using `TOML` in a markdown code-fence with `cargo` at the start of the
-infostring inside a target-level doc-comment. It is an error to have multiple
-`cargo` code fences in the target-level doc-comment. We can relax this later,
-either merging the code fences or ignoring later code fences.
-
-Supported forms of embedded manifest are:
-``````rust
-//! ```cargo
-//! ```
-``````
-``````rust
-/*!
- * ```cargo
- * ```
- */
-``````
+is stored using `TOML` in rust "frontmatter", a markdown code-fence with `cargo`
+at the start of the infostring at the top of the file.
Inferred / defaulted manifest fields:
- `package.name = <slugified file stem>`
@@ -1580,7 +1249,7 @@ The lockfile for single-file packages will be placed in `CARGO_TARGET_DIR`. In
the future, when workspaces are supported, that will allow a user to have a
persistent lockfile.
-#### Manifest-commands
+### Manifest-commands
You may pass a manifest directly to the `cargo` command, without a subcommand,
like `foo/Cargo.toml` or a single-file package like `foo.rs`. This is mostly
@@ -1600,133 +1269,41 @@ Differences between `cargo run --manifest-path <path>` and `cargo <path>`
- `cargo <path>` runs with the config for `<path>` and not the current dir, more like `cargo install --path <path>`
- `cargo <path>` is at a verbosity level below the normal default. Pass `-v` to get normal output.
-### `[lints]`
-
-* Tracking Issue: [#12115](https://github.com/rust-lang/cargo/issues/12115)
-
-A new `lints` table would be added to configure lints:
-```toml
-[lints.rust]
-unsafe = "forbid"
-```
-and `cargo` would pass these along as flags to `rustc`, `clippy`, or other lint tools when `-Zlints` is used.
-
-This would work with
-[RFC 2906 `workspace-deduplicate`](https://rust-lang.github.io/rfcs/2906-cargo-workspace-deduplicate.html):
-```toml
-[lints]
-workspace = true
-
-[workspace.lints.rust]
-unsafe = "forbid"
-```
-
-#### Documentation Updates
-
-##### The `lints` section
+### Documentation Updates
-*as a new ["Manifest Format" entry](./manifest.html#the-manifest-format)*
-
-Override the default level of lints from different tools by assigning them to a new level in a
-table, for example:
-```toml
-[lints.rust]
-unsafe = "forbid"
-```
-
-This is short-hand for:
-```toml
-[lints.rust]
-unsafe = { level = "forbid", priority = 0 }
-```
+# Stabilized and removed features
-`level` corresponds to the lint levels in `rustc`:
-- `forbid`
-- `deny`
-- `warn`
-- `allow`
-
-`priority` is a signed integer that controls which lints or lint groups override other lint groups:
-- lower (particularly negative) numbers have lower priority, being overridden
- by higher numbers, and show up first on the command-line to tools like
- `rustc`
-
-To know which table under `[lints]` a particular lint belongs under, it is the part before `::` in the lint
-name. If there isn't a `::`, then the tool is `rust`. For example a warning
-about `unsafe` would be `lints.rust.unsafe` but a lint about
-`clippy::enum_glob_use` would be `lints.clippy.enum_glob_use`.
-
-For example:
-```toml
-[lints.rust]
-unsafe = "forbid"
-
-[lints.clippy]
-enum_glob_use = "deny"
-```
-
-##### The `lints` table
-
-*as a new [`[workspace]` entry](./workspaces.html#the-workspace-section)*
-
-The `workspace.lints` table is where you define lint configuration to be inherited by members of a workspace.
-
-Specifying a workspace lint configuration is similar to package lints.
-
-Example:
-
-```toml
-# [PROJECT_DIR]/Cargo.toml
-[workspace]
-members = ["crates/*"]
-
-[workspace.lints.rust]
-unsafe = "forbid"
-```
-
-```toml
-# [PROJECT_DIR]/crates/bar/Cargo.toml
-[package]
-name = "bar"
-version = "0.1.0"
-
-[lints]
-workspace = true
-```
-
-## Stabilized and removed features
-
-### Compile progress
+## Compile progress
The compile-progress feature has been stabilized in the 1.30 release.
Progress bars are now enabled by default.
See [`term.progress`](config.md#termprogresswhen) for more information about
controlling this feature.
-### Edition
+## Edition
Specifying the `edition` in `Cargo.toml` has been stabilized in the 1.31 release.
See [the edition field](manifest.md#the-edition-field) for more information
about specifying this field.
-### rename-dependency
+## rename-dependency
Specifying renamed dependencies in `Cargo.toml` has been stabilized in the 1.31 release.
See [renaming dependencies](specifying-dependencies.md#renaming-dependencies-in-cargotoml)
for more information about renaming dependencies.
-### Alternate Registries
+## Alternate Registries
Support for alternate registries has been stabilized in the 1.34 release.
See the [Registries chapter](registries.md) for more information about alternate registries.
-### Offline Mode
+## Offline Mode
The offline feature has been stabilized in the 1.36 release.
See the [`--offline` flag](../commands/cargo.md#option-cargo---offline) for
more information on using the offline mode.
-### publish-lockfile
+## publish-lockfile
The `publish-lockfile` feature has been removed in the 1.37 release.
The `Cargo.lock` file is always included when a package is published if the
@@ -1735,19 +1312,19 @@ to use the `Cargo.lock` file.
See [`cargo package`](../commands/cargo-package.md) and
[`cargo install`](../commands/cargo-install.md) for more information.
-### default-run
+## default-run
The `default-run` feature has been stabilized in the 1.37 release.
See [the `default-run` field](manifest.md#the-default-run-field) for more
information about specifying the default target to run.
-### cache-messages
+## cache-messages
Compiler message caching has been stabilized in the 1.40 release.
Compiler warnings are now cached by default and will be replayed automatically
when re-running Cargo.
-### install-upgrade
+## install-upgrade
The `install-upgrade` feature has been stabilized in the 1.41 release.
[`cargo install`] will now automatically upgrade packages if they appear to be
@@ -1755,129 +1332,129 @@ out-of-date. See the [`cargo install`] documentation for more information.
[`cargo install`]: ../commands/cargo-install.md
-### Profile Overrides
+## Profile Overrides
Profile overrides have been stabilized in the 1.41 release.
See [Profile Overrides](profiles.md#overrides) for more information on using
overrides.
-### Config Profiles
+## Config Profiles
Specifying profiles in Cargo config files and environment variables has been
stabilized in the 1.43 release.
See the [config `[profile]` table](config.md#profile) for more information
about specifying [profiles](profiles.md) in config files.
-### crate-versions
+## crate-versions
The `-Z crate-versions` flag has been stabilized in the 1.47 release.
The crate version is now automatically included in the
[`cargo doc`](../commands/cargo-doc.md) documentation sidebar.
-### Features
+## Features
The `-Z features` flag has been stabilized in the 1.51 release.
See [feature resolver version 2](features.md#feature-resolver-version-2)
for more information on using the new feature resolver.
-### package-features
+## package-features
The `-Z package-features` flag has been stabilized in the 1.51 release.
See the [resolver version 2 command-line flags](features.md#resolver-version-2-command-line-flags)
for more information on using the features CLI options.
-### Resolver
+## Resolver
The `resolver` feature in `Cargo.toml` has been stabilized in the 1.51 release.
See the [resolver versions](resolver.md#resolver-versions) for more
information about specifying resolvers.
-### extra-link-arg
+## extra-link-arg
The `extra-link-arg` feature to specify additional linker arguments in build
scripts has been stabilized in the 1.56 release. See the [build script
documentation](build-scripts.md#outputs-of-the-build-script) for more
information on specifying extra linker arguments.
-### configurable-env
+## configurable-env
The `configurable-env` feature to specify environment variables in Cargo
configuration has been stabilized in the 1.56 release. See the [config
documentation](config.html#env) for more information about configuring
environment variables.
-### rust-version
+## rust-version
The `rust-version` field in `Cargo.toml` has been stabilized in the 1.56 release.
See the [rust-version field](manifest.html#the-rust-version-field) for more
information on using the `rust-version` field and the `--ignore-rust-version` option.
-### patch-in-config
+## patch-in-config
The `-Z patch-in-config` flag, and the corresponding support for
`[patch]` section in Cargo configuration files has been stabilized in
the 1.56 release. See the [patch field](config.html#patch) for more
information.
-### edition 2021
+## edition 2021
The 2021 edition has been stabilized in the 1.56 release.
See the [`edition` field](manifest.md#the-edition-field) for more information on setting the edition.
See [`cargo fix --edition`](../commands/cargo-fix.md) and [The Edition Guide](../../edition-guide/index.html) for more information on migrating existing projects.
-### Custom named profiles
+## Custom named profiles
Custom named profiles have been stabilized in the 1.57 release. See the
[profiles chapter](profiles.md#custom-profiles) for more information.
-### Profile `strip` option
+## Profile `strip` option
The profile `strip` option has been stabilized in the 1.59 release. See the
[profiles chapter](profiles.md#strip) for more information.
-### Future incompat report
+## Future incompat report
Support for generating a future-incompat report has been stabilized
in the 1.59 release. See the [future incompat report chapter](future-incompat-report.md)
for more information.
-### Namespaced features
+## Namespaced features
Namespaced features has been stabilized in the 1.60 release.
See the [Features chapter](features.md#optional-dependencies) for more information.
-### Weak dependency features
+## Weak dependency features
Weak dependency features has been stabilized in the 1.60 release.
See the [Features chapter](features.md#dependency-features) for more information.
-### timings
+## timings
The `-Ztimings` option has been stabilized as `--timings` in the 1.60 release.
(`--timings=html` and the machine-readable `--timings=json` output remain
unstable and require `-Zunstable-options`.)
-### config-cli
+## config-cli
The `--config` CLI option has been stabilized in the 1.63 release. See
the [config documentation](config.html#command-line-overrides) for more
information.
-### multitarget
+## multitarget
The `-Z multitarget` option has been stabilized in the 1.64 release.
See [`build.target`](config.md#buildtarget) for more information about
setting the default [target platform triples][target triple].
-### crate-type
+## crate-type
The `--crate-type` flag for `cargo rustc` has been stabilized in the 1.64
release. See the [`cargo rustc` documentation](../commands/cargo-rustc.md)
for more information.
-### Workspace Inheritance
+## Workspace Inheritance
Workspace Inheritance has been stabilized in the 1.64 release.
See [workspace.package](workspaces.md#the-package-table),
@@ -1885,27 +1462,50 @@ See [workspace.package](workspaces.md#the-package-table),
and [inheriting-a-dependency-from-a-workspace](specifying-dependencies.md#inheriting-a-dependency-from-a-workspace)
for more information.
-### terminal-width
+## terminal-width
The `-Z terminal-width` option has been stabilized in the 1.68 release.
The terminal width is always passed to the compiler when running from a
terminal where Cargo can automatically detect the width.
-### sparse-registry
+## sparse-registry
Sparse registry support has been stabilized in the 1.68 release.
See [Registry Protocols](registries.md#registry-protocols) for more information.
-#### `cargo logout`
+### `cargo logout`
The [`cargo logout`] command has been stabilized in the 1.70 release.
[target triple]: ../appendix/glossary.md#target '"target" (glossary)'
+[`cargo logout`]: ../commands/cargo-logout.md
-
-### `doctest-in-workspace`
+## `doctest-in-workspace`
The `-Z doctest-in-workspace` option for `cargo test` has been stabilized and
enabled by default in the 1.72 release. See the
[`cargo test` documentation](../commands/cargo-test.md#working-directory-of-tests)
for more information about the working directory for compiling and running tests.
+
+## keep-going
+
+The `--keep-going` option has been stabilized in the 1.74 release. See the
+[`--keep-going` flag](../commands/cargo-build.html#option-cargo-build---keep-going)
+in `cargo build` as an example for more details.
+
+## `[lints]`
+
+[`[lints]`](manifest.html#the-lints-section) (enabled via `-Zlints`) has been stabilized in the 1.74 release.
+
+## credential-process
+
+The `-Z credential-process` feature has been stabilized in the 1.74 release.
+
+See [Registry Authentication](registry-authentication.md) documentation for details.
+
+## registry-auth
+
+The `-Z registry-auth` feature has been stabilized in the 1.74 release with the additional
+requirement that a credential-provider is configured.
+
+See [Registry Authentication](registry-authentication.md) documentation for details.
diff --git a/src/tools/cargo/src/doc/src/reference/workspaces.md b/src/tools/cargo/src/doc/src/reference/workspaces.md
index 36a2e7323..17637d6c7 100644
--- a/src/tools/cargo/src/doc/src/reference/workspaces.md
+++ b/src/tools/cargo/src/doc/src/reference/workspaces.md
@@ -1,4 +1,4 @@
-## Workspaces
+# Workspaces
A *workspace* is a collection of one or more packages, called *workspace
members*, that are managed together.
@@ -24,12 +24,13 @@ In the `Cargo.toml`, the `[workspace]` table supports the following sections:
* [`default-members`](#the-default-members-field) --- Packages to operate on when a specific package wasn't selected.
* [`package`](#the-package-table) --- Keys for inheriting in packages.
* [`dependencies`](#the-dependencies-table) --- Keys for inheriting in package dependencies.
+ * [`lints`](#the-lints-table) --- Keys for inheriting in package lints.
* [`metadata`](#the-metadata-table) --- Extra settings for external tools.
* [`[patch]`](overriding-dependencies.md#the-patch-section) --- Override dependencies.
* [`[replace]`](overriding-dependencies.md#the-replace-section) --- Override dependencies (deprecated).
* [`[profile]`](profiles.md) --- Compiler settings and optimizations.
-### The `[workspace]` section
+## The `[workspace]` section
To create a workspace, you add the `[workspace]` table to a `Cargo.toml`:
```toml
@@ -40,7 +41,7 @@ To create a workspace, you add the `[workspace]` table to a `Cargo.toml`:
At minimum, a workspace has to have a member, either with a root package or as
a virtual manifest.
-#### Root package
+### Root package
If the [`[workspace]` section](#the-workspace-section) is added to a
`Cargo.toml` that already defines a `[package]`, the package is
@@ -56,7 +57,7 @@ version = "0.1.0" # the current version, obeying semver
authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
```
-#### Virtual workspace
+### Virtual workspace
Alternatively, a `Cargo.toml` file can be created with a `[workspace]` section
but without a [`[package]` section][package]. This is called a *virtual
@@ -84,7 +85,7 @@ should be specified manually. It is usually deduced from the [`package.edition`]
field which is absent in virtual manifests and the edition field of a member
won't affect the resolver used by the workspace.
-### The `members` and `exclude` fields
+## The `members` and `exclude` fields
The `members` and `exclude` fields define which packages are members of
the workspace:
@@ -114,7 +115,7 @@ manifest key can be used in member crates to point at a workspace's root to
override this automatic search. The manual setting can be useful if the member
is not inside a subdirectory of the workspace root.
-#### Package selection
+### Package selection
In a workspace, package-related Cargo commands like [`cargo build`] can use
the `-p` / `--package` or `--workspace` command-line flags to determine which
@@ -124,7 +125,7 @@ a [virtual workspace](#virtual-workspace), it will apply to all members (as if
`--workspace` were specified on the command-line). See also
[`default-members`](#the-default-members-field).
-### The `default-members` field
+## The `default-members` field
The optional `default-members` key can be specified to set the members to
operate on when in the workspace root and the package selection flags are not
@@ -138,7 +139,7 @@ default-members = ["path/to/member2", "path/to/member3/foo"]
When specified, `default-members` must expand to a subset of `members`.
-### The `package` table
+## The `package` table
The `workspace.package` table is where you define keys that can be
inherited by members of a workspace. These keys can be inherited by
@@ -183,7 +184,7 @@ description.workspace = true
documentation.workspace = true
```
-### The `dependencies` table
+## The `dependencies` table
The `workspace.dependencies` table is where you define dependencies to be
inherited by members of a workspace.
@@ -222,7 +223,34 @@ cc.workspace = true
rand.workspace = true
```
-### The `metadata` table
+## The `lints` table
+
+The `workspace.lints` table is where you define lint configuration to be inherited by members of a workspace.
+
+Specifying a workspace lint configuration is similar to package lints.
+
+Example:
+
+```toml
+# [PROJECT_DIR]/Cargo.toml
+[workspace]
+members = ["crates/*"]
+
+[workspace.lints.rust]
+unsafe_code = "forbid"
+```
+
+```toml
+# [PROJECT_DIR]/crates/bar/Cargo.toml
+[package]
+name = "bar"
+version = "0.1.0"
+
+[lints]
+workspace = true
+```
+
+## The `metadata` table
The `workspace.metadata` table is ignored by Cargo and will not be warned
about. This section can be used for tools that would like to store workspace
diff --git a/src/tools/cargo/src/etc/_cargo b/src/tools/cargo/src/etc/_cargo
index 164d7679f..7fb335252 100644
--- a/src/tools/cargo/src/etc/_cargo
+++ b/src/tools/cargo/src/etc/_cargo
@@ -342,9 +342,11 @@ _cargo() {
update)
_arguments -s -S $common $manifest \
'--aggressive=[force dependency update]' \
+ '--recursive=[force dependency update]' \
"--dry-run[don't actually write the lockfile]" \
'(-p --package)'{-p+,--package=}'[specify package to update]:package:_cargo_package_names' \
- '--precise=[update single dependency to precise release]:release'
+ '--precise=[update single dependency to precise release]:release' \
+ '*:package:_cargo_package_names'
;;
verify-project)
@@ -406,9 +408,15 @@ _cargo_cmds() {
}
_cargo_target_triple() {
- local -a targets
- targets=( ${(f)"$(rustc --print target-list)"} )
- _describe 'target triple' targets
+ local -a result
+
+ if (( $+commands[rustup] )); then
+ result=( ${(f)"$(rustup target list --installed)"} )
+ else
+ result=( ${(f)"$(rustc --print target-list)"} )
+ fi
+
+ _describe 'target triple' result
}
#FIXME: Disabled until fixed
diff --git a/src/tools/cargo/src/etc/cargo.bashcomp.sh b/src/tools/cargo/src/etc/cargo.bashcomp.sh
index 33f225ebf..a1e800bc3 100644
--- a/src/tools/cargo/src/etc/cargo.bashcomp.sh
+++ b/src/tools/cargo/src/etc/cargo.bashcomp.sh
@@ -87,7 +87,7 @@ _cargo()
local opt__t="$opt__test"
local opt__tree="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock --target -i --invert --prefix --no-dedupe --duplicates -d --charset -f --format -e --edges"
local opt__uninstall="$opt_common $opt_lock $opt_pkg --bin --root"
- local opt__update="$opt_common $opt_mani $opt_lock $opt_pkg --aggressive --precise --dry-run"
+ local opt__update="$opt_common $opt_mani $opt_lock $opt_pkg --aggressive --recursive --precise --dry-run"
local opt__vendor="$opt_common $opt_mani $opt_lock $opt_sync --no-delete --respect-source-config --versioned-dirs"
local opt__verify_project="$opt_common $opt_mani $opt_lock"
local opt__version="$opt_common $opt_lock"
@@ -250,15 +250,11 @@ _get_examples(){
}
_get_targets(){
- local result=()
- local targets=$(rustup target list)
- while read line
- do
- if [[ "$line" =~ default|installed ]]; then
- result+=("${line%% *}")
- fi
- done <<< "$targets"
- echo "${result[@]}"
+ if command -v rustup >/dev/null 2>/dev/null; then
+ rustup target list --installed
+ else
+ rustc --print target-list
+ fi
}
_toolchains(){
diff --git a/src/tools/cargo/src/etc/man/cargo-bench.1 b/src/tools/cargo/src/etc/man/cargo-bench.1
index 993dd3415..64498c4d6 100644
--- a/src/tools/cargo/src/etc/man/cargo-bench.1
+++ b/src/tools/cargo/src/etc/man/cargo-bench.1
@@ -502,11 +502,16 @@ a string \fBdefault\fR is provided, it sets the value back to defaults.
Should not be 0.
.RE
.sp
-\fB\-\-keep\-going\fR
+While \fBcargo bench\fR involves compilation, it does not provide a \fB\-\-keep\-going\fR
+flag. Use \fB\-\-no\-fail\-fast\fR to run as many benchmarks as possible without
+stopping at the first failure. To \[lq]compile\[rq] as many benchmarks as possible, use
+\fB\-\-benches\fR to build benchmark binaries separately. For example:
+.sp
.RS 4
-Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+.nf
+cargo build \-\-benches \-\-release \-\-keep\-going
+cargo bench \-\-no\-fail\-fast
+.fi
.RE
.SH "ENVIRONMENT"
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
diff --git a/src/tools/cargo/src/etc/man/cargo-build.1 b/src/tools/cargo/src/etc/man/cargo-build.1
index 4ee6a0d76..6bcfe8093 100644
--- a/src/tools/cargo/src/etc/man/cargo-build.1
+++ b/src/tools/cargo/src/etc/man/cargo-build.1
@@ -420,8 +420,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo build \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo build \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.sp
\fB\-\-future\-incompat\-report\fR
diff --git a/src/tools/cargo/src/etc/man/cargo-check.1 b/src/tools/cargo/src/etc/man/cargo-check.1
index 1aada2a21..fdbb84647 100644
--- a/src/tools/cargo/src/etc/man/cargo-check.1
+++ b/src/tools/cargo/src/etc/man/cargo-check.1
@@ -401,8 +401,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo check \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo check \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.sp
\fB\-\-future\-incompat\-report\fR
diff --git a/src/tools/cargo/src/etc/man/cargo-clean.1 b/src/tools/cargo/src/etc/man/cargo-clean.1
index 3cb321f05..d71b0e027 100644
--- a/src/tools/cargo/src/etc/man/cargo-clean.1
+++ b/src/tools/cargo/src/etc/man/cargo-clean.1
@@ -25,6 +25,12 @@ multiple times. See \fBcargo\-pkgid\fR(1) for the SPEC format.
.RE
.SS "Clean Options"
.sp
+\fB\-\-dry\-run\fR
+.RS 4
+Displays a summary of what would be deleted without deleting anything.
+Use with \fB\-\-verbose\fR to display the actual files that would be deleted.
+.RE
+.sp
\fB\-\-doc\fR
.RS 4
This option will cause \fBcargo clean\fR to remove only the \fBdoc\fR directory in
diff --git a/src/tools/cargo/src/etc/man/cargo-doc.1 b/src/tools/cargo/src/etc/man/cargo-doc.1
index 24621e9f6..2bdd8867b 100644
--- a/src/tools/cargo/src/etc/man/cargo-doc.1
+++ b/src/tools/cargo/src/etc/man/cargo-doc.1
@@ -368,8 +368,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo doc \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo doc \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.SH "ENVIRONMENT"
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
diff --git a/src/tools/cargo/src/etc/man/cargo-fix.1 b/src/tools/cargo/src/etc/man/cargo-fix.1
index 7f2a34cda..61083f214 100644
--- a/src/tools/cargo/src/etc/man/cargo-fix.1
+++ b/src/tools/cargo/src/etc/man/cargo-fix.1
@@ -496,8 +496,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo fix \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo fix \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.SH "ENVIRONMENT"
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
diff --git a/src/tools/cargo/src/etc/man/cargo-install.1 b/src/tools/cargo/src/etc/man/cargo-install.1
index 917c0d0e1..5ca3180fd 100644
--- a/src/tools/cargo/src/etc/man/cargo-install.1
+++ b/src/tools/cargo/src/etc/man/cargo-install.1
@@ -346,8 +346,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo install \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo install \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.SS "Display Options"
.sp
diff --git a/src/tools/cargo/src/etc/man/cargo-login.1 b/src/tools/cargo/src/etc/man/cargo-login.1
index 1ae1cc626..92b3b3f3c 100644
--- a/src/tools/cargo/src/etc/man/cargo-login.1
+++ b/src/tools/cargo/src/etc/man/cargo-login.1
@@ -4,14 +4,21 @@
.ad l
.ss \n[.ss] 0
.SH "NAME"
-cargo\-login \[em] Save an API token from the registry locally
+cargo\-login \[em] Log in to a registry
.SH "SYNOPSIS"
-\fBcargo login\fR [\fIoptions\fR] [\fItoken\fR]
+\fBcargo login\fR [\fIoptions\fR] [\fItoken\fR] \[en] [\fIargs\fR]
.SH "DESCRIPTION"
-This command will save the API token to disk so that commands that require
-authentication, such as \fBcargo\-publish\fR(1), will be automatically
-authenticated. The token is saved in \fB$CARGO_HOME/credentials.toml\fR\&. \fBCARGO_HOME\fR
-defaults to \fB\&.cargo\fR in your home directory.
+This command will run a credential provider to save a token so that commands
+that require authentication, such as \fBcargo\-publish\fR(1), will be
+automatically authenticated.
+.sp
+For the default \fBcargo:token\fR credential provider, the token is saved
+in \fB$CARGO_HOME/credentials.toml\fR\&. \fBCARGO_HOME\fR defaults to \fB\&.cargo\fR
+in your home directory.
+.sp
+If a registry has a credential\-provider specified, it will be used. Otherwise,
+the providers from the config value \fBregistry.global\-credential\-providers\fR will
+be attempted, starting from the end of the list.
.sp
If the \fItoken\fR argument is not specified, it will be read from stdin.
.sp
@@ -123,7 +130,7 @@ details on environment variables that Cargo reads.
.SH "EXAMPLES"
.sp
.RS 4
-\h'-04' 1.\h'+01'Save the API token to disk:
+\h'-04' 1.\h'+01'Save the token for the default registry:
.sp
.RS 4
.nf
@@ -131,5 +138,15 @@ cargo login
.fi
.RE
.RE
+.sp
+.RS 4
+\h'-04' 2.\h'+01'Save the token for a specific registry:
+.sp
+.RS 4
+.nf
+cargo login \-\-registry my\-registry
+.fi
+.RE
+.RE
.SH "SEE ALSO"
\fBcargo\fR(1), \fBcargo\-logout\fR(1), \fBcargo\-publish\fR(1)
diff --git a/src/tools/cargo/src/etc/man/cargo-logout.1 b/src/tools/cargo/src/etc/man/cargo-logout.1
index 7333cc62c..8d73e12a4 100644
--- a/src/tools/cargo/src/etc/man/cargo-logout.1
+++ b/src/tools/cargo/src/etc/man/cargo-logout.1
@@ -8,9 +8,15 @@ cargo\-logout \[em] Remove an API token from the registry locally
.SH "SYNOPSIS"
\fBcargo logout\fR [\fIoptions\fR]
.SH "DESCRIPTION"
-This command will remove the API token from the local credential storage.
-Credentials are stored in \fB$CARGO_HOME/credentials.toml\fR where \fB$CARGO_HOME\fR
-defaults to \fB\&.cargo\fR in your home directory.
+This command will run a credential provider to remove a saved token.
+.sp
+For the default \fBcargo:token\fR credential provider, credentials are stored
+in \fB$CARGO_HOME/credentials.toml\fR where \fB$CARGO_HOME\fR defaults to \fB\&.cargo\fR
+in your home directory.
+.sp
+If a registry has a credential\-provider specified, it will be used. Otherwise,
+the providers from the config value \fBregistry.global\-credential\-providers\fR will
+be attempted, starting from the end of the list.
.sp
If \fB\-\-registry\fR is not specified, then the credentials for the default
registry will be removed (configured by
diff --git a/src/tools/cargo/src/etc/man/cargo-metadata.1 b/src/tools/cargo/src/etc/man/cargo-metadata.1
index 95597d413..c1195c232 100644
--- a/src/tools/cargo/src/etc/man/cargo-metadata.1
+++ b/src/tools/cargo/src/etc/man/cargo-metadata.1
@@ -22,7 +22,7 @@ for a Rust API for reading the metadata.
.SS "Compatibility"
Within the same output format version, the compatibility is maintained, except
some scenarios. The following is a non\-exhaustive list of changes that are not
-considersed as incompatibile:
+considersed as incompatible:
.sp
.RS 4
\h'-04'\(bu\h'+02'\fBAdding new fields\fR \[em] New fields will be added when needed. Reserving this
diff --git a/src/tools/cargo/src/etc/man/cargo-package.1 b/src/tools/cargo/src/etc/man/cargo-package.1
index 8a7b1c191..f845cbc04 100644
--- a/src/tools/cargo/src/etc/man/cargo-package.1
+++ b/src/tools/cargo/src/etc/man/cargo-package.1
@@ -242,8 +242,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo package \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo package \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.SS "Display Options"
.sp
diff --git a/src/tools/cargo/src/etc/man/cargo-publish.1 b/src/tools/cargo/src/etc/man/cargo-publish.1
index d18f9e690..b2d95b9fd 100644
--- a/src/tools/cargo/src/etc/man/cargo-publish.1
+++ b/src/tools/cargo/src/etc/man/cargo-publish.1
@@ -27,8 +27,14 @@ which registries you are allowed to publish to.
.RE
.sp
.RS 4
-\h'-04' 3.\h'+01'Upload the crate to the registry. Note that the server will perform
-additional checks on the crate.
+\h'-04' 3.\h'+01'Upload the crate to the registry. The server will perform additional
+checks on the crate.
+.RE
+.sp
+.RS 4
+\h'-04' 4.\h'+01'The client will poll waiting for the package to appear in the index,
+and may timeout. In that case, you will need to check for completion
+manually. This timeout does not affect the upload.
.RE
.sp
This command requires you to be authenticated with either the \fB\-\-token\fR option
@@ -192,8 +198,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo publish \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo publish \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.SS "Display Options"
.sp
diff --git a/src/tools/cargo/src/etc/man/cargo-run.1 b/src/tools/cargo/src/etc/man/cargo-run.1
index 1c182ad1a..293814674 100644
--- a/src/tools/cargo/src/etc/man/cargo-run.1
+++ b/src/tools/cargo/src/etc/man/cargo-run.1
@@ -305,8 +305,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo run \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo run \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.SH "ENVIRONMENT"
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
diff --git a/src/tools/cargo/src/etc/man/cargo-rustc.1 b/src/tools/cargo/src/etc/man/cargo-rustc.1
index 50df99656..501e9208e 100644
--- a/src/tools/cargo/src/etc/man/cargo-rustc.1
+++ b/src/tools/cargo/src/etc/man/cargo-rustc.1
@@ -419,8 +419,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo rustc \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo rustc \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.sp
\fB\-\-future\-incompat\-report\fR
diff --git a/src/tools/cargo/src/etc/man/cargo-rustdoc.1 b/src/tools/cargo/src/etc/man/cargo-rustdoc.1
index 1792c6e2f..0335d6e54 100644
--- a/src/tools/cargo/src/etc/man/cargo-rustdoc.1
+++ b/src/tools/cargo/src/etc/man/cargo-rustdoc.1
@@ -387,8 +387,13 @@ Should not be 0.
\fB\-\-keep\-going\fR
.RS 4
Build as many crates in the dependency graph as possible, rather than aborting
-the build on the first one that fails to build. Unstable, requires
-\fB\-Zunstable\-options\fR\&.
+the build on the first one that fails to build.
+.sp
+For example if the current package depends on dependencies \fBfails\fR and \fBworks\fR,
+one of which fails to build, \fBcargo rustdoc \-j1\fR may or may not build the
+one that succeeds (depending on which one of the two builds Cargo picked to run
+first), whereas \fBcargo rustdoc \-j1 \-\-keep\-going\fR would definitely run both
+builds, even if the one run first fails.
.RE
.SH "ENVIRONMENT"
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
diff --git a/src/tools/cargo/src/etc/man/cargo-test.1 b/src/tools/cargo/src/etc/man/cargo-test.1
index 4ca150dbc..8e460e167 100644
--- a/src/tools/cargo/src/etc/man/cargo-test.1
+++ b/src/tools/cargo/src/etc/man/cargo-test.1
@@ -542,6 +542,18 @@ produced during execution of this command
.sp
See \fBcargo\-report\fR(1)
.RE
+.sp
+While \fBcargo test\fR involves compilation, it does not provide a \fB\-\-keep\-going\fR
+flag. Use \fB\-\-no\-fail\-fast\fR to run as many tests as possible without stopping at
+the first failure. To \[lq]compile\[rq] as many tests as possible, use \fB\-\-tests\fR to
+build test binaries separately. For example:
+.sp
+.RS 4
+.nf
+cargo build \-\-tests \-\-keep\-going
+cargo test \-\-tests \-\-no\-fail\-fast
+.fi
+.RE
.SH "ENVIRONMENT"
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
details on environment variables that Cargo reads.
diff --git a/src/tools/cargo/src/etc/man/cargo-update.1 b/src/tools/cargo/src/etc/man/cargo-update.1
index 6f697b3ab..c9fe881c8 100644
--- a/src/tools/cargo/src/etc/man/cargo-update.1
+++ b/src/tools/cargo/src/etc/man/cargo-update.1
@@ -6,7 +6,7 @@
.SH "NAME"
cargo\-update \[em] Update dependencies as recorded in the local lock file
.SH "SYNOPSIS"
-\fBcargo update\fR [\fIoptions\fR]
+\fBcargo update\fR [\fIoptions\fR] \fIspec\fR
.SH "DESCRIPTION"
This command will update dependencies in the \fBCargo.lock\fR file to the latest
version. If the \fBCargo.lock\fR file does not exist, it will be created with the
@@ -14,30 +14,29 @@ latest available versions.
.SH "OPTIONS"
.SS "Update Options"
.sp
-\fB\-p\fR \fIspec\fR\[u2026],
-\fB\-\-package\fR \fIspec\fR\[u2026]
+\fIspec\fR\[u2026]
.RS 4
Update only the specified packages. This flag may be specified
multiple times. See \fBcargo\-pkgid\fR(1) for the SPEC format.
.sp
-If packages are specified with the \fB\-p\fR flag, then a conservative update of
+If packages are specified with \fIspec\fR, then a conservative update of
the lockfile will be performed. This means that only the dependency specified
by SPEC will be updated. Its transitive dependencies will be updated only if
SPEC cannot be updated without updating dependencies. All other dependencies
will remain locked at their currently recorded versions.
.sp
-If \fB\-p\fR is not specified, all dependencies are updated.
+If \fIspec\fR is not specified, all dependencies are updated.
.RE
.sp
-\fB\-\-aggressive\fR
+\fB\-\-recursive\fR
.RS 4
-When used with \fB\-p\fR, dependencies of \fIspec\fR are forced to update as well.
+When used with \fIspec\fR, dependencies of \fIspec\fR are forced to update as well.
Cannot be used with \fB\-\-precise\fR\&.
.RE
.sp
\fB\-\-precise\fR \fIprecise\fR
.RS 4
-When used with \fB\-p\fR, allows you to specify a specific version number to set
+When used with \fIspec\fR, allows you to specify a specific version number to set
the package to. If the package comes from a git repository, this can be a git
revision (such as a SHA hash or tag).
.RE
@@ -200,7 +199,7 @@ cargo update
.sp
.RS 4
.nf
-cargo update \-p foo \-p bar
+cargo update foo bar
.fi
.RE
.RE
@@ -210,7 +209,7 @@ cargo update \-p foo \-p bar
.sp
.RS 4
.nf
-cargo update \-p foo \-\-precise 1.2.3
+cargo update foo \-\-precise 1.2.3
.fi
.RE
.RE
diff --git a/src/tools/cargo/tests/testsuite/alt_registry.rs b/src/tools/cargo/tests/testsuite/alt_registry.rs
index 91157cd53..d6d7dd531 100644
--- a/src/tools/cargo/tests/testsuite/alt_registry.rs
+++ b/src/tools/cargo/tests/testsuite/alt_registry.rs
@@ -1389,10 +1389,9 @@ fn both_index_and_registry() {
p.cargo(cmd)
.arg("--registry=foo")
.arg("--index=foo")
- .with_status(101)
- .with_stderr(
- "[ERROR] both `--index` and `--registry` \
- should not be set at the same time",
+ .with_status(1)
+ .with_stderr_contains(
+ "error: the argument '--registry <REGISTRY>' cannot be used with '--index <INDEX>'",
)
.run();
}
diff --git a/src/tools/cargo/tests/testsuite/artifact_dep.rs b/src/tools/cargo/tests/testsuite/artifact_dep.rs
index 08e413bf5..64aa9d8af 100644
--- a/src/tools/cargo/tests/testsuite/artifact_dep.rs
+++ b/src/tools/cargo/tests/testsuite/artifact_dep.rs
@@ -1445,13 +1445,7 @@ foo v0.0.0 ([CWD])
)
.run();
}
-
-// TODO: Fix this potentially by reverting 887562bfeb8c540594d7d08e6e9a4ab7eb255865 which adds artifact information to the registry
-// followed by 0ff93733626f7cbecaf9dce9ab62b4ced0be088e which picks it up.
-// For reference, see comments by ehuss https://github.com/rust-lang/cargo/pull/9992#discussion_r801086315 and
-// joshtriplett https://github.com/rust-lang/cargo/pull/9992#issuecomment-1033394197 .
#[cargo_test]
-#[ignore = "broken, need artifact info in index"]
fn targets_are_picked_up_from_non_workspace_artifact_deps() {
if cross_compile::disabled() {
return;
@@ -1464,6 +1458,7 @@ fn targets_are_picked_up_from_non_workspace_artifact_deps() {
let mut dep = registry::Dependency::new("artifact", "1.0.0");
Package::new("uses-artifact", "1.0.0")
+ .schema_version(3)
.file(
"src/lib.rs",
r#"pub fn uses_artifact() { let _b = include_bytes!(env!("CARGO_BIN_FILE_ARTIFACT")); }"#,
@@ -1496,6 +1491,127 @@ fn targets_are_picked_up_from_non_workspace_artifact_deps() {
}
#[cargo_test]
+fn index_version_filtering() {
+ if cross_compile::disabled() {
+ return;
+ }
+ let target = cross_compile::alternate();
+
+ Package::new("artifact", "1.0.0")
+ .file("src/main.rs", r#"fn main() {}"#)
+ .file("src/lib.rs", r#"pub fn lib() {}"#)
+ .publish();
+
+ let mut dep = registry::Dependency::new("artifact", "1.0.0");
+
+ Package::new("bar", "1.0.0").publish();
+ Package::new("bar", "1.0.1")
+ .schema_version(3)
+ .add_dep(dep.artifact("bin", Some(target.to_string())))
+ .publish();
+
+ // Verify that without `-Zbindeps` that it does not use 1.0.1.
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bar = "1.0"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("tree")
+ .with_stdout("foo v0.1.0 [..]\n└── bar v1.0.0")
+ .run();
+
+ // And with -Zbindeps it can use 1.0.1.
+ p.cargo("update -Zbindeps")
+ .masquerade_as_nightly_cargo(&["bindeps"])
+ .with_stderr(
+ "\
+[UPDATING] [..]
+[ADDING] artifact v1.0.0
+[UPDATING] bar v1.0.0 -> v1.0.1",
+ )
+ .run();
+
+ // And without -Zbindeps, now that 1.0.1 is in Cargo.lock, it should fail.
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[UPDATING] [..]
+error: failed to select a version for the requirement `bar = \"^1.0\"` (locked to 1.0.1)
+candidate versions found which didn't match: 1.0.0
+location searched: [..]
+required by package `foo v0.1.0 [..]`
+perhaps a crate was updated and forgotten to be re-vendored?",
+ )
+ .run();
+}
+
+// FIXME: `download_accessible` should work properly for artifact dependencies
+#[cargo_test]
+#[ignore = "broken, needs download_accessible fix"]
+fn proc_macro_in_artifact_dep() {
+ // Forcing FeatureResolver to check a proc-macro for a dependency behind a
+ // target dependency.
+ if cross_compile::disabled() {
+ return;
+ }
+ Package::new("pm", "1.0.0")
+ .file("src/lib.rs", "")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "pm"
+ version = "1.0.0"
+
+ [lib]
+ proc-macro = true
+
+ "#,
+ )
+ .publish();
+ let alternate = cross_compile::alternate();
+ Package::new("bin-uses-pm", "1.0.0")
+ .target_dep("pm", "1.0", alternate)
+ .file("src/main.rs", "fn main() {}")
+ .publish();
+ // Simulate a network error downloading the proc-macro.
+ std::fs::remove_file(cargo_test_support::paths::root().join("dl/pm/1.0.0/download")).unwrap();
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ edition = "2021"
+
+ [dependencies]
+ bin-uses-pm = {{ version = "1.0", artifact = "bin", target = "{alternate}"}}
+ "#
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check -Z bindeps")
+ .masquerade_as_nightly_cargo(&["bindeps"])
+ .with_stderr("")
+ .run();
+}
+
+#[cargo_test]
fn allow_dep_renames_with_multiple_versions() {
Package::new("bar", "1.0.0")
.file("src/main.rs", r#"fn main() {println!("1.0.0")}"#)
@@ -1926,15 +2042,23 @@ You may press ctrl-c [..]
"badges": {},
"categories": [],
"deps": [{
+ "artifact": ["bin"],
"default_features": true,
"features": [],
"kind": "normal",
+ "lib": true,
"name": "bar",
"optional": false,
"target": null,
"version_req": "^1.0"
},
{
+ "artifact": [
+ "bin:a",
+ "cdylib",
+ "staticlib"
+ ],
+ "bindep_target": "target",
"default_features": true,
"features": [],
"kind": "build",
@@ -2894,8 +3018,8 @@ fn check_transitive_artifact_dependency_with_different_target() {
p.cargo("check -Z bindeps")
.masquerade_as_nightly_cargo(&["bindeps"])
.with_stderr_contains(
- "error: could not find specification for target `custom-target`.\n \
- Dependency `baz v0.0.0 [..]` requires to build for target `custom-target`.",
+ "error: failed to determine target information for target `custom-target`.\n \
+ Artifact dependency `baz` in package `bar v0.0.0 [..]` requires building for `custom-target`",
)
.with_status(101)
.run();
diff --git a/src/tools/cargo/tests/testsuite/bad_config.rs b/src/tools/cargo/tests/testsuite/bad_config.rs
index 4434ea90d..82da880ea 100644
--- a/src/tools/cargo/tests/testsuite/bad_config.rs
+++ b/src/tools/cargo/tests/testsuite/bad_config.rs
@@ -172,9 +172,6 @@ Caused by:
could not parse TOML configuration in `[..]`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 1, column 2
|
1 | 4
@@ -199,8 +196,11 @@ fn bad_cargo_lock() {
[ERROR] failed to parse lock file at: [..]Cargo.lock
Caused by:
+ TOML parse error at line 1, column 1
+ |
+ 1 | [[package]]
+ | ^^^^^^^^^^^
missing field `name`
- in `package`
",
)
.run();
@@ -303,8 +303,11 @@ fn bad_source_in_cargo_lock() {
[ERROR] failed to parse lock file at: [..]
Caused by:
+ TOML parse error at line 12, column 26
+ |
+ 12 | source = \"You shall not parse\"
+ | ^^^^^^^^^^^^^^^^^^^^^
invalid source `You shall not parse`
- in `package.source`
",
)
.run();
@@ -449,9 +452,6 @@ fn malformed_override() {
[ERROR] failed to parse manifest at `[..]`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 8, column 27
|
8 | native = {
@@ -804,9 +804,6 @@ Caused by:
could not parse TOML configuration in `[..]`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 1, column 7
|
1 | [bar] baz = 2
@@ -1288,8 +1285,11 @@ fn bad_dependency() {
error: failed to parse manifest at `[..]`
Caused by:
+ TOML parse error at line 8, column 23
+ |
+ 8 | bar = 3
+ | ^
invalid type: integer `3`, expected a version string like [..]
- in `dependencies.bar`
",
)
.run();
@@ -1320,8 +1320,11 @@ fn bad_debuginfo() {
error: failed to parse manifest [..]
Caused by:
+ TOML parse error at line 8, column 25
+ |
+ 8 | debug = 'a'
+ | ^^^
invalid value: string \"a\", expected a boolean, 0, 1, 2, \"line-tables-only\", or \"line-directives-only\"
- in `profile.dev.debug`
",
)
.run();
@@ -1352,8 +1355,11 @@ fn bad_debuginfo2() {
error: failed to parse manifest at `[..]`
Caused by:
+ TOML parse error at line 8, column 25
+ |
+ 8 | debug = 3.6
+ | ^^^
invalid type: floating point `3.6`, expected a boolean, 0, 1, 2, \"line-tables-only\", or \"line-directives-only\"
- in `profile.dev.debug`
",
)
.run();
@@ -1382,8 +1388,11 @@ fn bad_opt_level() {
error: failed to parse manifest at `[..]`
Caused by:
- expected a boolean or a string
- in `package.build`
+ TOML parse error at line 6, column 25
+ |
+ 6 | build = 3
+ | ^
+ invalid type: integer `3`, expected a boolean or string
",
)
.run();
@@ -1412,6 +1421,117 @@ fn warn_semver_metadata() {
}
#[cargo_test]
+fn bad_http_ssl_version() {
+ // Invalid type in SslVersionConfig.
+ let p = project()
+ .file(
+ ".cargo/config.toml",
+ r#"
+ [http]
+ ssl-version = ["tlsv1.2", "tlsv1.3"]
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[ERROR] error in [..]/config.toml: could not load config key `http.ssl-version`
+
+Caused by:
+ invalid type: sequence, expected a string or map
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn bad_http_ssl_version_range() {
+ // Invalid type in SslVersionConfigRange.
+ let p = project()
+ .file(
+ ".cargo/config.toml",
+ r#"
+ [http]
+ ssl-version.min = false
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[ERROR] error in [..]/config.toml: could not load config key `http.ssl-version`
+
+Caused by:
+ error in [..]/config.toml: `http.ssl-version.min` expected a string, but found a boolean
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn bad_build_jobs() {
+ // Invalid type in JobsConfig.
+ let p = project()
+ .file(
+ ".cargo/config.toml",
+ r#"
+ [build]
+ jobs = { default = true }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[ERROR] error in [..]/config.toml: could not load config key `build.jobs`
+
+Caused by:
+ invalid type: map, expected an integer or string
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn bad_build_target() {
+ // Invalid type in BuildTargetConfig.
+ let p = project()
+ .file(
+ ".cargo/config.toml",
+ r#"
+ [build]
+ target.'cfg(unix)' = "x86_64"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[ERROR] error in [..]/config.toml: could not load config key `build.target`
+
+Caused by:
+ error in [..]/config.toml: could not load config key `build.target`
+
+Caused by:
+ invalid type: map, expected a string or array
+",
+ )
+ .run();
+}
+
+#[cargo_test]
fn bad_target_cfg() {
// Invalid type in a StringList.
//
diff --git a/src/tools/cargo/tests/testsuite/bench.rs b/src/tools/cargo/tests/testsuite/bench.rs
index d773308c6..01017e857 100644
--- a/src/tools/cargo/tests/testsuite/bench.rs
+++ b/src/tools/cargo/tests/testsuite/bench.rs
@@ -1671,24 +1671,6 @@ fn json_artifact_includes_executable_for_benchmark() {
.run();
}
-#[cargo_test]
-fn cargo_bench_no_keep_going() {
- let p = project()
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/main.rs", "")
- .build();
-
- p.cargo("bench --keep-going")
- .with_stderr(
- "\
-error: unexpected argument `--keep-going` found
-
- tip: to run as many benchmarks as possible without failing fast, use `--no-fail-fast`",
- )
- .with_status(101)
- .run();
-}
-
#[cargo_test(nightly, reason = "bench")]
fn cargo_bench_print_env_verbose() {
let p = project()
diff --git a/src/tools/cargo/tests/testsuite/build.rs b/src/tools/cargo/tests/testsuite/build.rs
index 8cb064a6f..1afa83918 100644
--- a/src/tools/cargo/tests/testsuite/build.rs
+++ b/src/tools/cargo/tests/testsuite/build.rs
@@ -136,6 +136,29 @@ fn incremental_config() {
}
#[cargo_test]
+fn cargo_compile_with_redundant_default_mode() {
+ let p = project()
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
+ .build();
+
+ p.cargo("build --debug")
+ .with_stderr(
+ "\
+error: unexpected argument '--debug' found
+
+ tip: `--debug` is the default for `cargo build`; instead `--release` is supported
+
+Usage: cargo[EXE] build [OPTIONS]
+
+For more information, try '--help'.
+",
+ )
+ .with_status(1)
+ .run();
+}
+
+#[cargo_test]
fn cargo_compile_with_workspace_excluded() {
let p = project().file("src/main.rs", "fn main() {}").build();
@@ -259,9 +282,6 @@ fn cargo_compile_with_invalid_manifest2() {
[ERROR] failed to parse manifest at `[..]`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 3, column 23
|
3 | foo = bar
@@ -284,9 +304,6 @@ fn cargo_compile_with_invalid_manifest3() {
[ERROR] failed to parse manifest at `[..]`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 1, column 5
|
1 | a = bar
@@ -346,8 +363,11 @@ fn cargo_compile_with_invalid_version() {
[ERROR] failed to parse manifest at `[..]`
Caused by:
+ TOML parse error at line 4, column 19
+ |
+ 4 | version = \"1.0\"
+ | ^^^^^
unexpected end of input while parsing minor version number
- in `package.version`
",
)
.run();
@@ -3036,9 +3056,6 @@ Caused by:
could not parse TOML configuration in `[..]`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 1, column 6
|
1 | this is not valid toml
diff --git a/src/tools/cargo/tests/testsuite/build_script.rs b/src/tools/cargo/tests/testsuite/build_script.rs
index 400d10547..0ccbb4e27 100644
--- a/src/tools/cargo/tests/testsuite/build_script.rs
+++ b/src/tools/cargo/tests/testsuite/build_script.rs
@@ -453,6 +453,43 @@ fn custom_build_env_var_rustc_linker() {
p.cargo("build --target").arg(&target).run();
}
+// Only run this test on linux, since it's difficult to construct
+// a case suitable for all platforms.
+// See:https://github.com/rust-lang/cargo/pull/12535#discussion_r1306618264
+#[cargo_test]
+#[cfg(target_os = "linux")]
+fn custom_build_env_var_rustc_linker_with_target_cfg() {
+ if cross_compile::disabled() {
+ return;
+ }
+
+ let target = cross_compile::alternate();
+ let p = project()
+ .file(
+ ".cargo/config",
+ r#"
+ [target.'cfg(target_pointer_width = "32")']
+ linker = "/path/to/linker"
+ "#,
+ )
+ .file(
+ "build.rs",
+ r#"
+ use std::env;
+
+ fn main() {
+ assert!(env::var("RUSTC_LINKER").unwrap().ends_with("/path/to/linker"));
+ }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ // no crate type set => linker never called => build succeeds if and
+ // only if build.rs succeeds, despite linker binary not existing.
+ p.cargo("build --target").arg(&target).run();
+}
+
#[cargo_test]
fn custom_build_env_var_rustc_linker_bad_host_target() {
let target = rustc_host();
diff --git a/src/tools/cargo/tests/testsuite/cargo/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo/help/stdout.log
index 26bcd745b..e15848ab7 100644
--- a/src/tools/cargo/tests/testsuite/cargo/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo/help/stdout.log
@@ -6,7 +6,7 @@ Usage: cargo [..][OPTIONS] [COMMAND]
Options:
-V, --version Print version info and exit
--list List installed commands
- --explain <CODE> Run `rustc --explain CODE`
+ --explain <CODE> Provide a detailed explanation of a rustc error message
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet Do not print cargo log messages
--color <WHEN> Coloring: auto, always, never
@@ -18,7 +18,7 @@ Options:
-Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
-h, --help Print help
-Some common cargo commands are (see all commands with --list):
+Commands:
build, b Compile the current package
check, c Analyze the current package and report errors, but don't build object files
clean Remove the target directory
@@ -35,5 +35,6 @@ Some common cargo commands are (see all commands with --list):
publish Package and upload this package to the registry
install Install a Rust binary. Default location is $HOME/.cargo/bin
uninstall Uninstall a Rust binary
+ ... See all commands with --list
See 'cargo help <command>' for more information on a specific command.
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/in/Cargo.toml
new file mode 100644
index 000000000..3ecdb6681
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/in/Cargo.toml
@@ -0,0 +1,5 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/README.md b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/in/src/lib.rs
index e69de29bb..e69de29bb 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/README.md
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/in/src/lib.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/mod.rs
new file mode 100644
index 000000000..467e9a681
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/mod.rs
@@ -0,0 +1,38 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::prelude::*;
+use cargo_test_support::Project;
+use itertools::Itertools;
+
+use cargo_test_support::curr_dir;
+
+#[cargo_test]
+fn case() {
+ const MANY_FEATURES_COUNT: usize = 200;
+ const ACTIVATED_FEATURES_COUNT: usize = 100;
+
+ cargo_test_support::registry::init();
+ let mut test_package =
+ cargo_test_support::registry::Package::new("your-face", "99999.0.0+my-package");
+ for i in 0..MANY_FEATURES_COUNT {
+ test_package.feature(format!("eyes{i:03}").as_str(), &[]);
+ }
+ test_package.publish();
+
+ let project = Project::from_template(curr_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = &project_root;
+
+ let features = (0..ACTIVATED_FEATURES_COUNT)
+ .map(|i| format!("eyes{i:03}"))
+ .join(",");
+ snapbox::cmd::Command::cargo_ui()
+ .arg("add")
+ .arg_line(format!("your-face --features {features}").as_str())
+ .current_dir(cwd)
+ .assert()
+ .success()
+ .stdout_matches_path(curr_dir!().join("stdout.log"))
+ .stderr_matches_path(curr_dir!().join("stderr.log"));
+
+ assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
+}
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/out/Cargo.toml
new file mode 100644
index 000000000..6c8c7e5a3
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/out/Cargo.toml
@@ -0,0 +1,8 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+
+[dependencies]
+your-face = { version = "99999.0.0", features = ["eyes000", "eyes001", "eyes002", "eyes003", "eyes004", "eyes005", "eyes006", "eyes007", "eyes008", "eyes009", "eyes010", "eyes011", "eyes012", "eyes013", "eyes014", "eyes015", "eyes016", "eyes017", "eyes018", "eyes019", "eyes020", "eyes021", "eyes022", "eyes023", "eyes024", "eyes025", "eyes026", "eyes027", "eyes028", "eyes029", "eyes030", "eyes031", "eyes032", "eyes033", "eyes034", "eyes035", "eyes036", "eyes037", "eyes038", "eyes039", "eyes040", "eyes041", "eyes042", "eyes043", "eyes044", "eyes045", "eyes046", "eyes047", "eyes048", "eyes049", "eyes050", "eyes051", "eyes052", "eyes053", "eyes054", "eyes055", "eyes056", "eyes057", "eyes058", "eyes059", "eyes060", "eyes061", "eyes062", "eyes063", "eyes064", "eyes065", "eyes066", "eyes067", "eyes068", "eyes069", "eyes070", "eyes071", "eyes072", "eyes073", "eyes074", "eyes075", "eyes076", "eyes077", "eyes078", "eyes079", "eyes080", "eyes081", "eyes082", "eyes083", "eyes084", "eyes085", "eyes086", "eyes087", "eyes088", "eyes089", "eyes090", "eyes091", "eyes092", "eyes093", "eyes094", "eyes095", "eyes096", "eyes097", "eyes098", "eyes099"] }
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/stderr.log
new file mode 100644
index 000000000..9288319aa
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/stderr.log
@@ -0,0 +1,5 @@
+ Updating `dummy-registry` index
+ Adding your-face v99999.0.0 to dependencies.
+ Features:
+ 100 activated features
+ 100 deactivated features
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/stdout.log
index e69de29bb..e69de29bb 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_activated_over_limit/stdout.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/Cargo.toml
new file mode 100644
index 000000000..3ecdb6681
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/Cargo.toml
@@ -0,0 +1,5 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/src/lib.rs
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/in/src/lib.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/mod.rs
new file mode 100644
index 000000000..b2ed6f87d
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/mod.rs
@@ -0,0 +1,38 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::prelude::*;
+use cargo_test_support::Project;
+use itertools::Itertools;
+
+use cargo_test_support::curr_dir;
+
+#[cargo_test]
+fn case() {
+ const MANY_FEATURES_COUNT: usize = 200;
+ const ACTIVATED_FEATURES_COUNT: usize = 30;
+
+ cargo_test_support::registry::init();
+ let mut test_package =
+ cargo_test_support::registry::Package::new("your-face", "99999.0.0+my-package");
+ for i in 0..MANY_FEATURES_COUNT {
+ test_package.feature(format!("eyes{i:03}").as_str(), &[]);
+ }
+ test_package.publish();
+
+ let project = Project::from_template(curr_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = &project_root;
+
+ let features = (0..ACTIVATED_FEATURES_COUNT)
+ .map(|i| format!("eyes{i:03}"))
+ .join(",");
+ snapbox::cmd::Command::cargo_ui()
+ .arg("add")
+ .arg_line(format!("your-face --features {features}").as_str())
+ .current_dir(cwd)
+ .assert()
+ .success()
+ .stdout_matches_path(curr_dir!().join("stdout.log"))
+ .stderr_matches_path(curr_dir!().join("stderr.log"));
+
+ assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
+}
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/out/Cargo.toml
new file mode 100644
index 000000000..b94cde668
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/out/Cargo.toml
@@ -0,0 +1,8 @@
+[workspace]
+
+[package]
+name = "cargo-list-test-fixture"
+version = "0.0.0"
+
+[dependencies]
+your-face = { version = "99999.0.0", features = ["eyes000", "eyes001", "eyes002", "eyes003", "eyes004", "eyes005", "eyes006", "eyes007", "eyes008", "eyes009", "eyes010", "eyes011", "eyes012", "eyes013", "eyes014", "eyes015", "eyes016", "eyes017", "eyes018", "eyes019", "eyes020", "eyes021", "eyes022", "eyes023", "eyes024", "eyes025", "eyes026", "eyes027", "eyes028", "eyes029"] }
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stderr.log
new file mode 100644
index 000000000..7f74e6bf0
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stderr.log
@@ -0,0 +1,34 @@
+ Updating `dummy-registry` index
+ Adding your-face v99999.0.0 to dependencies.
+ Features:
+ + eyes000
+ + eyes001
+ + eyes002
+ + eyes003
+ + eyes004
+ + eyes005
+ + eyes006
+ + eyes007
+ + eyes008
+ + eyes009
+ + eyes010
+ + eyes011
+ + eyes012
+ + eyes013
+ + eyes014
+ + eyes015
+ + eyes016
+ + eyes017
+ + eyes018
+ + eyes019
+ + eyes020
+ + eyes021
+ + eyes022
+ + eyes023
+ + eyes024
+ + eyes025
+ + eyes026
+ + eyes027
+ + eyes028
+ + eyes029
+ 170 deactivated features
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stdout.log
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_add/features_deactivated_over_limit/stdout.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log
index 0daba1a94..cf2a91313 100644
--- a/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log
@@ -42,7 +42,7 @@ Options:
--ignore-rust-version
Ignore `rust-version` specification in packages (unstable)
- --dry-run
+ -n, --dry-run
Don't actually write the manifest
-q, --quiet
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/invalid_manifest/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/invalid_manifest/stderr.log
index 3dabde349..9a8a93b5e 100644
--- a/src/tools/cargo/tests/testsuite/cargo_add/invalid_manifest/stderr.log
+++ b/src/tools/cargo/tests/testsuite/cargo_add/invalid_manifest/stderr.log
@@ -1,9 +1,6 @@
error: failed to parse manifest at `[ROOT]/case/Cargo.toml`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 8, column 7
|
8 | key = invalid-value
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/mod.rs
index de93afbc1..8c03b30dc 100644
--- a/src/tools/cargo/tests/testsuite/cargo_add/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_add/mod.rs
@@ -18,6 +18,8 @@ mod dev_prefer_existing_version;
mod dry_run;
mod empty_dep_table;
mod features;
+mod features_activated_over_limit;
+mod features_deactivated_over_limit;
mod features_empty;
mod features_multiple_occurrences;
mod features_preserve;
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs
index a382d95f1..f8aac0ad8 100644
--- a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs
@@ -26,7 +26,7 @@ fn case() {
.current_dir(cwd)
.masquerade_as_nightly_cargo(&["msrv-policy"])
.assert()
- .success()
+ .code(101)
.stdout_matches_path(curr_dir!().join("stdout.log"))
.stderr_matches_path(curr_dir!().join("stderr.log"));
diff --git a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log
index 430abe31b..96bcbddc2 100644
--- a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log
+++ b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log
@@ -1,2 +1,7 @@
Updating `dummy-registry` index
Adding rust-version-user v0.2.1 to dependencies.
+error: failed to select a version for the requirement `rust-version-user = "^0.2.1"`
+candidate versions found which didn't match: 0.2.1, 0.1.0
+location searched: `dummy-registry` index (which is replacing registry `crates-io`)
+required by package `cargo-list-test-fixture v0.0.0 ([ROOT]/case)`
+perhaps a crate was updated and forgotten to be re-vendored?
diff --git a/src/tools/cargo/tests/testsuite/cargo_alias_config.rs b/src/tools/cargo/tests/testsuite/cargo_alias_config.rs
index fd4aec917..679ca3d5f 100644
--- a/src/tools/cargo/tests/testsuite/cargo_alias_config.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_alias_config.rs
@@ -53,9 +53,6 @@ Caused by:
could not parse TOML configuration in `[..]/config`
Caused by:
- [..]
-
-Caused by:
TOML parse error at line [..]
|
3 | b-cargo-test = `
diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log
index 5d9484df9..430d8be42 100644
--- a/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log
@@ -45,7 +45,7 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
--profile <PROFILE-NAME> Build artifacts with the specified profile
- --target <TRIPLE> Build for the target triple
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/mod.rs b/src/tools/cargo/tests/testsuite/cargo_bench/mod.rs
index c0ce11180..28be9d1a7 100644
--- a/src/tools/cargo/tests/testsuite/cargo_bench/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_bench/mod.rs
@@ -1 +1,2 @@
mod help;
+mod no_keep_going;
diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/Cargo.toml
new file mode 100644
index 000000000..c35d63273
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/Cargo.toml
@@ -0,0 +1,3 @@
+[package]
+name = "foo"
+version = "0.1.0"
diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/src/lib.rs
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/in/src/lib.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/mod.rs b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/mod.rs
new file mode 100644
index 000000000..6ed5f81f9
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/mod.rs
@@ -0,0 +1,19 @@
+use cargo_test_support::curr_dir;
+use cargo_test_support::CargoCommand;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ let project = Project::from_template(curr_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = &project_root;
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("bench")
+ .arg("--keep-going")
+ .current_dir(cwd)
+ .assert()
+ .code(1)
+ .stdout_matches_path(curr_dir!().join("stdout.log"))
+ .stderr_matches_path(curr_dir!().join("stderr.log"));
+}
diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stderr.log b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stderr.log
new file mode 100644
index 000000000..7b94abbc4
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stderr.log
@@ -0,0 +1,7 @@
+error: unexpected argument '--keep-going' found
+
+ tip: use `--no-fail-fast` to run as many tests as possible regardless of failure
+
+Usage: cargo[EXE] bench [OPTIONS] [BENCHNAME] [-- [args]...]
+
+For more information, try '--help'.
diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stdout.log b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stdout.log
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_bench/no_keep_going/stdout.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log
index af906c24f..56b934cd1 100644
--- a/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log
@@ -41,8 +41,8 @@ Compilation Options:
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
- --target <TRIPLE> Build for the target triple
+ --keep-going Do not abort the build as soon as there is an error
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--out-dir <PATH> Copy final artifacts to this directory (unstable)
--build-plan Output the build plan in JSON (unstable)
diff --git a/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log
index 7c87615cd..92d44a6de 100644
--- a/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log
@@ -39,10 +39,10 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
-r, --release Check artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Check artifacts with the specified profile
- --target <TRIPLE> Check for the target triple
+ --target [<TRIPLE>] Check for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log
index fd3c8855c..6e9e82772 100644
--- a/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log
@@ -5,6 +5,7 @@ Usage: cargo[EXE] clean [OPTIONS]
Options:
--doc Whether or not to clean just the documentation directory
-q, --quiet Do not print cargo log messages
+ -n, --dry-run Display what would be deleted without deleting anything
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
--config <KEY=VALUE> Override a configuration value
@@ -17,7 +18,7 @@ Package Selection:
Compilation Options:
-r, --release Whether or not to clean release artifacts
--profile <PROFILE-NAME> Clean artifacts of the specified profile
- --target <TRIPLE> Target triple to clean output for
+ --target [<TRIPLE>] Target triple to clean output for
--target-dir <DIRECTORY> Directory for all generated artifacts
Manifest Options:
diff --git a/src/tools/cargo/tests/testsuite/cargo_config/mod.rs b/src/tools/cargo/tests/testsuite/cargo_config/mod.rs
index dc0a40ed8..c1769fb53 100644
--- a/src/tools/cargo/tests/testsuite/cargo_config/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_config/mod.rs
@@ -84,7 +84,7 @@ fn get_toml() {
alias.foo = \"abc --xyz\"
alias.sub-example = [\"sub\", \"example\"]
build.jobs = 99
-build.rustflags = [\"--flag-directory\", \"--flag-global\"]
+build.rustflags = [\"--flag-global\", \"--flag-directory\"]
extra-table.somekey = \"somevalue\"
profile.dev.opt-level = 3
profile.dev.package.foo.opt-level = 1
@@ -111,7 +111,7 @@ target.\"cfg(target_os = \\\"linux\\\")\".runner = \"runme\"
cargo_process("config get build.rustflags -Zunstable-options")
.cwd(&sub_folder.parent().unwrap())
.masquerade_as_nightly_cargo(&["cargo-config"])
- .with_stdout("build.rustflags = [\"--flag-directory\", \"--flag-global\"]")
+ .with_stdout("build.rustflags = [\"--flag-global\", \"--flag-directory\"]")
.with_stderr("")
.run();
@@ -171,8 +171,8 @@ fn get_json() {
"build": {
"jobs": 99,
"rustflags": [
- "--flag-directory",
- "--flag-global"
+ "--flag-global",
+ "--flag-directory"
]
},
"extra-table": {
@@ -259,8 +259,8 @@ alias.sub-example = [
]
build.jobs = 99 # [ROOT]/home/.cargo/config.toml
build.rustflags = [
- \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
\"--flag-global\", # [ROOT]/home/.cargo/config.toml
+ \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
]
extra-table.somekey = \"somevalue\" # [ROOT]/home/.cargo/config.toml
profile.dev.opt-level = 3 # [ROOT]/home/.cargo/config.toml
@@ -280,8 +280,8 @@ target.\"cfg(target_os = \\\"linux\\\")\".runner = \"runme\" # [ROOT]/home/.carg
.with_stdout(
"\
build.rustflags = [
- \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
\"--flag-global\", # [ROOT]/home/.cargo/config.toml
+ \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
\"env1\", # environment variable `CARGO_BUILD_RUSTFLAGS`
\"env2\", # environment variable `CARGO_BUILD_RUSTFLAGS`
]
@@ -310,12 +310,12 @@ fn show_origin_toml_cli() {
.with_stdout(
"\
build.rustflags = [
- \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
\"--flag-global\", # [ROOT]/home/.cargo/config.toml
- \"cli1\", # --config cli option
- \"cli2\", # --config cli option
+ \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
\"env1\", # environment variable `CARGO_BUILD_RUSTFLAGS`
\"env2\", # environment variable `CARGO_BUILD_RUSTFLAGS`
+ \"cli1\", # --config cli option
+ \"cli2\", # --config cli option
]
",
)
@@ -471,7 +471,7 @@ fn includes() {
cargo_process("config get build.rustflags -Zunstable-options -Zconfig-include")
.cwd(&sub_folder.parent().unwrap())
.masquerade_as_nightly_cargo(&["cargo-config", "config-include"])
- .with_stdout(r#"build.rustflags = ["--flag-other", "--flag-directory", "--flag-global"]"#)
+ .with_stdout(r#"build.rustflags = ["--flag-global", "--flag-other", "--flag-directory"]"#)
.with_stderr("")
.run();
@@ -481,9 +481,9 @@ fn includes() {
.with_stdout(
"\
build.rustflags = [
+ \"--flag-global\", # [ROOT]/home/.cargo/config.toml
\"--flag-other\", # [ROOT]/foo/.cargo/other.toml
\"--flag-directory\", # [ROOT]/foo/.cargo/config.toml
- \"--flag-global\", # [ROOT]/home/.cargo/config.toml
]
",
)
diff --git a/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log
index 480e189c1..8ff5f9b72 100644
--- a/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log
@@ -36,10 +36,10 @@ Target Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
- --target <TRIPLE> Build for the target triple
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_features.rs b/src/tools/cargo/tests/testsuite/cargo_features.rs
index ed5f53a1e..cf7ef0190 100644
--- a/src/tools/cargo/tests/testsuite/cargo_features.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_features.rs
@@ -676,8 +676,11 @@ fn wrong_position() {
error: failed to parse manifest at [..]
Caused by:
- cargo-features = [\"test-dummy-unstable\"] was found in the wrong location: it \
- should be set at the top of Cargo.toml before any tables
+ TOML parse error at line 5, column 34
+ |
+ 5 | cargo-features = [\"test-dummy-unstable\"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ the field `cargo-features` should be set at the top of Cargo.toml before any tables
",
)
.run();
diff --git a/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log
index b9bd6c35b..32f29f1b3 100644
--- a/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log
@@ -11,7 +11,7 @@ Options:
-h, --help Print help
Compilation Options:
- --target <TRIPLE> Fetch dependencies for the target triple
+ --target [<TRIPLE>] Fetch dependencies for the target triple
Manifest Options:
--manifest-path <PATH> Path to Cargo.toml
diff --git a/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log
index c0a98218a..dbbd11b77 100644
--- a/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log
@@ -44,10 +44,10 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
-r, --release Fix artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
- --target <TRIPLE> Fix for the target triple
+ --target [<TRIPLE>] Fix for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/clean-glob b/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/clean-glob
index a9d37c560..eb5a316cb 100644
--- a/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/clean-glob
+++ b/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/clean-glob
@@ -1,2 +1 @@
target
-Cargo.lock
diff --git a/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/ignore-glob b/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/ignore-glob
index a9d37c560..eb5a316cb 100644
--- a/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/ignore-glob
+++ b/src/tools/cargo/tests/testsuite/cargo_init/fossil_autodetect/out/.fossil-settings/ignore-glob
@@ -1,2 +1 @@
target
-Cargo.lock
diff --git a/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log
index 5dfb02498..0eb4c976b 100644
--- a/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log
@@ -6,10 +6,9 @@ Arguments:
[path] [default: .]
Options:
- --vcs <VCS> Initialize a new repository for the given version control system (git,
- hg, pijul, or fossil) or do not initialize any version control at all
- (none), overriding a global configuration. [possible values: git, hg,
- pijul, fossil, none]
+ --vcs <VCS> Initialize a new repository for the given version control system,
+ overriding a global configuration. [possible values: git, hg, pijul,
+ fossil, none]
--bin Use a binary (application) template [default]
--lib Use a library template
--edition <YEAR> Edition to set for the crate generated [possible values: 2015, 2018,
diff --git a/src/tools/cargo/tests/testsuite/cargo_init/pijul_autodetect/out/.ignore b/src/tools/cargo/tests/testsuite/cargo_init/pijul_autodetect/out/.ignore
index 4fffb2f89..ea8c4bf7f 100644
--- a/src/tools/cargo/tests/testsuite/cargo_init/pijul_autodetect/out/.ignore
+++ b/src/tools/cargo/tests/testsuite/cargo_init/pijul_autodetect/out/.ignore
@@ -1,2 +1 @@
/target
-/Cargo.lock
diff --git a/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log
index a07fa47f6..2267c5f6b 100644
--- a/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log
@@ -42,9 +42,9 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
--profile <PROFILE-NAME> Install artifacts with the specified profile
- --target <TRIPLE> Build for the target triple
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log
index faec55c18..fd0f3eb3d 100644
--- a/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log
@@ -4,7 +4,7 @@ Usage: cargo[EXE] login [OPTIONS] [token] [-- [args]...]
Arguments:
[token]
- [args]... Arguments for the credential provider (unstable)
+ [args]... Additional arguments for the credential provider
Options:
--registry <REGISTRY> Registry to use
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log
index 7252e0da1..a937f619b 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log
@@ -6,10 +6,9 @@ Arguments:
<path>
Options:
- --vcs <VCS> Initialize a new repository for the given version control system (git,
- hg, pijul, or fossil) or do not initialize any version control at all
- (none), overriding a global configuration. [possible values: git, hg,
- pijul, fossil, none]
+ --vcs <VCS> Initialize a new repository for the given version control system,
+ overriding a global configuration. [possible values: git, hg, pijul,
+ fossil, none]
--bin Use a binary (application) template [default]
--lib Use a library template
--edition <YEAR> Edition to set for the crate generated [possible values: 2015, 2018,
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/inherit_workspace_lints/mod.rs b/src/tools/cargo/tests/testsuite/cargo_new/inherit_workspace_lints/mod.rs
index 0b7697d20..9b9642468 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/inherit_workspace_lints/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_new/inherit_workspace_lints/mod.rs
@@ -1,7 +1,6 @@
use cargo_test_support::compare::assert_ui;
use cargo_test_support::curr_dir;
use cargo_test_support::CargoCommand;
-use cargo_test_support::ChannelChanger;
use cargo_test_support::Project;
#[cargo_test]
@@ -12,9 +11,8 @@ fn case() {
snapbox::cmd::Command::cargo_ui()
.arg("new")
- .args(["crates/foo", "-Zlints"])
+ .args(["crates/foo"])
.current_dir(cwd)
- .masquerade_as_nightly_cargo(&["lints"])
.assert()
.success()
.stdout_matches_path(curr_dir!().join("stdout.log"))
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/mod.rs b/src/tools/cargo/tests/testsuite/cargo_new/mod.rs
index 887316395..969b09f4f 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_new/mod.rs
@@ -4,4 +4,4 @@ mod inherit_workspace_package_table;
mod inherit_workspace_package_table_with_edition;
mod inherit_workspace_package_table_with_registry;
mod inherit_workspace_package_table_without_version;
-mod not_inherit_workspace_package_table_if_not_memebers;
+mod not_inherit_workspace_package_table_if_not_members;
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/Cargo.toml
index 2d204581c..2d204581c 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/Cargo.toml
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/Cargo.toml
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/README.md b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/README.md
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/README.md
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/src/lib.rs
index 7d12d9af8..7d12d9af8 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/in/src/lib.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/in/src/lib.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/mod.rs b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/mod.rs
index cdddf0e64..cdddf0e64 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/mod.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/Cargo.toml
index 2d204581c..2d204581c 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/Cargo.toml
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/Cargo.toml
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/foo/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/foo/Cargo.toml
index 4fcf77121..4fcf77121 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/foo/Cargo.toml
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/foo/Cargo.toml
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/foo/src/main.rs b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/foo/src/main.rs
index e7a11a969..e7a11a969 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/foo/src/main.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/foo/src/main.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/src/lib.rs
index 7d12d9af8..7d12d9af8 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/out/src/lib.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/out/src/lib.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/stderr.log b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/stderr.log
index 03b1ff6db..03b1ff6db 100644
--- a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_memebers/stderr.log
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/stderr.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/stdout.log b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/stdout.log
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_new/not_inherit_workspace_package_table_if_not_members/stdout.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log
index 3c8495ff0..580be3c88 100644
--- a/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log
@@ -9,9 +9,9 @@ Options:
-a, --add <LOGIN> Name of a user or team to invite as an owner
-r, --remove <LOGIN> Name of a user or team to remove as an owner
-l, --list List owners of a crate
- --index <INDEX> Registry index to modify owners for
+ --index <INDEX> Registry index URL to modify owners for
+ --registry <REGISTRY> Registry to modify owners for
--token <TOKEN> API token to use when authenticating
- --registry <REGISTRY> Registry to use
-q, --quiet Do not print cargo log messages
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
diff --git a/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log
index 35e32f313..5079c2a6f 100644
--- a/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log
@@ -25,10 +25,10 @@ Feature Selection:
--no-default-features Do not activate the `default` feature
Compilation Options:
- --target <TRIPLE> Build for the target triple
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
Manifest Options:
--manifest-path <PATH> Path to Cargo.toml
diff --git a/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log
index c02522887..df2594fb4 100644
--- a/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log
@@ -3,9 +3,9 @@ Upload a package to the registry
Usage: cargo[EXE] publish [OPTIONS]
Options:
- --dry-run Perform all checks without uploading
+ -n, --dry-run Perform all checks without uploading
--index <INDEX> Registry index URL to upload the package to
- --registry <REGISTRY> Registry to publish to
+ --registry <REGISTRY> Registry to upload the package to
--token <TOKEN> Token to use when uploading
--no-verify Don't verify the contents by building them
--allow-dirty Allow dirty working directories to be packaged
@@ -26,8 +26,8 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
- --target <TRIPLE> Build for the target triple
+ --keep-going Do not abort the build as soon as there is an error
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
Manifest Options:
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log
index 81a2d78b6..8937fb9f3 100644
--- a/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log
@@ -6,7 +6,7 @@ Arguments:
<DEP_ID>... Dependencies to be removed
Options:
- --dry-run Don't actually write the manifest
+ -n, --dry-run Don't actually write the manifest
-q, --quiet Do not print cargo log messages
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
@@ -27,3 +27,5 @@ Manifest Options:
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
--offline Run without accessing the network
+
+Run `cargo help remove` for more detailed information.
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/mod.rs b/src/tools/cargo/tests/testsuite/cargo_remove/mod.rs
index ea7902bd8..4403e2425 100644
--- a/src/tools/cargo/tests/testsuite/cargo_remove/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/mod.rs
@@ -23,6 +23,7 @@ mod optional_dep_feature;
mod optional_feature;
mod package;
mod remove_basic;
+mod skip_gc_glob_profile;
mod target;
mod target_build;
mod target_dev;
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/Cargo.toml
new file mode 100644
index 000000000..a25e33ae0
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "cargo-remove-test-fixture"
+version = "0.1.0"
+
+[[bin]]
+name = "main"
+path = "src/main.rs"
+
+[dependencies]
+toml = "0.1"
+
+[profile.dev.package."*"]
+opt-level = 3 \ No newline at end of file
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/src/lib.rs
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/in/src/lib.rs
@@ -0,0 +1 @@
+
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/mod.rs b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/mod.rs
new file mode 100644
index 000000000..2d587455c
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/mod.rs
@@ -0,0 +1,25 @@
+use cargo_test_support::compare::assert_ui;
+use cargo_test_support::curr_dir;
+use cargo_test_support::CargoCommand;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ cargo_test_support::registry::init();
+ cargo_test_support::registry::Package::new("toml", "0.1.1+my-package").publish();
+
+ let project = Project::from_template(curr_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = &project_root;
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("remove")
+ .args(["toml"])
+ .current_dir(cwd)
+ .assert()
+ .success()
+ .stdout_matches_path(curr_dir!().join("stdout.log"))
+ .stderr_matches_path(curr_dir!().join("stderr.log"));
+
+ assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
+}
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/out/Cargo.toml
new file mode 100644
index 000000000..76e3bcf77
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/out/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "cargo-remove-test-fixture"
+version = "0.1.0"
+
+[[bin]]
+name = "main"
+path = "src/main.rs"
+
+[profile.dev.package."*"]
+opt-level = 3
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stderr.log b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stderr.log
new file mode 100644
index 000000000..9dee9e2b7
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stderr.log
@@ -0,0 +1 @@
+ Removing toml from dependencies
diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stdout.log b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stdout.log
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_remove/skip_gc_glob_profile/stdout.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log
index 6ab0e76b1..4b39f30b3 100644
--- a/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log
@@ -30,10 +30,10 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
- --target <TRIPLE> Build for the target triple
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log
index f587c3276..9d43841fe 100644
--- a/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log
@@ -41,10 +41,10 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
- --target <TRIPLE> Target triple which compiles will be for
+ --target [<TRIPLE>] Target triple which compiles will be for
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log
index 4cac29e0a..706072f24 100644
--- a/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log
@@ -39,10 +39,10 @@ Feature Selection:
Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
- --keep-going Do not abort the build as soon as there is an error (unstable)
+ --keep-going Do not abort the build as soon as there is an error
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
- --target <TRIPLE> Build for the target triple
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log
index 8572064e3..07170ad70 100644
--- a/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log
@@ -7,8 +7,8 @@ Arguments:
Options:
--limit <LIMIT> Limit the number of results (default: 10, max: 100)
- --index <INDEX> Registry index URL to upload the package to
- --registry <REGISTRY> Registry to use
+ --index <INDEX> Registry index URL to search packages in
+ --registry <REGISTRY> Registry to search packages in
-q, --quiet Do not print cargo log messages
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
diff --git a/src/tools/cargo/tests/testsuite/cargo_test/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_test/help/stdout.log
index d693dc3c9..5df62d6bb 100644
--- a/src/tools/cargo/tests/testsuite/cargo_test/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_test/help/stdout.log
@@ -48,7 +48,7 @@ Compilation Options:
-j, --jobs <N> Number of parallel jobs, defaults to # of CPUs.
-r, --release Build artifacts in release mode, with optimizations
--profile <PROFILE-NAME> Build artifacts with the specified profile
- --target <TRIPLE> Build for the target triple
+ --target [<TRIPLE>] Build for the target triple
--target-dir <DIRECTORY> Directory for all generated artifacts
--unit-graph Output build graph in JSON (unstable)
--timings[=<FMTS>] Timing output formats (unstable) (comma separated): html, json
diff --git a/src/tools/cargo/tests/testsuite/cargo_test/mod.rs b/src/tools/cargo/tests/testsuite/cargo_test/mod.rs
index c0ce11180..28be9d1a7 100644
--- a/src/tools/cargo/tests/testsuite/cargo_test/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_test/mod.rs
@@ -1 +1,2 @@
mod help;
+mod no_keep_going;
diff --git a/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/Cargo.toml
new file mode 100644
index 000000000..c35d63273
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/Cargo.toml
@@ -0,0 +1,3 @@
+[package]
+name = "foo"
+version = "0.1.0"
diff --git a/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/src/lib.rs
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/in/src/lib.rs
diff --git a/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/mod.rs b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/mod.rs
new file mode 100644
index 000000000..fdec61642
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/mod.rs
@@ -0,0 +1,19 @@
+use cargo_test_support::curr_dir;
+use cargo_test_support::CargoCommand;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ let project = Project::from_template(curr_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = &project_root;
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("test")
+ .arg("--keep-going")
+ .current_dir(cwd)
+ .assert()
+ .code(1)
+ .stdout_matches_path(curr_dir!().join("stdout.log"))
+ .stderr_matches_path(curr_dir!().join("stderr.log"));
+}
diff --git a/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stderr.log b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stderr.log
new file mode 100644
index 000000000..fd4ca9b2a
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stderr.log
@@ -0,0 +1,7 @@
+error: unexpected argument '--keep-going' found
+
+ tip: use `--no-fail-fast` to run as many tests as possible regardless of failure
+
+Usage: cargo[EXE] test [OPTIONS] [TESTNAME] [-- [args]...]
+
+For more information, try '--help'.
diff --git a/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stdout.log b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stdout.log
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_test/no_keep_going/stdout.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log
index 268b6b2ad..4170583a8 100644
--- a/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log
@@ -33,8 +33,8 @@ Feature Selection:
--no-default-features Do not activate the `default` feature
Compilation Options:
- --target <TRIPLE> Filter dependencies matching the given target-triple (default host
- platform). Pass `all` to include all targets.
+ --target [<TRIPLE>] Filter dependencies matching the given target-triple (default host
+ platform). Pass `all` to include all targets.
Manifest Options:
--manifest-path <PATH> Path to Cargo.toml
diff --git a/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log
index 6cc109151..92caeb656 100644
--- a/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log
@@ -1,11 +1,11 @@
Update dependencies as recorded in the local lock file
-Usage: cargo[EXE] update [OPTIONS]
+Usage: cargo[EXE] update [OPTIONS] [SPEC]...
Options:
- --dry-run Don't actually write the lockfile
- --aggressive Force updating all dependencies of SPEC as well when used with -p
- --precise <PRECISE> Update a single dependency to exactly PRECISE when used with -p
+ -n, --dry-run Don't actually write the lockfile
+ --recursive Force updating all dependencies of [SPEC]... as well
+ --precise <PRECISE> Update [SPEC] to exactly PRECISE
-q, --quiet Do not print cargo log messages
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
--color <WHEN> Coloring: auto, always, never
@@ -14,8 +14,8 @@ Options:
-h, --help Print help
Package Selection:
- -w, --workspace Only update the workspace packages
- -p, --package [<SPEC>] Package to update
+ -w, --workspace Only update the workspace packages
+ [SPEC]... Package to update
Manifest Options:
--manifest-path <PATH> Path to Cargo.toml
diff --git a/src/tools/cargo/tests/testsuite/cargo_update/mod.rs b/src/tools/cargo/tests/testsuite/cargo_update/mod.rs
index c0ce11180..a809d9fe9 100644
--- a/src/tools/cargo/tests/testsuite/cargo_update/mod.rs
+++ b/src/tools/cargo/tests/testsuite/cargo_update/mod.rs
@@ -1 +1,2 @@
mod help;
+mod toolchain_pkgname;
diff --git a/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/Cargo.toml
new file mode 100644
index 000000000..c844631b2
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/Cargo.toml
@@ -0,0 +1,5 @@
+[package]
+name = "test"
+version = "0.1.0"
+
+[dependencies]
diff --git a/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/src/main.rs b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/src/main.rs
new file mode 100644
index 000000000..e7a11a969
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/in/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("Hello, world!");
+}
diff --git a/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/mod.rs b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/mod.rs
new file mode 100644
index 000000000..f1488b90d
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/mod.rs
@@ -0,0 +1,19 @@
+use cargo_test_support::curr_dir;
+use cargo_test_support::prelude::*;
+use cargo_test_support::Project;
+
+#[cargo_test]
+fn case() {
+ let project = Project::from_template(curr_dir!().join("in"));
+ let project_root = project.root();
+ let cwd = &project_root;
+
+ snapbox::cmd::Command::cargo_ui()
+ .arg("update")
+ .arg("+stable")
+ .current_dir(cwd)
+ .assert()
+ .code(101)
+ .stdout_matches_path(curr_dir!().join("stdout.log"))
+ .stderr_matches_path(curr_dir!().join("stderr.log"));
+}
diff --git a/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stderr.log b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stderr.log
new file mode 100644
index 000000000..7e5870c54
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stderr.log
@@ -0,0 +1,2 @@
+error: invalid character `+` in package name: `+stable`
+ Use `cargo +stable update` if you meant to use the `stable` toolchain.
diff --git a/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stdout.log b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stdout.log
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/cargo_update/toolchain_pkgname/stdout.log
diff --git a/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log
index 25b04e6c7..c6dbfeb9d 100644
--- a/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log
+++ b/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log
@@ -8,8 +8,8 @@ Arguments:
Options:
--version <VERSION> The version to yank or un-yank
--undo Undo a yank, putting a version back into the index
- --index <INDEX> Registry index to yank from
- --registry <REGISTRY> Registry to use
+ --index <INDEX> Registry index URL to yank from
+ --registry <REGISTRY> Registry to yank from
--token <TOKEN> API token to use when authenticating
-q, --quiet Do not print cargo log messages
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
diff --git a/src/tools/cargo/tests/testsuite/check.rs b/src/tools/cargo/tests/testsuite/check.rs
index 7bc9a38a3..b74bd6209 100644
--- a/src/tools/cargo/tests/testsuite/check.rs
+++ b/src/tools/cargo/tests/testsuite/check.rs
@@ -861,8 +861,7 @@ fn check_keep_going() {
.build();
// Due to -j1, without --keep-going only one of the two bins would be built.
- foo.cargo("check -j1 --keep-going -Zunstable-options")
- .masquerade_as_nightly_cargo(&["keep-going"])
+ foo.cargo("check -j1 --keep-going")
.with_status(101)
.with_stderr_contains("error: ONE")
.with_stderr_contains("error: TWO")
diff --git a/src/tools/cargo/tests/testsuite/clean.rs b/src/tools/cargo/tests/testsuite/clean.rs
index e0885fd26..fbb4d3e5b 100644
--- a/src/tools/cargo/tests/testsuite/clean.rs
+++ b/src/tools/cargo/tests/testsuite/clean.rs
@@ -272,7 +272,7 @@ fn clean_doc() {
assert!(doc_path.is_dir());
- p.cargo("clean --doc").run();
+ p.cargo("clean --doc").with_stderr("[REMOVED] [..]").run();
assert!(!doc_path.is_dir());
assert!(p.build_dir().is_dir());
@@ -414,9 +414,10 @@ fn clean_verbose() {
if cfg!(target_os = "macos") {
// Rust 1.69 has changed so that split-debuginfo=unpacked includes unpacked for rlibs.
for obj in p.glob("target/debug/deps/bar-*.o") {
- expected.push_str(&format!("[REMOVING] [..]{}", obj.unwrap().display()));
+ expected.push_str(&format!("[REMOVING] [..]{}\n", obj.unwrap().display()));
}
}
+ expected.push_str("[REMOVED] [..] files, [..] total\n");
p.cargo("clean -p bar --verbose")
.with_stderr_unordered(&expected)
.run();
@@ -569,10 +570,120 @@ fn assert_all_clean(build_dir: &Path) {
}
#[cargo_test]
-fn clean_spec_multiple() {
+fn clean_spec_version() {
// clean -p foo where foo matches multiple versions
- Package::new("bar", "1.0.0").publish();
- Package::new("bar", "2.0.0").publish();
+ Package::new("bar", "0.1.0").publish();
+ Package::new("bar", "0.2.0").publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bar1 = {version="0.1", package="bar"}
+ bar2 = {version="0.2", package="bar"}
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("build").run();
+
+ // Check suggestion for bad pkgid.
+ p.cargo("clean -p baz")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: package ID specification `baz` did not match any packages
+
+<tab>Did you mean `bar`?
+",
+ )
+ .run();
+
+ p.cargo("clean -p bar:0.1.0")
+ .with_stderr(
+ "warning: version qualifier in `-p bar:0.1.0` is ignored, \
+ cleaning all versions of `bar` found\n\
+ [REMOVED] [..] files, [..] total",
+ )
+ .run();
+ let mut walker = walkdir::WalkDir::new(p.build_dir())
+ .into_iter()
+ .filter_map(|e| e.ok())
+ .filter(|e| {
+ let n = e.file_name().to_str().unwrap();
+ n.starts_with("bar") || n.starts_with("libbar")
+ });
+ if let Some(e) = walker.next() {
+ panic!("{:?} was not cleaned", e.path());
+ }
+}
+
+#[cargo_test]
+fn clean_spec_partial_version() {
+ // clean -p foo where foo matches multiple versions
+ Package::new("bar", "0.1.0").publish();
+ Package::new("bar", "0.2.0").publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bar1 = {version="0.1", package="bar"}
+ bar2 = {version="0.2", package="bar"}
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("build").run();
+
+ // Check suggestion for bad pkgid.
+ p.cargo("clean -p baz")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: package ID specification `baz` did not match any packages
+
+<tab>Did you mean `bar`?
+",
+ )
+ .run();
+
+ p.cargo("clean -p bar:0.1")
+ .with_stderr(
+ "warning: version qualifier in `-p bar:0.1` is ignored, \
+ cleaning all versions of `bar` found\n\
+ [REMOVED] [..] files, [..] total",
+ )
+ .run();
+ let mut walker = walkdir::WalkDir::new(p.build_dir())
+ .into_iter()
+ .filter_map(|e| e.ok())
+ .filter(|e| {
+ let n = e.file_name().to_str().unwrap();
+ n.starts_with("bar") || n.starts_with("libbar")
+ });
+ if let Some(e) = walker.next() {
+ panic!("{:?} was not cleaned", e.path());
+ }
+}
+
+#[cargo_test]
+fn clean_spec_partial_version_ambiguous() {
+ // clean -p foo where foo matches multiple versions
+ Package::new("bar", "0.1.0").publish();
+ Package::new("bar", "0.2.0").publish();
let p = project()
.file(
@@ -583,8 +694,8 @@ fn clean_spec_multiple() {
version = "0.1.0"
[dependencies]
- bar1 = {version="1.0", package="bar"}
- bar2 = {version="2.0", package="bar"}
+ bar1 = {version="0.1", package="bar"}
+ bar2 = {version="0.2", package="bar"}
"#,
)
.file("src/lib.rs", "")
@@ -604,10 +715,11 @@ error: package ID specification `baz` did not match any packages
)
.run();
- p.cargo("clean -p bar:1.0.0")
+ p.cargo("clean -p bar:0")
.with_stderr(
- "warning: version qualifier in `-p bar:1.0.0` is ignored, \
- cleaning all versions of `bar` found",
+ "warning: version qualifier in `-p bar:0` is ignored, \
+ cleaning all versions of `bar` found\n\
+ [REMOVED] [..] files, [..] total",
)
.run();
let mut walker = walkdir::WalkDir::new(p.build_dir())
@@ -673,3 +785,72 @@ fn clean_spec_reserved() {
)
.run();
}
+
+#[cargo_test]
+fn clean_dry_run() {
+ // Basic `clean --dry-run` test.
+ Package::new("bar", "1.0.0").publish();
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bar = "1.0"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ let ls_r = || -> Vec<_> {
+ let mut file_list: Vec<_> = walkdir::WalkDir::new(p.build_dir())
+ .into_iter()
+ .filter_map(|e| e.map(|e| e.path().to_owned()).ok())
+ .collect();
+ file_list.sort();
+ file_list
+ };
+
+ // Start with no files.
+ p.cargo("clean --dry-run")
+ .with_stdout("")
+ .with_stderr(
+ "[SUMMARY] 0 files\n\
+ [WARNING] no files deleted due to --dry-run",
+ )
+ .run();
+ p.cargo("check").run();
+ let before = ls_r();
+ p.cargo("clean --dry-run")
+ .with_stderr(
+ "[SUMMARY] [..] files, [..] total\n\
+ [WARNING] no files deleted due to --dry-run",
+ )
+ .run();
+ // Verify it didn't delete anything.
+ let after = ls_r();
+ assert_eq!(before, after);
+ let expected = cargo::util::iter_join(before.iter().map(|p| p.to_str().unwrap()), "\n");
+ eprintln!("{expected}");
+ // Verify the verbose output.
+ p.cargo("clean --dry-run -v")
+ .with_stdout_unordered(expected)
+ .with_stderr(
+ "[SUMMARY] [..] files, [..] total\n\
+ [WARNING] no files deleted due to --dry-run",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn doc_with_package_selection() {
+ // --doc with -p
+ let p = project().file("src/lib.rs", "").build();
+ p.cargo("clean --doc -p foo")
+ .with_status(101)
+ .with_stderr("error: --doc cannot be used with -p")
+ .run();
+}
diff --git a/src/tools/cargo/tests/testsuite/config.rs b/src/tools/cargo/tests/testsuite/config.rs
index 5d4163818..7078fc445 100644
--- a/src/tools/cargo/tests/testsuite/config.rs
+++ b/src/tools/cargo/tests/testsuite/config.rs
@@ -541,18 +541,18 @@ expected boolean, but found array",
config.get::<VSOB>("b").unwrap(),
VSOB::VecString(vec![
"b".to_string(),
- "clib".to_string(),
"env1".to_string(),
- "env2".to_string()
+ "env2".to_string(),
+ "clib".to_string(),
])
);
assert_eq!(
config.get::<VSOB>("c").unwrap(),
VSOB::VecString(vec![
"c".to_string(),
- "clic".to_string(),
"e1".to_string(),
- "e2".to_string()
+ "e2".to_string(),
+ "clic".to_string(),
])
);
}
@@ -722,9 +722,6 @@ Caused by:
could not parse TOML configuration in `[..]/.cargo/config`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 1, column 5
|
1 | asdf
@@ -1091,9 +1088,6 @@ Caused by:
could not parse TOML configuration in `[..]/.cargo/config`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 3, column 1
|
3 | ssl-version.min = 'tlsv1.2'
@@ -1582,12 +1576,12 @@ known-hosts = [
.as_ref()
.unwrap();
assert_eq!(kh.len(), 4);
- assert_eq!(kh[0].val, "example.org ...");
- assert_eq!(kh[0].definition, Definition::Path(foo_path.clone()));
- assert_eq!(kh[1].val, "example.com ...");
+ assert_eq!(kh[0].val, "example.com ...");
+ assert_eq!(kh[0].definition, Definition::Path(root_path.clone()));
+ assert_eq!(kh[1].val, "example.net ...");
assert_eq!(kh[1].definition, Definition::Path(root_path.clone()));
- assert_eq!(kh[2].val, "example.net ...");
- assert_eq!(kh[2].definition, Definition::Path(root_path.clone()));
+ assert_eq!(kh[2].val, "example.org ...");
+ assert_eq!(kh[2].definition, Definition::Path(foo_path.clone()));
assert_eq!(kh[3].val, "env-example");
assert_eq!(
kh[3].definition,
diff --git a/src/tools/cargo/tests/testsuite/config_cli.rs b/src/tools/cargo/tests/testsuite/config_cli.rs
index 1120e279d..67aca0d19 100644
--- a/src/tools/cargo/tests/testsuite/config_cli.rs
+++ b/src/tools/cargo/tests/testsuite/config_cli.rs
@@ -143,11 +143,9 @@ fn merges_array() {
.env("CARGO_BUILD_RUSTFLAGS", "--env1 --env2")
.config_arg("build.rustflags = ['--cli']")
.build();
- // The order of cli/env is a little questionable here, but would require
- // much more complex merging logic.
assert_eq!(
config.get::<Vec<String>>("build.rustflags").unwrap(),
- ["--file", "--cli", "--env1", "--env2"]
+ ["--file", "--env1", "--env2", "--cli"]
);
// With advanced-env.
@@ -158,7 +156,7 @@ fn merges_array() {
.build();
assert_eq!(
config.get::<Vec<String>>("build.rustflags").unwrap(),
- ["--file", "--cli", "--env"]
+ ["--file", "--env", "--cli"]
);
// Merges multiple instances.
@@ -202,7 +200,7 @@ fn string_list_array() {
.get::<cargo::util::config::StringList>("build.rustflags")
.unwrap()
.as_slice(),
- ["--file", "--cli", "--env1", "--env2"]
+ ["--file", "--env1", "--env2", "--cli"]
);
// With advanced-env.
@@ -216,7 +214,7 @@ fn string_list_array() {
.get::<cargo::util::config::StringList>("build.rustflags")
.unwrap()
.as_slice(),
- ["--file", "--cli", "--env"]
+ ["--file", "--env", "--cli"]
);
}
diff --git a/src/tools/cargo/tests/testsuite/credential_process.rs b/src/tools/cargo/tests/testsuite/credential_process.rs
index c010c01cd..815089f70 100644
--- a/src/tools/cargo/tests/testsuite/credential_process.rs
+++ b/src/tools/cargo/tests/testsuite/credential_process.rs
@@ -7,63 +7,6 @@ fn toml_bin(proj: &Project, name: &str) -> String {
proj.bin(name).display().to_string().replace('\\', "\\\\")
}
-#[cargo_test]
-fn gated() {
- let _alternative = registry::RegistryBuilder::new()
- .alternative()
- .no_configure_token()
- .build();
-
- let cratesio = registry::RegistryBuilder::new()
- .no_configure_token()
- .build();
-
- let p = project()
- .file(
- ".cargo/config",
- r#"
- [registry]
- credential-provider = ["false"]
- "#,
- )
- .file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
- .file("src/lib.rs", "")
- .build();
-
- p.cargo("publish --no-verify")
- .replace_crates_io(cratesio.index_url())
- .masquerade_as_nightly_cargo(&["credential-process"])
- .with_status(101)
- .with_stderr(
- "\
-[UPDATING] [..]
-[ERROR] no token found, please run `cargo login`
-or use environment variable CARGO_REGISTRY_TOKEN
-",
- )
- .run();
-
- p.change_file(
- ".cargo/config",
- r#"
- [registry.alternative]
- credential-process = "false"
- "#,
- );
-
- p.cargo("publish --no-verify --registry alternative")
- .masquerade_as_nightly_cargo(&["credential-process"])
- .with_status(101)
- .with_stderr(
- "\
-[UPDATING] [..]
-[ERROR] no token found for `alternative`, please run `cargo login --registry alternative`
-or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN
-",
- )
- .run();
-}
-
/// Setup for a test that will issue a command that needs to fetch a token.
///
/// This does the following:
@@ -125,14 +68,13 @@ fn publish() {
// Checks that credential-process is used for `cargo publish`.
let (p, _t) = get_token_test();
- p.cargo("publish --no-verify --registry alternative -Z credential-process -Z registry-auth")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ p.cargo("publish --no-verify --registry alternative")
.with_stderr(
r#"[UPDATING] [..]
-{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read"}
[PACKAGING] foo v0.1.0 [..]
[PACKAGED] [..]
-{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]"}
[UPLOADING] foo v0.1.0 [..]
[UPLOADED] foo v0.1.0 [..]
note: Waiting [..]
@@ -151,9 +93,8 @@ fn basic_unsupported() {
.credential_provider(&["cargo:token-from-stdout", "false"])
.build();
- cargo_process("login -Z credential-process abcdefg")
+ cargo_process("login abcdefg")
.replace_crates_io(registry.index_url())
- .masquerade_as_nightly_cargo(&["credential-process"])
.with_status(101)
.with_stderr(
"\
@@ -166,9 +107,8 @@ Caused by:
)
.run();
- cargo_process("logout -Z credential-process")
+ cargo_process("logout")
.replace_crates_io(registry.index_url())
- .masquerade_as_nightly_cargo(&["credential-process"])
.with_status(101)
.with_stderr(
"\
@@ -192,8 +132,7 @@ fn login() {
])
.build();
- cargo_process("login -Z credential-process abcdefg -- cmd3 --cmd4")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login abcdefg -- cmd3 --cmd4")
.replace_crates_io(registry.index_url())
.with_stderr(
r#"[UPDATING] [..]
@@ -213,11 +152,10 @@ fn logout() {
)])
.build();
- cargo_process("logout -Z credential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("logout")
.replace_crates_io(server.index_url())
.with_stderr(
- r#"{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"logout","args":[]}
+ r#"{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"logout"}
"#,
)
.run();
@@ -227,12 +165,11 @@ fn logout() {
fn yank() {
let (p, _t) = get_token_test();
- p.cargo("yank --version 0.1.0 --registry alternative -Zcredential-process -Zregistry-auth")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ p.cargo("yank --version 0.1.0 --registry alternative")
.with_stderr(
r#"[UPDATING] [..]
-{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read","args":[]}
-{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"yank","name":"foo","vers":"0.1.0","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read"}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"yank","name":"foo","vers":"0.1.0"}
[YANK] foo@0.1.0
"#,
)
@@ -243,12 +180,11 @@ fn yank() {
fn owner() {
let (p, _t) = get_token_test();
- p.cargo("owner --add username --registry alternative -Zcredential-process -Zregistry-auth")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ p.cargo("owner --add username --registry alternative")
.with_stderr(
r#"[UPDATING] [..]
-{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read","args":[]}
-{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"owners","name":"foo","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative","headers":[..]},"kind":"get","operation":"read"}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"owners","name":"foo"}
[OWNER] completed!
"#,
)
@@ -278,8 +214,7 @@ fn invalid_token_output() {
.file("src/lib.rs", "")
.build();
- p.cargo("publish --no-verify --registry alternative -Z credential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ p.cargo("publish --no-verify --registry alternative")
.with_status(101)
.with_stderr(
"\
@@ -321,6 +256,35 @@ fn build_provider(name: &str, response: &str) -> String {
}
#[cargo_test]
+fn not_found() {
+ let registry = registry::RegistryBuilder::new()
+ .no_configure_token()
+ .http_index()
+ .auth_required()
+ .credential_provider(&[&build_provider(
+ "not_found",
+ r#"{"Err": {"kind": "not-found"}}"#,
+ )])
+ .build();
+
+ // should not suggest a _TOKEN environment variable since the cargo:token provider isn't available.
+ cargo_process("install -v foo")
+ .replace_crates_io(registry.index_url())
+ .with_status(101)
+ .with_stderr(
+ r#"[UPDATING] [..]
+[CREDENTIAL] [..]not_found[..] get crates-io
+{"v":1[..]
+[ERROR] failed to query replaced source registry `crates-io`
+
+Caused by:
+ no token found, please run `cargo login`
+"#,
+ )
+ .run();
+}
+
+#[cargo_test]
fn all_not_found() {
let server = registry::RegistryBuilder::new()
.no_configure_token()
@@ -342,19 +306,18 @@ fn all_not_found() {
)
.unwrap();
- cargo_process("install -v foo -Zcredential-process -Zregistry-auth")
- .masquerade_as_nightly_cargo(&["credential-process", "registry-auth"])
+ // should not suggest a _TOKEN environment variable since the cargo:token provider isn't available.
+ cargo_process("install -v foo")
.replace_crates_io(server.index_url())
.with_status(101)
.with_stderr(
r#"[UPDATING] [..]
[CREDENTIAL] [..]not_found[..] get crates-io
-{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read"}
[ERROR] failed to query replaced source registry `crates-io`
Caused by:
no token found, please run `cargo login`
- or use environment variable CARGO_REGISTRY_TOKEN
"#,
)
.run();
@@ -383,14 +346,13 @@ fn all_not_supported() {
)
.unwrap();
- cargo_process("install -v foo -Zcredential-process -Zregistry-auth")
- .masquerade_as_nightly_cargo(&["credential-process", "registry-auth"])
+ cargo_process("install -v foo")
.replace_crates_io(server.index_url())
.with_status(101)
.with_stderr(
r#"[UPDATING] [..]
[CREDENTIAL] [..]not_supported[..] get crates-io
-{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"crates-io","headers":[[..]"WWW-Authenticate: Cargo login_url=\"https://test-registry-login/me\""[..]]},"kind":"get","operation":"read"}
[ERROR] failed to query replaced source registry `crates-io`
Caused by:
@@ -431,15 +393,14 @@ fn multiple_providers() {
)
.unwrap();
- cargo_process("login -Z credential-process -v abcdefg")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login -v abcdefg")
.replace_crates_io(server.index_url())
.with_stderr(
r#"[UPDATING] [..]
[CREDENTIAL] [..]url_not_supported[..] login crates-io
-{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]","args":[]}
+{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]"}
[CREDENTIAL] [..]success_provider[..] login crates-io
-{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]","args":[]}
+{"v":1,"registry":{"index-url":"https://github.com/rust-lang/crates.io-index","name":"crates-io"},"kind":"login","token":"abcdefg","login-url":"[..]"}
"#,
)
.run();
@@ -447,25 +408,42 @@ fn multiple_providers() {
#[cargo_test]
fn both_token_and_provider() {
+ let server = registry::RegistryBuilder::new()
+ .credential_provider(&["cargo:paseto"])
+ .build();
+
+ cargo_process("login -Z asymmetric-token")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
+ .replace_crates_io(server.index_url())
+ .with_stderr(
+ r#"[UPDATING] [..]
+[WARNING] registry `crates-io` has a token configured in [..] that will be ignored because this registry is configured to use credential-provider `cargo:paseto`
+k3.public[..]
+"#,
+ )
+ .run();
+}
+
+#[cargo_test]
+fn registry_provider_overrides_global() {
let server = registry::RegistryBuilder::new().build();
cargo_util::paths::append(
&paths::home().join(".cargo/config"),
format!(
r#"
[registry]
- credential-provider = ["cargo:token"]
+ global-credential-providers = ["should-not-be-called"]
"#,
)
.as_bytes(),
)
.unwrap();
- cargo_process("login -Z credential-process -v abcdefg")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login -v abcdefg")
+ .env("CARGO_REGISTRY_CREDENTIAL_PROVIDER", "cargo:token")
.replace_crates_io(server.index_url())
.with_stderr(
r#"[UPDATING] [..]
-[WARNING] registry `crates-io` has a token configured in [..]credentials.toml that will be ignored because a credential-provider is configured for this registry`
[CREDENTIAL] cargo:token login crates-io
[LOGIN] token for `crates-io` saved
"#,
@@ -492,8 +470,8 @@ fn both_asymmetric_and_token() {
)
.unwrap();
- cargo_process("login -Z credential-process -v abcdefg")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login -Zasymmetric-token -v abcdefg")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.replace_crates_io(server.index_url())
.with_stderr(
r#"[UPDATING] [..]
@@ -520,13 +498,13 @@ fn token_caching() {
// Token should not be re-used if it is expired
let expired_provider = build_provider(
- "test-cred",
- r#"{"Ok":{"kind":"get","token":"sekrit","cache":{"expires":0},"operation_independent":true}}"#,
+ "expired_provider",
+ r#"{"Ok":{"kind":"get","token":"sekrit","cache":"expires","expiration":0,"operation_independent":true}}"#,
);
// Token should not be re-used for a different operation if it is not operation_independent
let non_independent_provider = build_provider(
- "test-cred",
+ "non_independent_provider",
r#"{"Ok":{"kind":"get","token":"sekrit","cache":"session","operation_independent":false}}"#,
);
@@ -557,10 +535,10 @@ fn token_caching() {
.build();
let output = r#"[UPDATING] `alternative` index
-{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"read","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"read"}
[PACKAGING] foo v0.1.0 [..]
[PACKAGED] [..]
-{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]","args":[]}
+{"v":1,"registry":{"index-url":"[..]","name":"alternative"},"kind":"get","operation":"publish","name":"foo","vers":"0.1.0","cksum":"[..]"}
[UPLOADING] foo v0.1.0 [..]
[UPLOADED] foo v0.1.0 [..]
note: Waiting [..]
@@ -568,11 +546,10 @@ You may press ctrl-c [..]
[PUBLISHED] foo v0.1.0 [..]
"#;
- // The output should contain two JSON messages from the provider in boths cases:
+ // The output should contain two JSON messages from the provider in both cases:
// The first because the credential is expired, the second because the provider
// indicated that the token was non-operation-independent.
- p.cargo("publish -Z credential-process --registry alternative --no-verify")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ p.cargo("publish --registry alternative --no-verify")
.with_stderr(output)
.run();
@@ -588,8 +565,7 @@ You may press ctrl-c [..]
),
);
- p.cargo("publish -Z credential-process --registry alternative --no-verify")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ p.cargo("publish --registry alternative --no-verify")
.with_stderr(output)
.run();
}
@@ -639,8 +615,7 @@ fn basic_provider() {
.build();
Package::new("bar", "0.0.1").alternative(true).publish();
- p.cargo("check -Z credential-process -Z registry-auth")
- .masquerade_as_nightly_cargo(&["credential-process", "registry-auth"])
+ p.cargo("check")
.with_stderr(
"\
[UPDATING] `alternative` index
@@ -656,3 +631,72 @@ CARGO_REGISTRY_INDEX_URL=Some([..])
)
.run();
}
+
+#[cargo_test]
+fn unsupported_version() {
+ let cred_proj = project()
+ .at("new-vers")
+ .file("Cargo.toml", &basic_manifest("new-vers", "1.0.0"))
+ .file(
+ "src/main.rs",
+ &r####"
+ fn main() {
+ println!(r#"{{"v":[998, 999]}}"#);
+ assert_eq!(std::env::args().skip(1).next().unwrap(), "--cargo-plugin");
+ let mut buffer = String::new();
+ std::io::stdin().read_line(&mut buffer).unwrap();
+ std::thread::sleep(std::time::Duration::from_secs(1));
+ panic!("child process should have been killed before getting here");
+ } "####,
+ )
+ .build();
+ cred_proj.cargo("build").run();
+ let provider = toml_bin(&cred_proj, "new-vers");
+
+ let registry = registry::RegistryBuilder::new()
+ .no_configure_token()
+ .credential_provider(&[&provider])
+ .build();
+
+ cargo_process("login abcdefg")
+ .replace_crates_io(registry.index_url())
+ .with_status(101)
+ .with_stderr(
+ r#"[UPDATING] [..]
+[ERROR] credential provider `[..]` failed action `login`
+
+Caused by:
+ credential provider supports protocol versions [998, 999], while Cargo supports [1]
+"#,
+ )
+ .run();
+}
+
+#[cargo_test]
+fn alias_builtin_warning() {
+ let registry = registry::RegistryBuilder::new()
+ .credential_provider(&[&"cargo:token"])
+ .build();
+
+ cargo_util::paths::append(
+ &paths::home().join(".cargo/config"),
+ format!(
+ r#"
+ [credential-alias]
+ "cargo:token" = ["ignored"]
+ "#,
+ )
+ .as_bytes(),
+ )
+ .unwrap();
+
+ cargo_process("login abcdefg")
+ .replace_crates_io(registry.index_url())
+ .with_stderr(
+ r#"[UPDATING] [..]
+[WARNING] credential-alias `cargo:token` (defined in `[..]`) will be ignored because it would shadow a built-in credential-provider
+[LOGIN] token for `crates-io` saved
+"#,
+ )
+ .run();
+}
diff --git a/src/tools/cargo/tests/testsuite/doc.rs b/src/tools/cargo/tests/testsuite/doc.rs
index 481df8590..a16980912 100644
--- a/src/tools/cargo/tests/testsuite/doc.rs
+++ b/src/tools/cargo/tests/testsuite/doc.rs
@@ -2004,7 +2004,7 @@ fn crate_versions() {
let output_path = p.root().join("target/doc/foo/index.html");
let output_documentation = fs::read_to_string(&output_path).unwrap();
- assert!(output_documentation.contains("Version 1.2.4"));
+ assert!(output_documentation.contains("1.2.4"));
}
#[cargo_test]
@@ -2028,7 +2028,7 @@ fn crate_versions_flag_is_overridden() {
};
let asserts = |html: String| {
assert!(!html.contains("1.2.4"));
- assert!(html.contains("Version 2.0.3"));
+ assert!(html.contains("2.0.3"));
};
p.cargo("doc")
diff --git a/src/tools/cargo/tests/testsuite/features2.rs b/src/tools/cargo/tests/testsuite/features2.rs
index 68fecb863..9238de2c6 100644
--- a/src/tools/cargo/tests/testsuite/features2.rs
+++ b/src/tools/cargo/tests/testsuite/features2.rs
@@ -1431,9 +1431,10 @@ fn edition_2021_workspace_member() {
p.cargo("check")
.with_stderr(
"\
-warning: some crates are on edition 2021 which defaults to `resolver = \"2\"`, but virtual workspaces default to `resolver = \"1\"`
+warning: virtual workspace defaulting to `resolver = \"1\"` despite one or more workspace members being on edition 2021 which implies `resolver = \"2\"`
note: to keep the current resolver, specify `workspace.resolver = \"1\"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = \"2\"` in the workspace root's manifest
+note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
[CHECKING] a v0.1.0 [..]
[FINISHED] [..]
",
diff --git a/src/tools/cargo/tests/testsuite/freshness.rs b/src/tools/cargo/tests/testsuite/freshness.rs
index f28f1ff46..d450cbbd9 100644
--- a/src/tools/cargo/tests/testsuite/freshness.rs
+++ b/src/tools/cargo/tests/testsuite/freshness.rs
@@ -2786,7 +2786,7 @@ fn verify_source_before_recompile() {
"vendor/bar/src/lib.rs",
r#"compile_error!("You shall not pass!");"#,
);
- // Should ignore modifed sources without any recompile.
+ // Should ignore modified sources without any recompile.
p.cargo("check --verbose")
.with_stderr(
"\
@@ -2799,7 +2799,7 @@ fn verify_source_before_recompile() {
// Add a `RUSTFLAGS` to trigger a recompile.
//
- // Cargo should refuse to build because of checksum verfication failure.
+ // Cargo should refuse to build because of checksum verification failure.
// Cargo shouldn't recompile dependency `bar`.
p.cargo("check --verbose")
.env("RUSTFLAGS", "-W warnings")
diff --git a/src/tools/cargo/tests/testsuite/future_incompat_report.rs b/src/tools/cargo/tests/testsuite/future_incompat_report.rs
index 4d2c66d17..c52bf25a9 100644
--- a/src/tools/cargo/tests/testsuite/future_incompat_report.rs
+++ b/src/tools/cargo/tests/testsuite/future_incompat_report.rs
@@ -369,7 +369,7 @@ fn suggestions_for_updates() {
// project or something). This could use some more consideration of how to
// handle this better (maybe only trigger an update if it hasn't updated
// in a long while?).
- p.cargo("update -p without_updates").run();
+ p.cargo("update without_updates").run();
let update_message = "\
- Some affected dependencies have newer versions available.
diff --git a/src/tools/cargo/tests/testsuite/git.rs b/src/tools/cargo/tests/testsuite/git.rs
index f60ee978a..e27315346 100644
--- a/src/tools/cargo/tests/testsuite/git.rs
+++ b/src/tools/cargo/tests/testsuite/git.rs
@@ -742,11 +742,11 @@ fn update_with_shared_deps() {
// By default, not transitive updates
println!("dep1 update");
- p.cargo("update -p dep1").with_stdout("").run();
+ p.cargo("update dep1").with_stdout("").run();
// Don't do anything bad on a weird --precise argument
println!("bar bad precise update");
- p.cargo("update -p bar --precise 0.1.2")
+ p.cargo("update bar --precise 0.1.2")
.with_status(101)
.with_stderr(
"\
@@ -764,14 +764,14 @@ Caused by:
// Specifying a precise rev to the old rev shouldn't actually update
// anything because we already have the rev in the db.
println!("bar precise update");
- p.cargo("update -p bar --precise")
+ p.cargo("update bar --precise")
.arg(&old_head.to_string())
.with_stdout("")
.run();
- // Updating aggressively should, however, update the repo.
- println!("dep1 aggressive update");
- p.cargo("update -p dep1 --aggressive")
+ // Updating recursively should, however, update the repo.
+ println!("dep1 recursive update");
+ p.cargo("update dep1 --recursive")
.with_stderr(&format!(
"[UPDATING] git repository `{}`\n\
[UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
@@ -795,7 +795,7 @@ Caused by:
.run();
// We should be able to update transitive deps
- p.cargo("update -p bar")
+ p.cargo("update bar")
.with_stderr(&format!(
"[UPDATING] git repository `{}`",
git_project.url()
@@ -1183,7 +1183,7 @@ fn two_deps_only_update_one() {
let oid = git::commit(&repo);
println!("dep1 head sha: {}", oid_to_short_sha(oid));
- p.cargo("update -p dep1")
+ p.cargo("update dep1")
.with_stderr(&format!(
"[UPDATING] git repository `{}`\n\
[UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
@@ -1881,14 +1881,14 @@ fn update_ambiguous() {
.build();
p.cargo("generate-lockfile").run();
- p.cargo("update -p bar")
+ p.cargo("update bar")
.with_status(101)
.with_stderr(
"\
[ERROR] There are multiple `bar` packages in your project, and the specification `bar` \
is ambiguous.
-Please re-run this command with `-p <spec>` where `<spec>` is one of the \
-following:
+Please re-run this command with one of the \
+following specifications:
bar@0.[..].0
bar@0.[..].0
",
@@ -1928,7 +1928,7 @@ fn update_one_dep_in_repo_with_many_deps() {
.build();
p.cargo("generate-lockfile").run();
- p.cargo("update -p bar")
+ p.cargo("update bar")
.with_stderr(&format!("[UPDATING] git repository `{}`", bar.url()))
.run();
}
@@ -2091,7 +2091,7 @@ fn update_one_source_updates_all_packages_in_that_git_source() {
git::add(&repo);
git::commit(&repo);
- p.cargo("update -p dep").run();
+ p.cargo("update dep").run();
let lockfile = p.read_lockfile();
assert!(
!lockfile.contains(&rev1.to_string()),
@@ -2578,9 +2578,6 @@ Caused by:
failed to parse manifest at `[..]`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 8, column 21
|
8 | categories = [\"algorithms\"]
diff --git a/src/tools/cargo/tests/testsuite/inheritable_workspace_fields.rs b/src/tools/cargo/tests/testsuite/inheritable_workspace_fields.rs
index cc261a47f..47437102a 100644
--- a/src/tools/cargo/tests/testsuite/inheritable_workspace_fields.rs
+++ b/src/tools/cargo/tests/testsuite/inheritable_workspace_fields.rs
@@ -1234,8 +1234,11 @@ fn error_workspace_false() {
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
Caused by:
+ TOML parse error at line 7, column 41
+ |
+ 7 | description = { workspace = false }
+ | ^^^^^
`workspace` cannot be false
- in `package.description.workspace`
",
)
.run();
@@ -1323,9 +1326,6 @@ fn error_malformed_workspace_root() {
Caused by:
[..]
-
-Caused by:
- [..]
|
3 | members = [invalid toml
| ^
diff --git a/src/tools/cargo/tests/testsuite/install.rs b/src/tools/cargo/tests/testsuite/install.rs
index 0c7fc5037..0a3670e6c 100644
--- a/src/tools/cargo/tests/testsuite/install.rs
+++ b/src/tools/cargo/tests/testsuite/install.rs
@@ -72,6 +72,18 @@ fn toolchain() {
}
#[cargo_test]
+fn url() {
+ pkg("foo", "0.0.1");
+ cargo_process("install https://github.com/bar/foo")
+ .with_status(101)
+ .with_stderr(
+ "\
+[ERROR] invalid package name: `https://github.com/bar/foo`
+ Use `cargo install --git https://github.com/bar/foo` if you meant to install from a git repository.")
+ .run();
+}
+
+#[cargo_test]
fn simple_with_message_format() {
pkg("foo", "0.0.1");
@@ -1600,8 +1612,13 @@ fn inline_version_without_name() {
pkg("foo", "0.1.2");
cargo_process("install @0.1.1")
- .with_status(101)
- .with_stderr("error: missing crate name for `@0.1.1`")
+ .with_status(1)
+ .with_stderr(
+ "error: invalid value '@0.1.1' for '[crate]...': missing crate name before '@'
+
+For more information, try '--help'.
+",
+ )
.run();
}
@@ -1612,7 +1629,7 @@ fn inline_and_explicit_version() {
cargo_process("install foo@0.1.1 --version 0.1.1")
.with_status(101)
- .with_stderr("error: cannot specify both `@0.1.1` and `--version`")
+ .with_stderr("error: cannot specify both `@<VERSION>` and `--version <VERSION>`")
.run();
}
@@ -1827,7 +1844,7 @@ fn install_empty_argument() {
cargo_process("install")
.arg("")
.with_status(1)
- .with_stderr_contains("[ERROR] a value is required for '[crate]...' but none was supplied")
+ .with_stderr_contains("[ERROR] invalid value '' for '[crate]...': crate name is empty")
.run();
}
@@ -2275,9 +2292,9 @@ fn failed_install_retains_temp_directory() {
.unwrap();
// Find the path in the output.
- let start = stderr.find("found at `").unwrap() + 10;
- let end = stderr[start..].find('.').unwrap() - 1;
- let path = Path::new(&stderr[start..(end + start)]);
+ let stderr = stderr.split_once("found at `").unwrap().1;
+ let end = stderr.find('.').unwrap() - 1;
+ let path = Path::new(&stderr[..end]);
assert!(path.exists());
assert!(path.join("release/deps").exists());
}
@@ -2426,3 +2443,23 @@ fn ambiguous_registry_vs_local_package() {
.run();
assert_has_installed_exe(cargo_home(), "foo");
}
+
+#[cargo_test]
+fn install_with_redundant_default_mode() {
+ pkg("foo", "0.0.1");
+
+ cargo_process("install foo --release")
+ .with_stderr(
+ "\
+error: unexpected argument '--release' found
+
+ tip: `--release` is the default for `cargo install`; instead `--debug` is supported
+
+Usage: cargo[EXE] install [OPTIONS] [crate]...
+
+For more information, try '--help'.
+",
+ )
+ .with_status(1)
+ .run();
+}
diff --git a/src/tools/cargo/tests/testsuite/install_upgrade.rs b/src/tools/cargo/tests/testsuite/install_upgrade.rs
index ae641ba98..580117f5c 100644
--- a/src/tools/cargo/tests/testsuite/install_upgrade.rs
+++ b/src/tools/cargo/tests/testsuite/install_upgrade.rs
@@ -230,12 +230,14 @@ fn ambiguous_version_no_longer_allowed() {
cargo_process("install foo --version=1.0")
.with_stderr(
"\
-[ERROR] the `--version` provided, `1.0`, is not a valid semver version: cannot parse '1.0' as a semver
+[ERROR] invalid value '1.0' for '--version <VERSION>': cannot parse '1.0' as a SemVer version
-if you want to specify semver range, add an explicit qualifier, like ^1.0
+ tip: if you want to specify SemVer range, add an explicit qualifier, like '^1.0'
+
+For more information, try '--help'.
",
)
- .with_status(101)
+ .with_status(1)
.run();
}
diff --git a/src/tools/cargo/tests/testsuite/lints.rs b/src/tools/cargo/tests/testsuite/lints.rs
index 854de69e9..21139d00a 100644
--- a/src/tools/cargo/tests/testsuite/lints.rs
+++ b/src/tools/cargo/tests/testsuite/lints.rs
@@ -4,72 +4,6 @@ use cargo_test_support::project;
use cargo_test_support::registry::Package;
#[cargo_test]
-fn package_requires_option() {
- let foo = project()
- .file(
- "Cargo.toml",
- r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [lints.rust]
- unsafe_code = "forbid"
- "#,
- )
- .file("src/lib.rs", "")
- .build();
-
- foo.cargo("check")
- .with_stderr(
- "\
-warning: unused manifest key `lints` (may be supported in a future version)
-
-this Cargo does not support nightly features, but if you
-switch to nightly channel you can pass
-`-Zlints` to enable this feature.
-[CHECKING] [..]
-[FINISHED] [..]
-",
- )
- .run();
-}
-
-#[cargo_test]
-fn workspace_requires_option() {
- let foo = project()
- .file(
- "Cargo.toml",
- r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
-
- [workspace.lints.rust]
- unsafe_code = "forbid"
- "#,
- )
- .file("src/lib.rs", "")
- .build();
-
- foo.cargo("check")
- .with_stderr(
- "\
-warning: [CWD]/Cargo.toml: unused manifest key `lints` (may be supported in a future version)
-
-this Cargo does not support nightly features, but if you
-switch to nightly channel you can pass
-`-Zlints` to enable this feature.
-[CHECKING] [..]
-[FINISHED] [..]
-",
- )
- .run();
-}
-
-#[cargo_test]
fn dependency_warning_ignored() {
let foo = project()
.file(
@@ -133,53 +67,55 @@ fn malformed_on_stable() {
.build();
foo.cargo("check")
+ .with_status(101)
.with_stderr(
"\
-warning: unused manifest key `lints` (may be supported in a future version)
+error: failed to parse manifest[..]
-this Cargo does not support nightly features, but if you
-switch to nightly channel you can pass
-`-Zlints` to enable this feature.
-[CHECKING] [..]
-[FINISHED] [..]
+Caused by:
+ TOML parse error at line 2, column 25
+ |
+ 2 | lints = 20
+ | ^^
+ invalid type: integer `20`, expected a lints table
",
)
.run();
}
#[cargo_test]
-fn malformed_on_nightly() {
+fn fail_on_invalid_tool() {
let foo = project()
.file(
"Cargo.toml",
r#"
- lints = 20
[package]
name = "foo"
version = "0.0.1"
authors = []
+ [workspace.lints.super-awesome-linter]
+ unsafe_code = "forbid"
"#,
)
.file("src/lib.rs", "")
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr(
"\
-error: failed to parse manifest[..]
+[..]
Caused by:
- invalid type: integer `20`, expected a map
+ unsupported `super-awesome-linter` in `[lints]`, must be one of rust, clippy, rustdoc
",
)
.run();
}
#[cargo_test]
-fn fail_on_invalid_tool() {
+fn invalid_type_in_lint_value() {
let foo = project()
.file(
"Cargo.toml",
@@ -187,24 +123,26 @@ fn fail_on_invalid_tool() {
[package]
name = "foo"
version = "0.0.1"
- authors = []
- [workspace.lints.super-awesome-linter]
- unsafe_code = "forbid"
+ [workspace.lints.rust]
+ rust-2018-idioms = -1
"#,
)
.file("src/lib.rs", "")
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr(
"\
-[..]
+error: failed to parse manifest at `[..]/Cargo.toml`
Caused by:
- unsupported `super-awesome-linter` in `[lints]`, must be one of rust, clippy, rustdoc
+ TOML parse error at line 7, column 36
+ |
+ 7 | rust-2018-idioms = -1
+ | ^^
+ invalid type: integer `-1`, expected a string or map
",
)
.run();
@@ -228,8 +166,7 @@ fn fail_on_tool_injection() {
.file("src/lib.rs", "")
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr(
"\
@@ -260,8 +197,7 @@ fn fail_on_redundant_tool() {
.file("src/lib.rs", "")
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr(
"\
@@ -292,8 +228,7 @@ fn fail_on_conflicting_tool() {
.file("src/lib.rs", "")
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr(
"\
@@ -331,8 +266,7 @@ pub fn foo(num: i32) -> u32 {
)
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr_contains(
"\
@@ -370,8 +304,7 @@ pub fn foo(num: i32) -> u32 {
)
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr_contains(
"\
@@ -382,6 +315,49 @@ error: usage of an `unsafe` block
}
#[cargo_test]
+fn workspace_and_package_lints() {
+ let foo = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lints]
+ workspace = true
+ [lints.rust]
+ "unsafe_code" = "allow"
+
+ [workspace.lints.rust]
+ "unsafe_code" = "deny"
+ "#,
+ )
+ .file(
+ "src/lib.rs",
+ "
+pub fn foo(num: i32) -> u32 {
+ unsafe { std::mem::transmute(num) }
+}
+",
+ )
+ .build();
+
+ foo.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
+
+Caused by:
+ cannot override `workspace.lints` in `lints`, either remove the overrides or `lints.workspace = true` and manually specify the lints
+",
+ )
+ .run();
+}
+
+#[cargo_test]
fn attribute_has_precedence() {
let foo = project()
.file(
@@ -408,9 +384,8 @@ pub fn foo(num: i32) -> u32 {
)
.build();
- foo.cargo("check -Zlints")
+ foo.cargo("check")
.arg("-v") // Show order of rustflags on failure
- .masquerade_as_nightly_cargo(&["lints"])
.run();
}
@@ -439,10 +414,9 @@ pub fn foo(num: i32) -> u32 {
)
.build();
- foo.cargo("check -Zlints")
+ foo.cargo("check")
.arg("-v") // Show order of rustflags on failure
.env("RUSTFLAGS", "-Aunsafe_code")
- .masquerade_as_nightly_cargo(&["lints"])
.run();
}
@@ -475,9 +449,9 @@ pub fn foo(num: i32) -> u32 {
)
.build();
- foo.cargo("check -Zlints")
+ foo.cargo("check")
.arg("-v") // Show order of rustflags on failure
- .masquerade_as_nightly_cargo(&["lints", "profile-rustflags"])
+ .masquerade_as_nightly_cargo(&["profile-rustflags"])
.run();
}
@@ -512,9 +486,8 @@ pub fn foo(num: i32) -> u32 {
)
.build();
- foo.cargo("check -Zlints")
+ foo.cargo("check")
.arg("-v") // Show order of rustflags on failure
- .masquerade_as_nightly_cargo(&["lints"])
.run();
}
@@ -552,8 +525,7 @@ pub fn foo() -> u32 {
)
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_status(101)
.with_stderr_contains(
"\
@@ -597,9 +569,7 @@ pub fn foo() -> u32 {
)
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
- .run();
+ foo.cargo("check").run();
}
#[cargo_test]
@@ -627,8 +597,7 @@ pub fn foo() -> u32 {
)
.build();
- foo.cargo("doc -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("doc")
.with_status(101)
.with_stderr_contains(
"\
@@ -671,8 +640,7 @@ pub const Ĕ: i32 = 2;
)
.build();
- foo.cargo("check -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("check")
.with_stderr(
"\
[CHECKING] foo v0.0.1 ([CWD])
@@ -681,8 +649,7 @@ pub const Ĕ: i32 = 2;
)
.run();
- foo.cargo("test --doc -Zlints")
- .masquerade_as_nightly_cargo(&["lints"])
+ foo.cargo("test --doc")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
diff --git a/src/tools/cargo/tests/testsuite/list_availables.rs b/src/tools/cargo/tests/testsuite/list_availables.rs
index 6bbbeb160..fe635a19b 100644
--- a/src/tools/cargo/tests/testsuite/list_availables.rs
+++ b/src/tools/cargo/tests/testsuite/list_availables.rs
@@ -8,6 +8,7 @@ const BIN: u8 = 1 << 1;
const TEST: u8 = 1 << 2;
const BENCH: u8 = 1 << 3;
const PACKAGE: u8 = 1 << 4;
+const TARGET: u8 = 1 << 5;
fn list_availables_test(command: &str, targets: u8) {
let full_project = project()
@@ -159,56 +160,70 @@ No tests available.
.with_status(101)
.run();
}
+
+ if targets & TARGET != 0 {
+ empty_project
+ .cargo(&format!("{} --target", command))
+ .with_stderr(
+ "\
+error: \"--target\" takes a target architecture as an argument.
+
+Run `[..]` to see possible targets.
+",
+ )
+ .with_status(101)
+ .run();
+ }
}
#[cargo_test]
fn build_list_availables() {
- list_availables_test("build", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
+ list_availables_test("build", EXAMPLE | BIN | TEST | BENCH | PACKAGE | TARGET);
}
#[cargo_test]
fn check_list_availables() {
- list_availables_test("check", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
+ list_availables_test("check", EXAMPLE | BIN | TEST | BENCH | PACKAGE | TARGET);
}
#[cargo_test]
fn doc_list_availables() {
- list_availables_test("doc", BIN | PACKAGE);
+ list_availables_test("doc", BIN | PACKAGE | TARGET);
}
#[cargo_test]
fn fix_list_availables() {
- list_availables_test("fix", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
+ list_availables_test("fix", EXAMPLE | BIN | TEST | BENCH | PACKAGE | TARGET);
}
#[cargo_test]
fn run_list_availables() {
- list_availables_test("run", EXAMPLE | BIN | PACKAGE);
+ list_availables_test("run", EXAMPLE | BIN | PACKAGE | TARGET);
}
#[cargo_test]
fn test_list_availables() {
- list_availables_test("test", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
+ list_availables_test("test", EXAMPLE | BIN | TEST | BENCH | PACKAGE | TARGET);
}
#[cargo_test]
fn bench_list_availables() {
- list_availables_test("bench", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
+ list_availables_test("bench", EXAMPLE | BIN | TEST | BENCH | PACKAGE | TARGET);
}
#[cargo_test]
fn install_list_availables() {
- list_availables_test("install", EXAMPLE | BIN);
+ list_availables_test("install", EXAMPLE | BIN | TARGET);
}
#[cargo_test]
fn rustdoc_list_availables() {
- list_availables_test("rustdoc", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
+ list_availables_test("rustdoc", EXAMPLE | BIN | TEST | BENCH | PACKAGE | TARGET);
}
#[cargo_test]
fn rustc_list_availables() {
- list_availables_test("rustc", EXAMPLE | BIN | TEST | BENCH | PACKAGE);
+ list_availables_test("rustc", EXAMPLE | BIN | TEST | BENCH | PACKAGE | TARGET);
}
#[cargo_test]
@@ -218,12 +233,12 @@ fn pkgid_list_availables() {
#[cargo_test]
fn tree_list_availables() {
- list_availables_test("tree", PACKAGE);
+ list_availables_test("tree", PACKAGE | TARGET);
}
#[cargo_test]
fn clean_list_availables() {
- list_availables_test("clean", PACKAGE);
+ list_availables_test("clean", PACKAGE | TARGET);
}
#[cargo_test]
diff --git a/src/tools/cargo/tests/testsuite/login.rs b/src/tools/cargo/tests/testsuite/login.rs
index 16bd29dce..0eec734ce 100644
--- a/src/tools/cargo/tests/testsuite/login.rs
+++ b/src/tools/cargo/tests/testsuite/login.rs
@@ -197,8 +197,8 @@ fn bad_asymmetric_token_args() {
.build();
// These cases are kept brief as the implementation is covered by clap, so this is only smoke testing that we have clap configured correctly.
- cargo_process("login -Zcredential-process -- --key-subject")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login -Zasymmetric-token -- --key-subject")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.replace_crates_io(registry.index_url())
.with_stderr_contains(
" error: a value is required for '--key-subject <SUBJECT>' but none was supplied",
@@ -228,8 +228,8 @@ fn login_with_asymmetric_token_and_subject_on_stdin() {
.no_configure_token()
.build();
let credentials = credentials_toml();
- cargo_process("login -v -Z credential-process -- --key-subject=foo")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login -v -Z asymmetric-token -- --key-subject=foo")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.replace_crates_io(registry.index_url())
.with_stderr_contains(
"\
@@ -286,8 +286,8 @@ fn login_with_asymmetric_token_on_stdin() {
.no_configure_token()
.build();
let credentials = credentials_toml();
- cargo_process("login -vZ credential-process --registry alternative")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login -v -Z asymmetric-token --registry alternative")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.with_stderr(
"\
[UPDATING] [..]
@@ -308,8 +308,8 @@ fn login_with_generate_asymmetric_token() {
.no_configure_token()
.build();
let credentials = credentials_toml();
- cargo_process("login -Z credential-process --registry alternative")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ cargo_process("login -Z asymmetric-token --registry alternative")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.with_stderr("[UPDATING] `alternative` index\nk3.public.[..]")
.run();
let credentials = fs::read_to_string(&credentials).unwrap();
diff --git a/src/tools/cargo/tests/testsuite/logout.rs b/src/tools/cargo/tests/testsuite/logout.rs
index 7b5e10de2..6829cec2a 100644
--- a/src/tools/cargo/tests/testsuite/logout.rs
+++ b/src/tools/cargo/tests/testsuite/logout.rs
@@ -83,8 +83,7 @@ fn default_registry_configured() {
check_token(Some("dummy-token"), Some("dummy-registry"));
check_token(Some("crates-io-token"), None);
- cargo_process("logout -Zunstable-options")
- .masquerade_as_nightly_cargo(&["cargo-logout"])
+ cargo_process("logout")
.with_stderr(
"\
[LOGOUT] token for `dummy-registry` has been removed from local storage
@@ -97,8 +96,24 @@ fn default_registry_configured() {
check_token(None, Some("dummy-registry"));
check_token(Some("crates-io-token"), None);
- cargo_process("logout -Zunstable-options")
- .masquerade_as_nightly_cargo(&["cargo-logout"])
+ cargo_process("logout")
.with_stderr("[LOGOUT] not currently logged in to `dummy-registry`")
.run();
}
+
+#[cargo_test]
+fn logout_asymmetric() {
+ let _registry = registry::RegistryBuilder::new()
+ .token(cargo_test_support::registry::Token::rfc_key())
+ .build();
+
+ cargo_process("logout --registry crates-io -Zasymmetric-token")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
+ .with_stderr("[LOGOUT] secret-key for `crates-io` has been removed from local storage")
+ .run();
+
+ cargo_process("logout --registry crates-io -Zasymmetric-token")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
+ .with_stderr("[LOGOUT] not currently logged in to `crates-io`")
+ .run();
+}
diff --git a/src/tools/cargo/tests/testsuite/lto.rs b/src/tools/cargo/tests/testsuite/lto.rs
index 40b4f7ca2..b4972a64d 100644
--- a/src/tools/cargo/tests/testsuite/lto.rs
+++ b/src/tools/cargo/tests/testsuite/lto.rs
@@ -453,10 +453,8 @@ fn verify_lto(output: &Output, krate: &str, krate_info: &str, expected_lto: Lto)
krate, krate_info, line, line2, stderr
);
}
- let actual_lto = if let Some(index) = line.find("-C lto=") {
- let s = &line[index..];
- let end = s.find(' ').unwrap();
- let mode = &line[index..index + end];
+ let actual_lto = if let Some((_, line)) = line.split_once("-C lto=") {
+ let mode = line.splitn(2, ' ').next().unwrap();
if mode == "off" {
Lto::Off
} else {
diff --git a/src/tools/cargo/tests/testsuite/metadata.rs b/src/tools/cargo/tests/testsuite/metadata.rs
index ac2cec396..fbead4dea 100644
--- a/src/tools/cargo/tests/testsuite/metadata.rs
+++ b/src/tools/cargo/tests/testsuite/metadata.rs
@@ -1821,8 +1821,11 @@ fn cargo_metadata_with_invalid_authors_field() {
r#"[ERROR] failed to parse manifest at `[..]`
Caused by:
- invalid type: string "", expected a vector of strings or workspace
- in `package.authors`"#,
+ TOML parse error at line 3, column 27
+ |
+ 3 | authors = ""
+ | ^^
+ invalid type: string "", expected a vector of strings or workspace"#,
)
.run();
}
@@ -1846,8 +1849,11 @@ fn cargo_metadata_with_invalid_version_field() {
r#"[ERROR] failed to parse manifest at `[..]`
Caused by:
- invalid type: integer `1`, expected SemVer version
- in `package.version`"#,
+ TOML parse error at line 3, column 27
+ |
+ 3 | version = 1
+ | ^
+ invalid type: integer `1`, expected SemVer version"#,
)
.run();
}
@@ -1871,8 +1877,11 @@ fn cargo_metadata_with_invalid_publish_field() {
r#"[ERROR] failed to parse manifest at `[..]`
Caused by:
- invalid type: string "foo", expected a boolean, a vector of strings, or workspace
- in `package.publish`"#,
+ TOML parse error at line 3, column 27
+ |
+ 3 | publish = "foo"
+ | ^^^^^
+ invalid type: string "foo", expected a boolean, a vector of strings, or workspace"#,
)
.run();
}
diff --git a/src/tools/cargo/tests/testsuite/new.rs b/src/tools/cargo/tests/testsuite/new.rs
index b9ddcf2d7..91a2871e9 100644
--- a/src/tools/cargo/tests/testsuite/new.rs
+++ b/src/tools/cargo/tests/testsuite/new.rs
@@ -95,7 +95,7 @@ fn simple_git() {
let fp = paths::root().join("foo/.gitignore");
let contents = fs::read_to_string(&fp).unwrap();
- assert_eq!(contents, "/target\n/Cargo.lock\n",);
+ assert_eq!(contents, "/target\n",);
cargo_process("build").cwd(&paths::root().join("foo")).run();
}
@@ -112,7 +112,7 @@ fn simple_hg() {
let fp = paths::root().join("foo/.hgignore");
let contents = fs::read_to_string(&fp).unwrap();
- assert_eq!(contents, "^target$\n^Cargo.lock$\n",);
+ assert_eq!(contents, "^target$\n",);
cargo_process("build").cwd(&paths::root().join("foo")).run();
}
diff --git a/src/tools/cargo/tests/testsuite/offline.rs b/src/tools/cargo/tests/testsuite/offline.rs
index 5f164dbeb..e68425319 100644
--- a/src/tools/cargo/tests/testsuite/offline.rs
+++ b/src/tools/cargo/tests/testsuite/offline.rs
@@ -673,7 +673,7 @@ fn main(){
.with_stdout("1.2.9")
.run();
// updates happen without updating the index
- p2.cargo("update -p present_dep --precise 1.2.3 --offline")
+ p2.cargo("update present_dep --precise 1.2.3 --offline")
.with_status(0)
.with_stderr(
"\
@@ -706,7 +706,7 @@ fn main(){
.run();
// No v1.2.8 loaded into the cache so expect failure.
- p2.cargo("update -p present_dep --precise 1.2.8 --offline")
+ p2.cargo("update present_dep --precise 1.2.8 --offline")
.with_status(101)
.with_stderr(
"\
diff --git a/src/tools/cargo/tests/testsuite/owner.rs b/src/tools/cargo/tests/testsuite/owner.rs
index 7b38bcc5e..fc0e0b5c4 100644
--- a/src/tools/cargo/tests/testsuite/owner.rs
+++ b/src/tools/cargo/tests/testsuite/owner.rs
@@ -117,8 +117,8 @@ fn simple_add_with_asymmetric() {
// The http_api server will check that the authorization is correct.
// If the authorization was not sent then we would get an unauthorized error.
p.cargo("owner -a username")
- .arg("-Zcredential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ .arg("-Zasymmetric-token")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.replace_crates_io(registry.index_url())
.with_status(0)
.run();
@@ -184,9 +184,9 @@ fn simple_remove_with_asymmetric() {
// The http_api server will check that the authorization is correct.
// If the authorization was not sent then we would get an unauthorized error.
p.cargo("owner -r username")
- .arg("-Zcredential-process")
+ .arg("-Zasymmetric-token")
.replace_crates_io(registry.index_url())
- .masquerade_as_nightly_cargo(&["credential-process"])
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.with_status(0)
.run();
}
diff --git a/src/tools/cargo/tests/testsuite/patch.rs b/src/tools/cargo/tests/testsuite/patch.rs
index f2f077d7d..a467f60b5 100644
--- a/src/tools/cargo/tests/testsuite/patch.rs
+++ b/src/tools/cargo/tests/testsuite/patch.rs
@@ -1965,8 +1965,8 @@ fn update_unused_new_version() {
// Restore the lock file, and see if `update` will work, too.
fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap();
- // Try `update -p`.
- p.cargo("update -p bar")
+ // Try `update <pkg>`.
+ p.cargo("update bar")
.with_stderr(
"\
[UPDATING] `dummy-registry` index
@@ -2425,7 +2425,7 @@ fn can_update_with_alt_reg() {
p.cargo("check").with_stderr("[FINISHED] [..]").run();
// This does nothing, due to `=` requirement.
- p.cargo("update -p bar")
+ p.cargo("update bar")
.with_stderr(
"\
[UPDATING] `alternative` index
@@ -2658,3 +2658,45 @@ failed to select a version for `qux` which could resolve this conflict"#,
)
.run();
}
+
+#[cargo_test]
+fn mismatched_version_with_prerelease() {
+ Package::new("prerelease-deps", "0.0.1").publish();
+ // A patch to a location that has an prerelease version
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ prerelease-deps = "0.1.0"
+
+ [patch.crates-io]
+ prerelease-deps = { path = "./prerelease-deps" }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file(
+ "prerelease-deps/Cargo.toml",
+ &basic_manifest("prerelease-deps", "0.1.1-pre1"),
+ )
+ .file("prerelease-deps/src/lib.rs", "")
+ .build();
+
+ p.cargo("generate-lockfile")
+ .with_status(101)
+ .with_stderr(
+ r#"[UPDATING] `dummy-registry` index
+[ERROR] failed to select a version for the requirement `prerelease-deps = "^0.1.0"`
+candidate versions found which didn't match: 0.1.1-pre1, 0.0.1
+location searched: `dummy-registry` index (which is replacing registry `crates-io`)
+required by package `foo v0.1.0 [..]`
+if you are looking for the prerelease package it needs to be specified explicitly
+ prerelease-deps = { version = "0.1.1-pre1" }
+perhaps a crate was updated and forgotten to be re-vendored?"#,
+ )
+ .run();
+}
diff --git a/src/tools/cargo/tests/testsuite/pkgid.rs b/src/tools/cargo/tests/testsuite/pkgid.rs
index 3e3e4692a..88d991e80 100644
--- a/src/tools/cargo/tests/testsuite/pkgid.rs
+++ b/src/tools/cargo/tests/testsuite/pkgid.rs
@@ -4,22 +4,31 @@ use cargo_test_support::project;
use cargo_test_support::registry::Package;
#[cargo_test]
-fn simple() {
- Package::new("bar", "0.1.0").publish();
+fn local() {
let p = project()
.file(
"Cargo.toml",
r#"
+ [workspace]
+ members = ["bar"]
+
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
-
- [dependencies]
- bar = "0.1.0"
"#,
)
.file("src/main.rs", "fn main() {}")
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+ edition = "2018"
+ "#,
+ )
+ .file("bar/src/main.rs", "fn main() {}")
.build();
p.cargo("generate-lockfile").run();
@@ -28,16 +37,38 @@ fn simple() {
.with_stdout(format!("file://[..]{}#0.1.0", p.root().to_str().unwrap()))
.run();
- p.cargo("pkgid bar")
- .with_stdout("https://github.com/rust-lang/crates.io-index#bar@0.1.0")
+ // Bad file URL.
+ p.cargo("pkgid ./Cargo.toml")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: invalid package ID specification: `./Cargo.toml`
+
+Caused by:
+ package ID specification `./Cargo.toml` looks like a file path, maybe try file://[..]/Cargo.toml
+",
+ )
+ .run();
+
+ // Bad file URL with similar name.
+ p.cargo("pkgid './bar'")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: invalid package ID specification: `./bar`
+
+<tab>Did you mean `bar`?
+
+Caused by:
+ package ID specification `./bar` looks like a file path, maybe try file://[..]/bar
+",
+ )
.run();
}
#[cargo_test]
-fn suggestion_bad_pkgid() {
+fn registry() {
Package::new("crates-io", "0.1.0").publish();
- Package::new("two-ver", "0.1.0").publish();
- Package::new("two-ver", "0.2.0").publish();
let p = project()
.file(
"Cargo.toml",
@@ -49,16 +80,18 @@ fn suggestion_bad_pkgid() {
[dependencies]
crates-io = "0.1.0"
- two-ver = "0.1.0"
- two-ver2 = { package = "two-ver", version = "0.2.0" }
"#,
)
- .file("src/lib.rs", "")
+ .file("src/main.rs", "fn main() {}")
.file("cratesio", "")
.build();
p.cargo("generate-lockfile").run();
+ p.cargo("pkgid crates-io")
+ .with_stdout("https://github.com/rust-lang/crates.io-index#crates-io@0.1.0")
+ .run();
+
// Bad URL.
p.cargo("pkgid https://example.com/crates-io")
.with_status(101)
@@ -83,45 +116,81 @@ error: package ID specification `crates_io` did not match any packages
",
)
.run();
+}
- // Bad version.
- p.cargo("pkgid two-ver:0.3.0")
+#[cargo_test]
+fn multiple_versions() {
+ Package::new("two-ver", "0.1.0").publish();
+ Package::new("two-ver", "0.2.0").publish();
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ edition = "2018"
+
+ [dependencies]
+ two-ver = "0.1.0"
+ two-ver2 = { package = "two-ver", version = "0.2.0" }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("cratesio", "")
+ .build();
+
+ p.cargo("generate-lockfile").run();
+
+ p.cargo("pkgid two-ver:0.2.0")
+ .with_stdout("https://github.com/rust-lang/crates.io-index#two-ver@0.2.0")
+ .run();
+
+ // Incomplete version.
+ p.cargo("pkgid two-ver@0")
.with_status(101)
.with_stderr(
"\
-error: package ID specification `two-ver@0.3.0` did not match any packages
-Did you mean one of these?
-
+error: There are multiple `two-ver` packages in your project, and the specification `two-ver@0` is ambiguous.
+Please re-run this command with one of the following specifications:
two-ver@0.1.0
two-ver@0.2.0
",
)
.run();
- // Bad file URL.
- p.cargo("pkgid ./Cargo.toml")
+ // Incomplete version.
+ p.cargo("pkgid two-ver@0.2")
+ .with_stdout(
+ "\
+https://github.com/rust-lang/crates.io-index#two-ver@0.2.0
+",
+ )
+ .run();
+
+ // Ambiguous.
+ p.cargo("pkgid two-ver")
.with_status(101)
.with_stderr(
"\
-error: invalid package ID specification: `./Cargo.toml`
-
-Caused by:
- package ID specification `./Cargo.toml` looks like a file path, maybe try file://[..]/Cargo.toml
+error: There are multiple `two-ver` packages in your project, and the specification `two-ver` is ambiguous.
+Please re-run this command with one of the following specifications:
+ two-ver@0.1.0
+ two-ver@0.2.0
",
)
.run();
- // Bad file URL with similar name.
- p.cargo("pkgid './cratesio'")
+ // Bad version.
+ p.cargo("pkgid two-ver:0.3.0")
.with_status(101)
.with_stderr(
"\
-error: invalid package ID specification: `./cratesio`
-
-<tab>Did you mean `crates-io`?
+error: package ID specification `two-ver@0.3.0` did not match any packages
+Did you mean one of these?
-Caused by:
- package ID specification `./cratesio` looks like a file path, maybe try file://[..]/cratesio
+ two-ver@0.1.0
+ two-ver@0.2.0
",
)
.run();
diff --git a/src/tools/cargo/tests/testsuite/profile_config.rs b/src/tools/cargo/tests/testsuite/profile_config.rs
index 26104e7e7..143c050f9 100644
--- a/src/tools/cargo/tests/testsuite/profile_config.rs
+++ b/src/tools/cargo/tests/testsuite/profile_config.rs
@@ -370,7 +370,7 @@ fn profile_config_mixed_types() {
#[cargo_test]
fn named_config_profile() {
- // Exercises config named profies.
+ // Exercises config named profiles.
// foo -> middle -> bar -> dev
// middle exists in Cargo.toml, the others in .cargo/config
use super::config::ConfigBuilder;
@@ -427,7 +427,7 @@ fn named_config_profile() {
let ws = Workspace::new(&paths::root().join("Cargo.toml"), &config).unwrap();
let profiles = Profiles::new(&ws, profile_name).unwrap();
- let crates_io = cargo::core::source::SourceId::crates_io(&config).unwrap();
+ let crates_io = cargo::core::SourceId::crates_io(&config).unwrap();
let a_pkg = PackageId::new("a", "0.1.0", crates_io).unwrap();
let dep_pkg = PackageId::new("dep", "0.1.0", crates_io).unwrap();
diff --git a/src/tools/cargo/tests/testsuite/profile_custom.rs b/src/tools/cargo/tests/testsuite/profile_custom.rs
index ea6b54c95..f7139e552 100644
--- a/src/tools/cargo/tests/testsuite/profile_custom.rs
+++ b/src/tools/cargo/tests/testsuite/profile_custom.rs
@@ -543,7 +543,9 @@ fn clean_custom_dirname() {
assert!(!p.build_dir().join("release").is_dir());
// This should clean 'other'
- p.cargo("clean --profile=other").with_stderr("").run();
+ p.cargo("clean --profile=other")
+ .with_stderr("[REMOVED] [..] files, [..] total")
+ .run();
assert!(p.build_dir().join("debug").is_dir());
assert!(!p.build_dir().join("other").is_dir());
}
diff --git a/src/tools/cargo/tests/testsuite/profile_overrides.rs b/src/tools/cargo/tests/testsuite/profile_overrides.rs
index dc9bafba1..65d9f3b51 100644
--- a/src/tools/cargo/tests/testsuite/profile_overrides.rs
+++ b/src/tools/cargo/tests/testsuite/profile_overrides.rs
@@ -268,6 +268,60 @@ found package specs: bar, bar@0.5.0",
}
#[cargo_test]
+fn profile_override_spec_with_version() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [dependencies]
+ bar = { path = "bar" }
+
+ [profile.dev.package."bar:0.5.0"]
+ codegen-units = 2
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
+ .file("bar/src/lib.rs", "")
+ .build();
+
+ p.cargo("check -v")
+ .with_stderr_contains("[RUNNING] `rustc [..]bar/src/lib.rs [..] -C codegen-units=2 [..]")
+ .run();
+}
+
+#[cargo_test]
+fn profile_override_spec_with_partial_version() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [dependencies]
+ bar = { path = "bar" }
+
+ [profile.dev.package."bar:0.5"]
+ codegen-units = 2
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
+ .file("bar/src/lib.rs", "")
+ .build();
+
+ p.cargo("check -v")
+ .with_stderr_contains("[RUNNING] `rustc [..]bar/src/lib.rs [..] -C codegen-units=2 [..]")
+ .run();
+}
+
+#[cargo_test]
fn profile_override_spec() {
let p = project()
.file(
diff --git a/src/tools/cargo/tests/testsuite/profiles.rs b/src/tools/cargo/tests/testsuite/profiles.rs
index 465ab3b99..531c02700 100644
--- a/src/tools/cargo/tests/testsuite/profiles.rs
+++ b/src/tools/cargo/tests/testsuite/profiles.rs
@@ -744,7 +744,7 @@ Caused by:
.run();
}
-#[cargo_test(nightly, reason = "debug options stabilized in 1.70")]
+#[cargo_test]
fn debug_options_valid() {
let build = |option| {
let p = project()
diff --git a/src/tools/cargo/tests/testsuite/publish.rs b/src/tools/cargo/tests/testsuite/publish.rs
index 50ad697d5..67569bf3b 100644
--- a/src/tools/cargo/tests/testsuite/publish.rs
+++ b/src/tools/cargo/tests/testsuite/publish.rs
@@ -194,8 +194,8 @@ fn simple_publish_with_asymmetric() {
.file("src/main.rs", "fn main() {}")
.build();
- p.cargo("publish --no-verify -Zcredential-process --registry dummy-registry")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ p.cargo("publish --no-verify -Zasymmetric-token --registry dummy-registry")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.with_stderr(
"\
[UPDATING] `dummy-registry` index
@@ -922,6 +922,48 @@ You may press ctrl-c [..]
}
#[cargo_test]
+fn publish_failed_with_index_and_only_allowed_registry() {
+ let registry = RegistryBuilder::new()
+ .http_api()
+ .http_index()
+ .alternative()
+ .build();
+
+ let p = project().build();
+
+ let _ = repo(&paths::root().join("foo"))
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ documentation = "foo"
+ homepage = "foo"
+ repository = "foo"
+ publish = ["alternative"]
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("publish")
+ .arg("--index")
+ .arg(registry.index_url().as_str())
+ .with_status(101)
+ .with_stderr(
+ "\
+[NOTE] Found `alternative` as only allowed registry. Publishing to it automatically.
+[ERROR] command-line argument --index requires --token to be specified
+",
+ )
+ .run();
+}
+
+#[cargo_test]
fn publish_fail_with_no_registry_specified() {
let p = project().build();
@@ -1923,6 +1965,7 @@ Caused by:
headers:
<tab>HTTP/1.1 400
<tab>Content-Length: 7
+ <tab>Connection: close
<tab>
body:
go away
diff --git a/src/tools/cargo/tests/testsuite/registry.rs b/src/tools/cargo/tests/testsuite/registry.rs
index 8982b1cb6..f485180c9 100644
--- a/src/tools/cargo/tests/testsuite/registry.rs
+++ b/src/tools/cargo/tests/testsuite/registry.rs
@@ -807,7 +807,7 @@ required by package `foo v0.0.1 ([..])`
)
.run();
- p.cargo("update -p baz")
+ p.cargo("update baz")
.with_stderr_contains(
"\
[UPDATING] `[..]` index
@@ -952,7 +952,7 @@ fn update_lockfile() {
Package::new("bar", "0.0.3").publish();
paths::home().join(".cargo/registry").rm_rf();
println!("0.0.2 update");
- p.cargo("update -p bar --precise 0.0.2")
+ p.cargo("update bar --precise 0.0.2")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -975,7 +975,7 @@ fn update_lockfile() {
.run();
println!("0.0.3 update");
- p.cargo("update -p bar")
+ p.cargo("update bar")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -1000,7 +1000,7 @@ fn update_lockfile() {
println!("new dependencies update");
Package::new("bar", "0.0.4").dep("spam", "0.2.5").publish();
Package::new("spam", "0.2.5").publish();
- p.cargo("update -p bar")
+ p.cargo("update bar")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -1012,7 +1012,7 @@ fn update_lockfile() {
println!("new dependencies update");
Package::new("bar", "0.0.5").publish();
- p.cargo("update -p bar")
+ p.cargo("update bar")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -1433,7 +1433,7 @@ fn update_transitive_dependency() {
Package::new("b", "0.1.1").publish();
- p.cargo("update -pb")
+ p.cargo("update b")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -1504,7 +1504,7 @@ fn update_backtracking_ok() {
.dep("cookie", "0.1.0")
.publish();
- p.cargo("update -p hyper")
+ p.cargo("update hyper")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -1555,7 +1555,7 @@ fn update_multiple_packages() {
Package::new("b", "0.1.1").publish();
Package::new("c", "0.1.1").publish();
- p.cargo("update -pa -pb")
+ p.cargo("update a b")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -1565,7 +1565,7 @@ fn update_multiple_packages() {
)
.run();
- p.cargo("update -pb -pc")
+ p.cargo("update b c")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -1671,7 +1671,7 @@ fn update_same_prefix_oh_my_how_was_this_a_bug() {
.publish();
p.cargo("generate-lockfile").run();
- p.cargo("update -pfoobar --precise=0.2.0").run();
+ p.cargo("update foobar --precise=0.2.0").run();
}
#[cargo_test]
@@ -1756,12 +1756,12 @@ fn use_semver_package_incorrectly() {
.with_status(101)
.with_stderr(
"\
-error: no matching package found
-searched package name: `a`
-prerelease package needs to be specified explicitly
-a = { version = \"0.1.1-alpha.0\" }
+error: failed to select a version for the requirement `a = \"^0.1\"`
+candidate versions found which didn't match: 0.1.1-alpha.0
location searched: [..]
required by package `b v0.1.0 ([..])`
+if you are looking for the prerelease package it needs to be specified explicitly
+ a = { version = \"0.1.1-alpha.0\" }
",
)
.run();
@@ -2604,7 +2604,9 @@ fn ignores_unknown_index_version_git() {
fn ignores_unknown_index_version() {
// If the version field is not understood, it is ignored.
Package::new("bar", "1.0.0").publish();
- Package::new("bar", "1.0.1").schema_version(9999).publish();
+ Package::new("bar", "1.0.1")
+ .schema_version(u32::MAX)
+ .publish();
let p = project()
.file(
@@ -2631,6 +2633,41 @@ fn ignores_unknown_index_version() {
}
#[cargo_test]
+fn unknown_index_version_error() {
+ // If the version field is not understood, it is ignored.
+ Package::new("bar", "1.0.1")
+ .schema_version(u32::MAX)
+ .publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bar = "1.0"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("generate-lockfile")
+ .with_status(101)
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[ERROR] no matching package named `bar` found
+location searched: registry `crates-io`
+required by package `foo v0.1.0 ([CWD])`
+",
+ )
+ .run();
+}
+
+#[cargo_test]
fn protocol() {
cargo_process("install bar")
.with_status(101)
diff --git a/src/tools/cargo/tests/testsuite/registry_auth.rs b/src/tools/cargo/tests/testsuite/registry_auth.rs
index 4422c638a..df2bdf565 100644
--- a/src/tools/cargo/tests/testsuite/registry_auth.rs
+++ b/src/tools/cargo/tests/testsuite/registry_auth.rs
@@ -6,9 +6,12 @@ use cargo_test_support::{project, Execs, Project};
fn cargo(p: &Project, s: &str) -> Execs {
let mut e = p.cargo(s);
- e.masquerade_as_nightly_cargo(&["registry-auth", "credential-process"])
- .arg("-Zregistry-auth")
- .arg("-Zcredential-process");
+ e.masquerade_as_nightly_cargo(&["asymmetric-token"])
+ .arg("-Zasymmetric-token");
+ e.env(
+ "CARGO_REGISTRY_GLOBAL_CREDENTIAL_PROVIDERS",
+ "cargo:paseto cargo:token",
+ );
e
}
@@ -43,7 +46,7 @@ static SUCCESS_OUTPUT: &'static str = "\
";
#[cargo_test]
-fn requires_nightly() {
+fn requires_credential_provider() {
let _registry = RegistryBuilder::new()
.alternative()
.auth_required()
@@ -55,14 +58,14 @@ fn requires_nightly() {
.with_status(101)
.with_stderr(
r#"[UPDATING] `alternative` index
-[DOWNLOADING] crates ...
-error: failed to download from `[..]/dl/bar/0.0.1/download`
+error: failed to download `bar v0.0.1 (registry `alternative`)`
Caused by:
- failed to get successful HTTP response from `[..]` (127.0.0.1), got 401
- body:
- Unauthorized message from server.
-"#,
+ unable to get packages from source
+
+Caused by:
+ authenticated registries require a credential-provider to be configured
+ see https://doc.rust-lang.org/cargo/reference/registry-authentication.html for details"#,
)
.run();
}
diff --git a/src/tools/cargo/tests/testsuite/replace.rs b/src/tools/cargo/tests/testsuite/replace.rs
index c11c49330..b9de51d2f 100644
--- a/src/tools/cargo/tests/testsuite/replace.rs
+++ b/src/tools/cargo/tests/testsuite/replace.rs
@@ -533,7 +533,7 @@ fn override_adds_some_deps() {
p.cargo("check").with_stdout("").run();
Package::new("baz", "0.1.2").publish();
- p.cargo("update -p")
+ p.cargo("update")
.arg(&format!("{}#bar", foo.url()))
.with_stderr(
"\
@@ -542,7 +542,7 @@ fn override_adds_some_deps() {
",
)
.run();
- p.cargo("update -p https://github.com/rust-lang/crates.io-index#bar")
+ p.cargo("update https://github.com/rust-lang/crates.io-index#bar")
.with_stderr(
"\
[UPDATING] `dummy-registry` index
@@ -1298,3 +1298,157 @@ fn override_plus_dep() {
.with_stderr_contains("error: cyclic package dependency: [..]")
.run();
}
+
+#[cargo_test]
+fn override_generic_matching_other_versions() {
+ Package::new("bar", "0.1.0+a").publish();
+
+ let bar = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
+ .file("src/lib.rs", "pub fn bar() {}")
+ .build();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1.0"
+
+ [replace]
+ "bar:0.1.0" = {{ git = '{}' }}
+ "#,
+ bar.url()
+ ),
+ )
+ .file(
+ "src/lib.rs",
+ "extern crate bar; pub fn foo() { bar::bar(); }",
+ )
+ .build();
+
+ p.cargo("check")
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[UPDATING] git repository `[..]`
+[ERROR] failed to get `bar` as a dependency of package `foo v0.0.1 ([..]/foo)`
+
+Caused by:
+ replacement specification `https://github.com/rust-lang/crates.io-index#bar@0.1.0` matched 0.1.0+a and tried to override it with 0.1.0
+ avoid matching unrelated packages by being more specific
+",
+ )
+ .with_status(101)
+ .run();
+}
+
+#[cargo_test]
+fn override_respects_spec_metadata() {
+ Package::new("bar", "0.1.0+a").publish();
+
+ let bar = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", &basic_manifest("bar", "0.1.0+a"))
+ .file("src/lib.rs", "pub fn bar() {}")
+ .build();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1.0"
+
+ [replace]
+ "bar:0.1.0+notTheBuild" = {{ git = '{}' }}
+ "#,
+ bar.url()
+ ),
+ )
+ .file(
+ "src/lib.rs",
+ "extern crate bar; pub fn foo() { bar::bar(); }",
+ )
+ .build();
+
+ p.cargo("check")
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[WARNING] package replacement is not used: https://github.com/rust-lang/crates.io-index#bar@0.1.0+notTheBuild
+[DOWNLOADING] crates ...
+[DOWNLOADED] bar v0.1.0+a (registry `dummy-registry`)
+[CHECKING] bar v0.1.0+a
+[CHECKING] foo v0.0.1 ([..]/foo)
+[..]
+[..]
+[..]
+[..]
+[..]
+[..]
+[..]
+error: could not compile `foo` (lib) due to previous error
+",
+ )
+ .with_status(101)
+ .run();
+}
+
+#[cargo_test]
+fn override_spec_metadata_is_optional() {
+ Package::new("bar", "0.1.0+a").publish();
+
+ let bar = git::repo(&paths::root().join("override"))
+ .file("Cargo.toml", &basic_manifest("bar", "0.1.0+a"))
+ .file("src/lib.rs", "pub fn bar() {}")
+ .build();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = "0.1.0"
+
+ [replace]
+ "bar:0.1.0" = {{ git = '{}' }}
+ "#,
+ bar.url()
+ ),
+ )
+ .file(
+ "src/lib.rs",
+ "extern crate bar; pub fn foo() { bar::bar(); }",
+ )
+ .build();
+
+ p.cargo("check")
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[UPDATING] git repository `[..]`
+[CHECKING] bar v0.1.0+a (file://[..])
+[CHECKING] foo v0.0.1 ([CWD])
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
diff --git a/src/tools/cargo/tests/testsuite/run.rs b/src/tools/cargo/tests/testsuite/run.rs
index 64cf4e16c..c58c239ac 100644
--- a/src/tools/cargo/tests/testsuite/run.rs
+++ b/src/tools/cargo/tests/testsuite/run.rs
@@ -38,6 +38,43 @@ fn quiet_arg() {
}
#[cargo_test]
+fn unsupported_silent_arg() {
+ let p = project()
+ .file("src/main.rs", r#"fn main() { println!("hello"); }"#)
+ .build();
+
+ p.cargo("run -s")
+ .with_stderr(
+ "\
+error: unexpected argument '--silent' found
+
+ tip: a similar argument exists: '--quiet'
+
+Usage: cargo[EXE] run [OPTIONS] [args]...
+
+For more information, try '--help'.
+",
+ )
+ .with_status(1)
+ .run();
+
+ p.cargo("run --silent")
+ .with_stderr(
+ "\
+error: unexpected argument '--silent' found
+
+ tip: a similar argument exists: '--quiet'
+
+Usage: cargo[EXE] run [OPTIONS] [args]...
+
+For more information, try '--help'.
+",
+ )
+ .with_status(1)
+ .run();
+}
+
+#[cargo_test]
fn quiet_arg_and_verbose_arg() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
diff --git a/src/tools/cargo/tests/testsuite/rust_version.rs b/src/tools/cargo/tests/testsuite/rust_version.rs
index 91711cf1a..21321b7c5 100644
--- a/src/tools/cargo/tests/testsuite/rust_version.rs
+++ b/src/tools/cargo/tests/testsuite/rust_version.rs
@@ -44,8 +44,48 @@ fn rust_version_bad_caret() {
.cargo("check")
.with_status(101)
.with_stderr(
- "error: failed to parse manifest at `[..]`\n\n\
- Caused by:\n `rust-version` must be a value like \"1.32\"",
+ "\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ TOML parse error at line 6, column 28
+ |
+ 6 | rust-version = \"^1.43\"
+ | ^^^^^^^
+ unexpected version requirement, expected a version like \"1.32\"",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn rust_version_good_pre_release() {
+ project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ rust-version = "1.43.0-beta.1"
+ [[bin]]
+ name = "foo"
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .build()
+ .cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ TOML parse error at line 6, column 28
+ |
+ 6 | rust-version = \"1.43.0-beta.1\"
+ | ^^^^^^^^^^^^^^^
+ unexpected prerelease field, expected a version like \"1.32\"",
)
.run();
}
@@ -70,8 +110,15 @@ fn rust_version_bad_pre_release() {
.cargo("check")
.with_status(101)
.with_stderr(
- "error: failed to parse manifest at `[..]`\n\n\
- Caused by:\n `rust-version` must be a value like \"1.32\"",
+ "\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ TOML parse error at line 6, column 28
+ |
+ 6 | rust-version = \"1.43-beta.1\"
+ | ^^^^^^^^^^^^^
+ unexpected prerelease field, expected a version like \"1.32\"",
)
.run();
}
@@ -96,8 +143,15 @@ fn rust_version_bad_nonsense() {
.cargo("check")
.with_status(101)
.with_stderr(
- "error: failed to parse manifest at `[..]`\n\n\
- Caused by:\n `rust-version` must be a value like \"1.32\"",
+ "\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ TOML parse error at line 6, column 28
+ |
+ 6 | rust-version = \"foodaddle\"
+ | ^^^^^^^^^^^
+ expected a version like \"1.32\"",
)
.run();
}
@@ -131,7 +185,7 @@ fn rust_version_too_high() {
}
#[cargo_test]
-fn rust_version_dependency_fails() {
+fn dependency_rust_version_newer_than_rustc() {
Package::new("bar", "0.0.1")
.rust_version("1.2345.0")
.file("src/lib.rs", "fn other_stuff() {}")
@@ -161,7 +215,7 @@ fn rust_version_dependency_fails() {
error: package `bar v0.0.1` cannot be built because it requires \
rustc 1.2345.0 or newer, while the currently active rustc version is [..]\n\
Either upgrade to rustc 1.2345.0 or newer, or use\n\
- cargo update -p bar@0.0.1 --precise ver\n\
+ cargo update bar@0.0.1 --precise ver\n\
where `ver` is the latest version of `bar` supporting rustc [..]",
)
.run();
@@ -169,6 +223,189 @@ fn rust_version_dependency_fails() {
}
#[cargo_test]
+fn dependency_rust_version_newer_than_package() {
+ Package::new("bar", "1.6.0")
+ .rust_version("1.65.0")
+ .file("src/lib.rs", "fn other_stuff() {}")
+ .publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ rust-version = "1.60.0"
+ [dependencies]
+ bar = "1.0.0"
+ "#,
+ )
+ .file("src/main.rs", "fn main(){}")
+ .build();
+
+ p.cargo("check --ignore-rust-version")
+ .arg("-Zmsrv-policy")
+ .masquerade_as_nightly_cargo(&["msrv-policy"])
+ // This shouldn't fail
+ .with_status(101)
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[ERROR] failed to select a version for the requirement `bar = \"^1.0.0\"`
+candidate versions found which didn't match: 1.6.0
+location searched: `dummy-registry` index (which is replacing registry `crates-io`)
+required by package `foo v0.0.1 ([CWD])`
+perhaps a crate was updated and forgotten to be re-vendored?
+",
+ )
+ .run();
+ p.cargo("check")
+ .arg("-Zmsrv-policy")
+ .masquerade_as_nightly_cargo(&["msrv-policy"])
+ .with_status(101)
+ // This should have a better error message
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[ERROR] failed to select a version for the requirement `bar = \"^1.0.0\"`
+candidate versions found which didn't match: 1.6.0
+location searched: `dummy-registry` index (which is replacing registry `crates-io`)
+required by package `foo v0.0.1 ([CWD])`
+perhaps a crate was updated and forgotten to be re-vendored?
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn dependency_rust_version_older_and_newer_than_package() {
+ Package::new("bar", "1.5.0")
+ .rust_version("1.55.0")
+ .file("src/lib.rs", "fn other_stuff() {}")
+ .publish();
+ Package::new("bar", "1.6.0")
+ .rust_version("1.65.0")
+ .file("src/lib.rs", "fn other_stuff() {}")
+ .publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ rust-version = "1.60.0"
+ [dependencies]
+ bar = "1.0.0"
+ "#,
+ )
+ .file("src/main.rs", "fn main(){}")
+ .build();
+
+ p.cargo("check --ignore-rust-version")
+ .arg("-Zmsrv-policy")
+ .masquerade_as_nightly_cargo(&["msrv-policy"])
+ // This should pick 1.6.0
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[DOWNLOADING] crates ...
+[DOWNLOADED] bar v1.5.0 (registry `dummy-registry`)
+[CHECKING] bar v1.5.0
+[CHECKING] [..]
+[FINISHED] [..]
+",
+ )
+ .run();
+ p.cargo("check")
+ .arg("-Zmsrv-policy")
+ .masquerade_as_nightly_cargo(&["msrv-policy"])
+ .with_stderr(
+ "\
+[FINISHED] [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn workspace_with_mixed_rust_version() {
+ Package::new("bar", "1.4.0")
+ .rust_version("1.45.0")
+ .file("src/lib.rs", "fn other_stuff() {}")
+ .publish();
+ Package::new("bar", "1.5.0")
+ .rust_version("1.55.0")
+ .file("src/lib.rs", "fn other_stuff() {}")
+ .publish();
+ Package::new("bar", "1.6.0")
+ .rust_version("1.65.0")
+ .file("src/lib.rs", "fn other_stuff() {}")
+ .publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [workspace]
+ members = ["lower"]
+
+ [package]
+ name = "higher"
+ version = "0.0.1"
+ authors = []
+ rust-version = "1.60.0"
+ [dependencies]
+ bar = "1.0.0"
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .file(
+ "lower/Cargo.toml",
+ r#"
+ [package]
+ name = "lower"
+ version = "0.0.1"
+ authors = []
+ rust-version = "1.50.0"
+ [dependencies]
+ bar = "1.0.0"
+ "#,
+ )
+ .file("lower/src/main.rs", "fn main() {}")
+ .build();
+
+ p.cargo("check --ignore-rust-version")
+ .arg("-Zmsrv-policy")
+ .masquerade_as_nightly_cargo(&["msrv-policy"])
+ // This should pick 1.6.0
+ .with_stderr(
+ "\
+[UPDATING] `dummy-registry` index
+[DOWNLOADING] crates ...
+[DOWNLOADED] bar v1.4.0 (registry `dummy-registry`)
+[CHECKING] bar v1.4.0
+[CHECKING] [..]
+[FINISHED] [..]
+",
+ )
+ .run();
+ p.cargo("check")
+ .arg("-Zmsrv-policy")
+ .masquerade_as_nightly_cargo(&["msrv-policy"])
+ .with_stderr(
+ "\
+[FINISHED] [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
fn rust_version_older_than_edition() {
project()
.file(
diff --git a/src/tools/cargo/tests/testsuite/rustdocflags.rs b/src/tools/cargo/tests/testsuite/rustdocflags.rs
index 6992961ce..c37d5a826 100644
--- a/src/tools/cargo/tests/testsuite/rustdocflags.rs
+++ b/src/tools/cargo/tests/testsuite/rustdocflags.rs
@@ -110,17 +110,19 @@ fn whitespace() {
.with_status(101)
.run();
- const SPACED_VERSION: &str = "a\nb\tc\u{00a0}d";
p.cargo("doc")
.env_remove("__CARGO_TEST_FORCE_ARGFILE") // Not applicable for argfile.
.env(
"RUSTDOCFLAGS",
- format!("--crate-version {}", SPACED_VERSION),
+ "--crate-version 1111\n2222\t3333\u{00a0}4444",
)
.run();
let contents = p.read_file("target/doc/foo/index.html");
- assert!(contents.contains(SPACED_VERSION));
+ assert!(contents.contains("1111"));
+ assert!(contents.contains("2222"));
+ assert!(contents.contains("3333"));
+ assert!(contents.contains("4444"));
}
#[cargo_test]
diff --git a/src/tools/cargo/tests/testsuite/script.rs b/src/tools/cargo/tests/testsuite/script.rs
index 0c0441d62..96f3a5eb4 100644
--- a/src/tools/cargo/tests/testsuite/script.rs
+++ b/src/tools/cargo/tests/testsuite/script.rs
@@ -162,7 +162,7 @@ fn warn_when_plugin_masks_manifest_on_stable() {
.with_stdout("")
.with_stderr(
"\
-warning: external subcommand `echo.rs` has the appearance of a manfiest-command
+warning: external subcommand `echo.rs` has the appearance of a manifest-command
This was previously accepted but will be phased out when `-Zscript` is stabilized.
For more information, see issue #12207 <https://github.com/rust-lang/cargo/issues/12207>.
",
@@ -208,11 +208,10 @@ error: running `echo.rs` requires `-Zscript`
#[cargo_test]
fn clean_output_with_edition() {
let script = r#"#!/usr/bin/env cargo
-
-//! ```cargo
-//! [package]
-//! edition = "2018"
-//! ```
+```cargo
+[package]
+edition = "2018"
+```
fn main() {
println!("Hello world!");
@@ -240,10 +239,9 @@ fn main() {
#[cargo_test]
fn warning_without_edition() {
let script = r#"#!/usr/bin/env cargo
-
-//! ```cargo
-//! [package]
-//! ```
+```cargo
+[package]
+```
fn main() {
println!("Hello world!");
@@ -625,11 +623,10 @@ fn missing_script_rs() {
fn test_name_same_as_dependency() {
Package::new("script", "1.0.0").publish();
let script = r#"#!/usr/bin/env cargo
-
-//! ```cargo
-//! [dependencies]
-//! script = "1.0.0"
-//! ```
+```cargo
+[dependencies]
+script = "1.0.0"
+```
fn main() {
println!("Hello world!");
@@ -662,11 +659,10 @@ fn main() {
#[cargo_test]
fn test_path_dep() {
let script = r#"#!/usr/bin/env cargo
-
-//! ```cargo
-//! [dependencies]
-//! bar.path = "./bar"
-//! ```
+```cargo
+[dependencies]
+bar.path = "./bar"
+```
fn main() {
println!("Hello world!");
@@ -980,6 +976,7 @@ fn cmd_clean_with_embedded() {
.with_stderr(
"\
[WARNING] `package.edition` is unspecified, defaulting to `2021`
+[REMOVED] [..] files, [..] total
",
)
.run();
diff --git a/src/tools/cargo/tests/testsuite/search.rs b/src/tools/cargo/tests/testsuite/search.rs
index 1f6f40327..4c3155c8f 100644
--- a/src/tools/cargo/tests/testsuite/search.rs
+++ b/src/tools/cargo/tests/testsuite/search.rs
@@ -89,7 +89,8 @@ fn setup() -> RegistryBuilder {
fn not_update() {
let registry = setup().build();
- use cargo::core::{Shell, Source, SourceId};
+ use cargo::core::{Shell, SourceId};
+ use cargo::sources::source::Source;
use cargo::sources::RegistrySource;
use cargo::util::Config;
@@ -172,8 +173,7 @@ fn colored_results() {
fn auth_required_failure() {
let server = setup().auth_required().no_configure_token().build();
- cargo_process("-Zregistry-auth search postgres")
- .masquerade_as_nightly_cargo(&["registry-auth"])
+ cargo_process("search postgres")
.replace_crates_io(server.index_url())
.with_status(101)
.with_stderr_contains("[ERROR] no token found, please run `cargo login`")
@@ -184,8 +184,7 @@ fn auth_required_failure() {
fn auth_required() {
let server = setup().auth_required().build();
- cargo_process("-Zregistry-auth search postgres")
- .masquerade_as_nightly_cargo(&["registry-auth"])
+ cargo_process("search postgres")
.replace_crates_io(server.index_url())
.with_stdout_contains(SEARCH_RESULTS)
.run();
diff --git a/src/tools/cargo/tests/testsuite/source_replacement.rs b/src/tools/cargo/tests/testsuite/source_replacement.rs
index 24f2ca3e3..41f3fe0b7 100644
--- a/src/tools/cargo/tests/testsuite/source_replacement.rs
+++ b/src/tools/cargo/tests/testsuite/source_replacement.rs
@@ -243,7 +243,52 @@ fn undefined_default() {
.replace_crates_io(crates_io.index_url())
.with_status(101)
.with_stderr(
- "[ERROR] no index found for registry: `undefined`
+ "[ERROR] registry index was not found in any configuration: `undefined`
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn source_replacement_with_registry_url() {
+ let alternative = RegistryBuilder::new().alternative().http_api().build();
+ Package::new("bar", "0.0.1").alternative(true).publish();
+
+ let crates_io = setup_replacement(&format!(
+ r#"
+ [source.crates-io]
+ replace-with = 'using-registry-url'
+
+ [source.using-registry-url]
+ registry = '{}'
+ "#,
+ alternative.index_url()
+ ));
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ [dependencies.bar]
+ version = "0.0.1"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check")
+ .replace_crates_io(crates_io.index_url())
+ .with_stderr(
+ "\
+[UPDATING] `using-registry-url` index
+[DOWNLOADING] crates ...
+[DOWNLOADED] bar v0.0.1 (registry `using-registry-url`)
+[CHECKING] bar v0.0.1
+[CHECKING] foo v0.0.1 ([CWD])
+[FINISHED] dev [..]
",
)
.run();
diff --git a/src/tools/cargo/tests/testsuite/ssh.rs b/src/tools/cargo/tests/testsuite/ssh.rs
index d1701d32d..f8c12819b 100644
--- a/src/tools/cargo/tests/testsuite/ssh.rs
+++ b/src/tools/cargo/tests/testsuite/ssh.rs
@@ -184,10 +184,9 @@ fn known_host_works() {
// Validate the fingerprint while we're here.
let fingerprint = stderr
.lines()
- .find(|line| line.starts_with(" The ECDSA key fingerprint"))
+ .find_map(|line| line.strip_prefix(" The ECDSA key fingerprint is: "))
.unwrap()
.trim();
- let fingerprint = &fingerprint[30..];
let finger_out = sshd.exec(&["ssh-keygen", "-l", "-f", "/etc/ssh/ssh_host_ecdsa_key.pub"]);
let gen_finger = std::str::from_utf8(&finger_out.stdout).unwrap();
// <key-size> <fingerprint> <comments…>
diff --git a/src/tools/cargo/tests/testsuite/test.rs b/src/tools/cargo/tests/testsuite/test.rs
index c6ae4ce61..5f6528109 100644
--- a/src/tools/cargo/tests/testsuite/test.rs
+++ b/src/tools/cargo/tests/testsuite/test.rs
@@ -4845,24 +4845,6 @@ error: 2 targets failed:
}
#[cargo_test]
-fn cargo_test_no_keep_going() {
- let p = project()
- .file("Cargo.toml", &basic_bin_manifest("foo"))
- .file("src/main.rs", "")
- .build();
-
- p.cargo("test --keep-going")
- .with_stderr(
- "\
-error: unexpected argument `--keep-going` found
-
- tip: to run as many tests as possible without failing fast, use `--no-fail-fast`",
- )
- .with_status(101)
- .run();
-}
-
-#[cargo_test]
fn cargo_test_print_env_verbose() {
let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.0.1"))
diff --git a/src/tools/cargo/tests/testsuite/tool_paths.rs b/src/tools/cargo/tests/testsuite/tool_paths.rs
index a211b5328..5428f9d01 100644
--- a/src/tools/cargo/tests/testsuite/tool_paths.rs
+++ b/src/tools/cargo/tests/testsuite/tool_paths.rs
@@ -32,6 +32,93 @@ fn pathless_tools() {
.run();
}
+// can set a custom linker via `target.'cfg(..)'.linker`
+#[cargo_test]
+fn custom_linker_cfg() {
+ let foo = project()
+ .file("Cargo.toml", &basic_lib_manifest("foo"))
+ .file("src/lib.rs", "")
+ .file(
+ ".cargo/config",
+ r#"
+ [target.'cfg(not(target_os = "none"))']
+ linker = "nonexistent-linker"
+ "#,
+ )
+ .build();
+
+ foo.cargo("build --verbose")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.5.0 ([CWD])
+[RUNNING] `rustc [..] -C linker=nonexistent-linker [..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
+
+// custom linker set via `target.$triple.linker` have precede over `target.'cfg(..)'.linker`
+#[cargo_test]
+fn custom_linker_cfg_precedence() {
+ let target = rustc_host();
+
+ let foo = project()
+ .file("Cargo.toml", &basic_lib_manifest("foo"))
+ .file("src/lib.rs", "")
+ .file(
+ ".cargo/config",
+ &format!(
+ r#"
+ [target.'cfg(not(target_os = "none"))']
+ linker = "ignored-linker"
+ [target.{}]
+ linker = "nonexistent-linker"
+ "#,
+ target
+ ),
+ )
+ .build();
+
+ foo.cargo("build --verbose")
+ .with_stderr(
+ "\
+[COMPILING] foo v0.5.0 ([CWD])
+[RUNNING] `rustc [..] -C linker=nonexistent-linker [..]`
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn custom_linker_cfg_collision() {
+ let foo = project()
+ .file("Cargo.toml", &basic_lib_manifest("foo"))
+ .file("src/lib.rs", "")
+ .file(
+ ".cargo/config",
+ r#"
+ [target.'cfg(not(target_arch = "avr"))']
+ linker = "nonexistent-linker1"
+ [target.'cfg(not(target_os = "none"))']
+ linker = "nonexistent-linker2"
+ "#,
+ )
+ .build();
+
+ foo.cargo("build --verbose")
+ .with_status(101)
+ .with_stderr(&format!(
+ "\
+[ERROR] several matching instances of `target.'cfg(..)'.linker` in configurations
+first match `cfg(not(target_arch = \"avr\"))` located in [..]/foo/.cargo/config
+second match `cfg(not(target_os = \"none\"))` located in [..]/foo/.cargo/config
+",
+ ))
+ .run();
+}
+
#[cargo_test]
fn absolute_tools() {
let target = rustc_host();
@@ -393,7 +480,6 @@ fn cfg_ignored_fields() {
[WARNING] unused key `ar` in [target] config table `cfg(not(target_os = \"none\"))`
[WARNING] unused key `foo` in [target] config table `cfg(not(target_os = \"none\"))`
[WARNING] unused key `invalid` in [target] config table `cfg(not(target_os = \"none\"))`
-[WARNING] unused key `linker` in [target] config table `cfg(not(target_os = \"none\"))`
[CHECKING] foo v0.0.1 ([..])
[FINISHED] [..]
",
diff --git a/src/tools/cargo/tests/testsuite/tree.rs b/src/tools/cargo/tests/testsuite/tree.rs
index e2e74c4f9..16cc37f7e 100644
--- a/src/tools/cargo/tests/testsuite/tree.rs
+++ b/src/tools/cargo/tests/testsuite/tree.rs
@@ -1675,7 +1675,7 @@ fn ambiguous_name() {
.with_stderr_contains(
"\
error: There are multiple `dep` packages in your project, and the specification `dep` is ambiguous.
-Please re-run this command with `-p <spec>` where `<spec>` is one of the following:
+Please re-run this command with one of the following specifications:
dep@1.0.0
dep@2.0.0
",
diff --git a/src/tools/cargo/tests/testsuite/update.rs b/src/tools/cargo/tests/testsuite/update.rs
index d42345355..fe1d86bd7 100644
--- a/src/tools/cargo/tests/testsuite/update.rs
+++ b/src/tools/cargo/tests/testsuite/update.rs
@@ -1,7 +1,7 @@
//! Tests for the `cargo update` command.
use cargo_test_support::registry::Package;
-use cargo_test_support::{basic_manifest, project};
+use cargo_test_support::{basic_lib_manifest, basic_manifest, git, project};
#[cargo_test]
fn minor_update_two_places() {
@@ -105,7 +105,7 @@ fn transitive_minor_update() {
//
// Also note that this is probably counterintuitive and weird. We may wish
// to change this one day.
- p.cargo("update -p serde")
+ p.cargo("update serde")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -155,7 +155,7 @@ fn conservative() {
Package::new("log", "0.1.1").publish();
Package::new("serde", "0.1.1").dep("log", "0.1").publish();
- p.cargo("update -p serde")
+ p.cargo("update serde")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -381,7 +381,7 @@ fn update_precise() {
Package::new("serde", "0.2.0").publish();
- p.cargo("update -p serde:0.2.1 --precise 0.2.0")
+ p.cargo("update serde:0.2.1 --precise 0.2.0")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -417,7 +417,7 @@ fn update_precise_do_not_force_update_deps() {
Package::new("log", "0.1.1").publish();
Package::new("serde", "0.2.2").dep("log", "0.1").publish();
- p.cargo("update -p serde:0.2.1 --precise 0.2.2")
+ p.cargo("update serde:0.2.1 --precise 0.2.2")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -428,7 +428,7 @@ fn update_precise_do_not_force_update_deps() {
}
#[cargo_test]
-fn update_aggressive() {
+fn update_recursive() {
Package::new("log", "0.1.0").publish();
Package::new("serde", "0.2.1").dep("log", "0.1").publish();
@@ -453,7 +453,7 @@ fn update_aggressive() {
Package::new("log", "0.1.1").publish();
Package::new("serde", "0.2.2").dep("log", "0.1").publish();
- p.cargo("update -p serde:0.2.1 --aggressive")
+ p.cargo("update serde:0.2.1 --recursive")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -465,7 +465,7 @@ fn update_aggressive() {
}
#[cargo_test]
-fn update_aggressive_conflicts_with_precise() {
+fn update_aggressive_alias_for_recursive() {
Package::new("log", "0.1.0").publish();
Package::new("serde", "0.2.1").dep("log", "0.1").publish();
@@ -490,13 +490,50 @@ fn update_aggressive_conflicts_with_precise() {
Package::new("log", "0.1.1").publish();
Package::new("serde", "0.2.2").dep("log", "0.1").publish();
- p.cargo("update -p serde:0.2.1 --precise 0.2.2 --aggressive")
+ p.cargo("update serde:0.2.1 --aggressive")
+ .with_stderr(
+ "\
+[UPDATING] `[..]` index
+[UPDATING] log v0.1.0 -> v0.1.1
+[UPDATING] serde v0.2.1 -> v0.2.2
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn update_recursive_conflicts_with_precise() {
+ Package::new("log", "0.1.0").publish();
+ Package::new("serde", "0.2.1").dep("log", "0.1").publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ serde = "0.2"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check").run();
+
+ Package::new("log", "0.1.1").publish();
+ Package::new("serde", "0.2.2").dep("log", "0.1").publish();
+
+ p.cargo("update serde:0.2.1 --precise 0.2.2 --recursive")
.with_status(1)
.with_stderr(
"\
-error: the argument '--precise <PRECISE>' cannot be used with '--aggressive'
+error: the argument '--precise <PRECISE>' cannot be used with '--recursive'
-Usage: cargo[EXE] update --package [<SPEC>] --precise <PRECISE>
+Usage: cargo[EXE] update --precise <PRECISE> <SPEC|--package [<SPEC>]>
For more information, try '--help'.
",
@@ -528,7 +565,7 @@ fn update_precise_first_run() {
.file("src/lib.rs", "")
.build();
- p.cargo("update -p serde --precise 0.2.0")
+ p.cargo("update serde --precise 0.2.0")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -682,7 +719,7 @@ fn update_precise_first_run() {
)
.run();
- p.cargo("update -p serde --precise 0.2.0")
+ p.cargo("update serde --precise 0.2.0")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -758,7 +795,7 @@ fn dry_run_update() {
Package::new("log", "0.1.1").publish();
Package::new("serde", "0.1.1").dep("log", "0.1").publish();
- p.cargo("update -p serde --dry-run")
+ p.cargo("update serde --dry-run")
.with_stderr(
"\
[UPDATING] `[..]` index
@@ -818,7 +855,7 @@ fn precise_with_build_metadata() {
Package::new("bar", "0.1.1+extra-stuff.1").publish();
Package::new("bar", "0.1.2+extra-stuff.2").publish();
- p.cargo("update -p bar --precise 0.1")
+ p.cargo("update bar --precise 0.1")
.with_status(101)
.with_stderr(
"\
@@ -830,7 +867,7 @@ Caused by:
)
.run();
- p.cargo("update -p bar --precise 0.1.1+does-not-match")
+ p.cargo("update bar --precise 0.1.1+does-not-match")
.with_status(101)
.with_stderr(
"\
@@ -842,7 +879,7 @@ required by package `foo v0.1.0 ([ROOT]/foo)`
)
.run();
- p.cargo("update -p bar --precise 0.1.1")
+ p.cargo("update bar --precise 0.1.1")
.with_stderr(
"\
[UPDATING] [..] index
@@ -852,7 +889,7 @@ required by package `foo v0.1.0 ([ROOT]/foo)`
.run();
Package::new("bar", "0.1.3").publish();
- p.cargo("update -p bar --precise 0.1.3+foo")
+ p.cargo("update bar --precise 0.1.3+foo")
.with_status(101)
.with_stderr(
"\
@@ -864,7 +901,7 @@ required by package `foo v0.1.0 ([ROOT]/foo)`
)
.run();
- p.cargo("update -p bar --precise 0.1.3")
+ p.cargo("update bar --precise 0.1.3")
.with_stderr(
"\
[UPDATING] [..] index
@@ -873,3 +910,185 @@ required by package `foo v0.1.0 ([ROOT]/foo)`
)
.run();
}
+
+#[cargo_test]
+fn update_only_members_order_one() {
+ let git_project = git::new("rustdns", |project| {
+ project
+ .file("Cargo.toml", &basic_lib_manifest("rustdns"))
+ .file("src/lib.rs", "pub fn bar() {}")
+ });
+
+ let workspace_toml = format!(
+ r#"
+[workspace.package]
+version = "2.29.8"
+edition = "2021"
+publish = false
+
+[workspace]
+members = [
+ "rootcrate",
+ "subcrate",
+]
+resolver = "2"
+
+[workspace.dependencies]
+# Internal crates
+subcrate = {{ version = "*", path = "./subcrate" }}
+
+# External dependencies
+rustdns = {{ version = "0.5.0", default-features = false, git = "{}" }}
+ "#,
+ git_project.url()
+ );
+ let p = project()
+ .file("Cargo.toml", &workspace_toml)
+ .file(
+ "rootcrate/Cargo.toml",
+ r#"
+[package]
+name = "rootcrate"
+version.workspace = true
+edition.workspace = true
+publish.workspace = true
+
+[dependencies]
+subcrate.workspace = true
+"#,
+ )
+ .file("rootcrate/src/main.rs", "fn main() {}")
+ .file(
+ "subcrate/Cargo.toml",
+ r#"
+[package]
+name = "subcrate"
+version.workspace = true
+edition.workspace = true
+publish.workspace = true
+
+[dependencies]
+rustdns.workspace = true
+"#,
+ )
+ .file("subcrate/src/lib.rs", "pub foo() {}")
+ .build();
+
+ // First time around we should compile both foo and bar
+ p.cargo("generate-lockfile")
+ .with_stderr(&format!(
+ "[UPDATING] git repository `{}`\n",
+ git_project.url(),
+ ))
+ .run();
+ // Modify a file manually, shouldn't trigger a recompile
+ git_project.change_file("src/lib.rs", r#"pub fn bar() { println!("hello!"); }"#);
+ // Commit the changes and make sure we don't trigger a recompile because the
+ // lock file says not to change
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+ p.change_file("Cargo.toml", &workspace_toml.replace("2.29.8", "2.29.81"));
+
+ p.cargo("update -p rootcrate")
+ .with_stderr(&format!(
+ "\
+[UPDATING] git repository `{}`
+[UPDATING] rootcrate v2.29.8 ([CWD]/rootcrate) -> v2.29.81
+[UPDATING] rustdns v0.5.0 ([..]) -> [..]
+[UPDATING] subcrate v2.29.8 ([CWD]/subcrate) -> v2.29.81",
+ git_project.url(),
+ ))
+ .run();
+}
+
+#[cargo_test]
+fn update_only_members_order_two() {
+ let git_project = git::new("rustdns", |project| {
+ project
+ .file("Cargo.toml", &basic_lib_manifest("rustdns"))
+ .file("src/lib.rs", "pub fn bar() {}")
+ });
+
+ let workspace_toml = format!(
+ r#"
+[workspace.package]
+version = "2.29.8"
+edition = "2021"
+publish = false
+
+[workspace]
+members = [
+ "crate2",
+ "crate1",
+]
+resolver = "2"
+
+[workspace.dependencies]
+# Internal crates
+crate1 = {{ version = "*", path = "./crate1" }}
+
+# External dependencies
+rustdns = {{ version = "0.5.0", default-features = false, git = "{}" }}
+ "#,
+ git_project.url()
+ );
+ let p = project()
+ .file("Cargo.toml", &workspace_toml)
+ .file(
+ "crate2/Cargo.toml",
+ r#"
+[package]
+name = "crate2"
+version.workspace = true
+edition.workspace = true
+publish.workspace = true
+
+[dependencies]
+crate1.workspace = true
+"#,
+ )
+ .file("crate2/src/main.rs", "fn main() {}")
+ .file(
+ "crate1/Cargo.toml",
+ r#"
+[package]
+name = "crate1"
+version.workspace = true
+edition.workspace = true
+publish.workspace = true
+
+[dependencies]
+rustdns.workspace = true
+"#,
+ )
+ .file("crate1/src/lib.rs", "pub foo() {}")
+ .build();
+
+ // First time around we should compile both foo and bar
+ p.cargo("generate-lockfile")
+ .with_stderr(&format!(
+ "[UPDATING] git repository `{}`\n",
+ git_project.url(),
+ ))
+ .run();
+ // Modify a file manually, shouldn't trigger a recompile
+ git_project.change_file("src/lib.rs", r#"pub fn bar() { println!("hello!"); }"#);
+ // Commit the changes and make sure we don't trigger a recompile because the
+ // lock file says not to change
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ git::add(&repo);
+ git::commit(&repo);
+ p.change_file("Cargo.toml", &workspace_toml.replace("2.29.8", "2.29.81"));
+
+ p.cargo("update -p crate2")
+ .with_stderr(&format!(
+ "\
+[UPDATING] git repository `{}`
+[UPDATING] crate1 v2.29.8 ([CWD]/crate1) -> v2.29.81
+[UPDATING] crate2 v2.29.8 ([CWD]/crate2) -> v2.29.81
+[UPDATING] rustdns v0.5.0 ([..]) -> [..]",
+ git_project.url(),
+ ))
+ .run();
+}
diff --git a/src/tools/cargo/tests/testsuite/workspaces.rs b/src/tools/cargo/tests/testsuite/workspaces.rs
index c6698f76a..4f8997b38 100644
--- a/src/tools/cargo/tests/testsuite/workspaces.rs
+++ b/src/tools/cargo/tests/testsuite/workspaces.rs
@@ -1091,9 +1091,6 @@ fn new_warning_with_corrupt_ws() {
failed to parse manifest at `[..]foo/Cargo.toml`
Caused by:
- could not parse input as TOML
-
-Caused by:
TOML parse error at line 1, column 5
|
1 | asdf
diff --git a/src/tools/cargo/tests/testsuite/yank.rs b/src/tools/cargo/tests/testsuite/yank.rs
index c0bd24776..9aff2fc84 100644
--- a/src/tools/cargo/tests/testsuite/yank.rs
+++ b/src/tools/cargo/tests/testsuite/yank.rs
@@ -76,14 +76,14 @@ fn explicit_version_with_asymmetric() {
// The http_api server will check that the authorization is correct.
// If the authorization was not sent then we would get an unauthorized error.
p.cargo("yank --version 0.0.1")
- .arg("-Zcredential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ .arg("-Zasymmetric-token")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.replace_crates_io(registry.index_url())
.run();
p.cargo("yank --undo --version 0.0.1")
- .arg("-Zcredential-process")
- .masquerade_as_nightly_cargo(&["credential-process"])
+ .arg("-Zasymmetric-token")
+ .masquerade_as_nightly_cargo(&["asymmetric-token"])
.replace_crates_io(registry.index_url())
.run();
}
diff --git a/src/tools/cargo/triagebot.toml b/src/tools/cargo/triagebot.toml
index 6d07f438f..c92b4ce8c 100644
--- a/src/tools/cargo/triagebot.toml
+++ b/src/tools/cargo/triagebot.toml
@@ -86,6 +86,9 @@ trigger_files = ["src/cargo/core/dependency.rs"]
[autolabel."A-crate-types"]
trigger_files = ["src/cargo/core/compiler/crate_type.rs"]
+[autolabel."A-credential-provider"]
+trigger_files = ["credential/"]
+
[autolabel."A-dep-info"]
trigger_files = ["src/cargo/core/compiler/output_depinfo.rs"]
@@ -123,6 +126,9 @@ trigger_files = ["src/cargo/core/compiler/future_incompat.rs"]
[autolabel."A-git"]
trigger_files = ["src/cargo/sources/git/"]
+[autolabel."A-home"]
+trigger_files = ["crates/home/"]
+
[autolabel."A-infrastructure"]
trigger_files = [
".cargo/",
@@ -180,7 +186,7 @@ trigger_files = ["src/cargo/core/compiler/fingerprint/"]
trigger_files = ["src/cargo/sources/registry/", "src/cargo/core/registry.rs"]
[autolabel."A-registry-authentication"]
-trigger_files = ["src/cargo/util/auth/", "credential/"]
+trigger_files = ["src/cargo/util/auth/"]
[autolabel."A-semver"]
trigger_files = [
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index 7044cb892..a5d2ffb15 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -140,7 +140,7 @@ fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
let status = Command::new("git")
.arg("fetch")
.arg(test.repo)
- .arg("master")
+ .arg(test.sha)
.arg(&format!("--depth={}", depth))
.current_dir(&out_dir)
.status()
diff --git a/src/tools/clippy/.github/driver.sh b/src/tools/clippy/.github/driver.sh
index 798782340..c05c6ecc1 100644
--- a/src/tools/clippy/.github/driver.sh
+++ b/src/tools/clippy/.github/driver.sh
@@ -30,7 +30,7 @@ unset CARGO_MANIFEST_DIR
# Run a lint and make sure it produces the expected output. It's also expected to exit with code 1
# FIXME: How to match the clippy invocation in compile-test.rs?
./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/double_neg.rs 2>double_neg.stderr && exit 1
-sed -e "s,tests/ui,\$DIR," -e "/= help/d" double_neg.stderr >normalized.stderr
+sed -e "s,tests/ui,\$DIR," -e "/= help: for/d" double_neg.stderr > normalized.stderr
diff -u normalized.stderr tests/ui/double_neg.stderr
# make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index 5c69714bc..9b96f8dc2 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -52,24 +52,14 @@ jobs:
needs: changelog
strategy:
matrix:
- os: [ubuntu-latest, windows-latest, macos-latest]
- host: [x86_64-unknown-linux-gnu, i686-unknown-linux-gnu, x86_64-apple-darwin, x86_64-pc-windows-msvc]
- exclude:
+ include:
- os: ubuntu-latest
- host: x86_64-apple-darwin
- - os: ubuntu-latest
- host: x86_64-pc-windows-msvc
- - os: macos-latest
- host: x86_64-unknown-linux-gnu
- - os: macos-latest
- host: i686-unknown-linux-gnu
- - os: macos-latest
- host: x86_64-pc-windows-msvc
- - os: windows-latest
host: x86_64-unknown-linux-gnu
- - os: windows-latest
+ - os: ubuntu-latest
host: i686-unknown-linux-gnu
- os: windows-latest
+ host: x86_64-pc-windows-msvc
+ - os: macos-latest
host: x86_64-apple-darwin
runs-on: ${{ matrix.os }}
@@ -84,8 +74,17 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
+ - name: Install i686 dependencies
+ if: matrix.host == 'i686-unknown-linux-gnu'
+ run: |
+ sudo dpkg --add-architecture i386
+ sudo apt-get update
+ sudo apt-get install gcc-multilib zlib1g-dev:i386
+
- name: Install toolchain
- run: rustup show active-toolchain
+ run: |
+ rustup set default-host ${{ matrix.host }}
+ rustup show active-toolchain
# Run
- name: Set LD_LIBRARY_PATH (Linux)
@@ -109,11 +108,11 @@ jobs:
run: cargo build --tests --features deny-warnings,internal
- name: Test
- if: runner.os == 'Linux'
+ if: matrix.host == 'x86_64-unknown-linux-gnu'
run: cargo test --features deny-warnings,internal
- name: Test
- if: runner.os != 'Linux'
+ if: matrix.host != 'x86_64-unknown-linux-gnu'
run: cargo test --features deny-warnings,internal -- --skip dogfood
- name: Test clippy_lints
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 7d25b6a2b..30bd47633 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -21,7 +21,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
- node-version: '14.x'
+ node-version: '18.x'
- name: Install remark
run: npm install remark-cli remark-lint remark-lint-maximum-line-length remark-preset-lint-recommended remark-gfm
@@ -29,19 +29,19 @@ jobs:
- name: Install mdbook
run: |
mkdir mdbook
- curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.28/mdbook-v0.4.28-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
+ curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdbook-v0.4.34-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
# Run
- name: Check *.md files
- run: git ls-files -z '*.md' | xargs -0 -n 1 -I {} ./node_modules/.bin/remark {} -u lint -f > /dev/null
+ run: ./node_modules/.bin/remark -u lint -f .
- name: Linkcheck book
run: |
rustup toolchain install nightly --component rust-docs
curl https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh -o linkcheck.sh
sh linkcheck.sh clippy --path ./book
-
+
- name: Build mdbook
run: mdbook build book
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 71671273c..8c9ab1e24 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,18 +6,105 @@ document.
## Unreleased / Beta / In Rust Nightly
-[435a8ad8...master](https://github.com/rust-lang/rust-clippy/compare/435a8ad8...master)
+[37f4c172...master](https://github.com/rust-lang/rust-clippy/compare/37f4c172...master)
-## Rust 1.71
+## Rust 1.72
+
+Current stable, released 2023-08-24
+
+[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)
+
+### New Lints
+
+* [`manual_try_fold`]
+ [#11012](https://github.com/rust-lang/rust-clippy/pull/11012)
+* [`tuple_array_conversions`]
+ [#11020](https://github.com/rust-lang/rust-clippy/pull/11020)
+* [`redundant_at_rest_pattern`]
+ [#11013](https://github.com/rust-lang/rust-clippy/pull/11013)
+* [`needless_pub_self`]
+ [#10967](https://github.com/rust-lang/rust-clippy/pull/10967)
+* [`pub_with_shorthand`]
+ [#10967](https://github.com/rust-lang/rust-clippy/pull/10967)
+* [`pub_without_shorthand`]
+ [#10967](https://github.com/rust-lang/rust-clippy/pull/10967)
+* [`manual_range_patterns`]
+ [#10968](https://github.com/rust-lang/rust-clippy/pull/10968)
+* [`needless_raw_string_hashes`]
+ [#10884](https://github.com/rust-lang/rust-clippy/pull/10884)
+* [`needless_raw_strings`]
+ [#10884](https://github.com/rust-lang/rust-clippy/pull/10884)
+* [`incorrect_clone_impl_on_copy_type`]
+ [#10925](https://github.com/rust-lang/rust-clippy/pull/10925)
+* [`drain_collect`]
+ [#10835](https://github.com/rust-lang/rust-clippy/pull/10835)
+* [`single_range_in_vec_init`]
+ [#10934](https://github.com/rust-lang/rust-clippy/pull/10934)
+* [`unnecessary_literal_unwrap`]
+ [#10358](https://github.com/rust-lang/rust-clippy/pull/10358)
+* [`large_stack_frames`]
+ [#10827](https://github.com/rust-lang/rust-clippy/pull/10827)
+* [`min_ident_chars`]
+ [#10916](https://github.com/rust-lang/rust-clippy/pull/10916)
+* [`needless_if`]
+ [#10921](https://github.com/rust-lang/rust-clippy/pull/10921)
+* [`excessive_nesting`]
+ [#10672](https://github.com/rust-lang/rust-clippy/pull/10672)
+* [`arc_with_non_send_sync`]
+ [#10898](https://github.com/rust-lang/rust-clippy/pull/10898)
+* [`redundant_type_annotations`]
+ [#10570](https://github.com/rust-lang/rust-clippy/pull/10570)
+* [`host_endian_bytes`]
+ [#10826](https://github.com/rust-lang/rust-clippy/pull/10826)
+* [`little_endian_bytes`]
+ [#10826](https://github.com/rust-lang/rust-clippy/pull/10826)
+* [`big_endian_bytes`]
+ [#10826](https://github.com/rust-lang/rust-clippy/pull/10826)
+* [`ptr_cast_constness`]
+ [#10779](https://github.com/rust-lang/rust-clippy/pull/10779)
+* [`needless_else`]
+ [#10810](https://github.com/rust-lang/rust-clippy/pull/10810)
+
+### Moves and Deprecations
+
+* Moved [`redundant_clone`] to `nursery` (Now allow-by-default)
+ [#10873](https://github.com/rust-lang/rust-clippy/pull/10873)
+
+### Enhancements
+
+* [`undocumented_unsafe_blocks`]: Added [`accept-comment-above-attributes`] configuration
+ [#10986](https://github.com/rust-lang/rust-clippy/pull/10986)
+* [`undocumented_unsafe_blocks`]: Added [`accept-comment-above-statement`] configuration.
+ [#10886](https://github.com/rust-lang/rust-clippy/pull/10886)
+* [`missing_panics_doc`]: No longer lints on `todo!()`
+ [#10976](https://github.com/rust-lang/rust-clippy/pull/10976)
+* [`module_inception`]: Added `allow-private-module-inception` configuration.
+ [#10917](https://github.com/rust-lang/rust-clippy/pull/10917)
+* Errors and warnings generated while parsing `clippy.toml` now point to the location in the TOML
+ file the error/warning occurred in.
+ [#10607](https://github.com/rust-lang/rust-clippy/pull/10607)
+
+### False Positive Fixes
+
+* [`excessive_precision`]: No longer lints overflowing literals
+ [#10952](https://github.com/rust-lang/rust-clippy/pull/10952)
+
+### Suggestion Fixes/Improvements
+
+* [`option_map_unwrap_or`]: The suggestion now considers the set [`msrv`] config value
+ [#11030](https://github.com/rust-lang/rust-clippy/pull/11030)
+
+### Documentation Improvements
+
+* [Clippy's lint list] now stores filter parameters in the URL, to allow easy sharing
+ [#10834](https://github.com/rust-lang/rust-clippy/pull/10834)
-Current stable, released 2023-07-13
+## Rust 1.71
-<!-- FIXME: Remove the request for feedback, with the next changelog -->
+Released 2023-07-13
-We're trying out a new shorter changelog format, that only contains significant changes.
-You can check out the list of merged pull requests for a list of all changes.
-If you have any feedback related to the new format, please share it in
-[#10847](https://github.com/rust-lang/rust-clippy/issues/10847)
+Note: Clippy will use a shorter changelog format from now on, if you want a detailed list of
+all changes, please check out the list of merged pull requests.
[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)
@@ -4677,6 +4764,7 @@ Released 2018-09-13
[pull3665]: https://github.com/rust-lang/rust-clippy/pull/3665
[adding_lints]: https://github.com/rust-lang/rust-clippy/blob/master/book/src/development/adding_lints.md
[`README.md`]: https://github.com/rust-lang/rust-clippy/blob/master/README.md
+[Clippy's lint list]: https://rust-lang.github.io/rust-clippy/master/index.html
<!-- lint disable no-unused-definitions -->
<!-- begin autogenerated links to lint list -->
@@ -4897,6 +4985,7 @@ Released 2018-09-13
[`implicit_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_return
[`implicit_saturating_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_add
[`implicit_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_sub
+[`implied_bounds_in_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#implied_bounds_in_impls
[`impossible_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#impossible_comparisons
[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops
[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
@@ -4942,6 +5031,7 @@ Released 2018-09-13
[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero
[`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections
[`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_single_items
+[`iter_out_of_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_out_of_bounds
[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned
[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next
[`iter_skip_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_zero
@@ -5042,6 +5132,7 @@ Released 2018-09-13
[`misnamed_getters`]: https://rust-lang.github.io/rust-clippy/master/index.html#misnamed_getters
[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
[`missing_assert_message`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_assert_message
+[`missing_asserts_for_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_asserts_for_indexing
[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
[`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames
@@ -5080,6 +5171,7 @@ Released 2018-09-13
[`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign
[`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
+[`needless_borrows_for_generic_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args
[`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
@@ -5115,6 +5207,8 @@ Released 2018-09-13
[`no_effect_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect_underscore_binding
[`no_mangle_with_rust_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_mangle_with_rust_abi
[`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_ascii_literal
+[`non_canonical_clone_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_clone_impl
+[`non_canonical_partial_ord_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_partial_ord_impl
[`non_minimal_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_minimal_cfg
[`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions
[`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty
@@ -5152,6 +5246,7 @@ Released 2018-09-13
[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none
[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite
+[`path_ends_with_ext`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext
[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch
[`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false
[`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters
@@ -5186,6 +5281,7 @@ Released 2018-09-13
[`readonly_write_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#readonly_write_lock
[`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl
[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation
+[`redundant_as_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_as_str
[`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_async_block
[`redundant_at_rest_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_at_rest_pattern
[`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
@@ -5211,6 +5307,7 @@ Released 2018-09-13
[`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro
[`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once
[`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts
+[`reserve_after_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#reserve_after_initialization
[`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs
[`result_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_expect_used
[`result_large_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err
@@ -5241,6 +5338,7 @@ Released 2018-09-13
[`short_circuit_statement`]: https://rust-lang.github.io/rust-clippy/master/index.html#short_circuit_statement
[`should_assert_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_assert_eq
[`should_implement_trait`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
+[`should_panic_without_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_panic_without_expect
[`significant_drop_in_scrutinee`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_in_scrutinee
[`significant_drop_tightening`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_tightening
[`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names
@@ -5342,6 +5440,7 @@ Released 2018-09-13
[`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join
[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
[`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap
+[`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor
[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
[`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings
@@ -5479,4 +5578,6 @@ Released 2018-09-13
[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
[`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
[`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
+[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
+[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
<!-- end autogenerated links to configuration documentation -->
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index 3df132803..04af1b98b 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -148,7 +148,7 @@ pub mod else_if_without_else;
pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
// ...
- store.register_early_pass(|| box else_if_without_else::ElseIfWithoutElse);
+ store.register_early_pass(|| Box::new(else_if_without_else::ElseIfWithoutElse));
// ...
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 0fb3a3a98..66786004f 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy"
-version = "0.1.73"
+version = "0.1.74"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
@@ -27,7 +27,7 @@ tempfile = { version = "3.2", optional = true }
termize = "0.1"
[dev-dependencies]
-ui_test = "0.11.5"
+ui_test = "0.20"
tester = "0.9"
regex = "1.5"
toml = "0.7.3"
@@ -38,7 +38,6 @@ itertools = "0.10.1"
# UI test dependencies
clippy_utils = { path = "clippy_utils" }
-derive-new = "0.5"
if_chain = "1.0"
quote = "1.0"
serde = { version = "1.0.125", features = ["derive"] }
diff --git a/src/tools/clippy/book/src/SUMMARY.md b/src/tools/clippy/book/src/SUMMARY.md
index 22fbdce75..b02457307 100644
--- a/src/tools/clippy/book/src/SUMMARY.md
+++ b/src/tools/clippy/book/src/SUMMARY.md
@@ -13,8 +13,13 @@
- [Development](development/README.md)
- [Basics](development/basics.md)
- [Adding Lints](development/adding_lints.md)
+ - [Defining Lints](development/defining_lints.md)
+ - [Writing tests](development/writing_tests.md)
- [Lint Passes](development/lint_passes.md)
+ - [Emitting lints](development/emitting_lints.md)
- [Type Checking](development/type_checking.md)
+ - [Trait Checking](development/trait_checking.md)
+ - [Method Checking](development/method_checking.md)
- [Macro Expansions](development/macro_expansions.md)
- [Common Tools](development/common_tools_writing_lints.md)
- [Infrastructure](development/infrastructure/README.md)
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index a0db80892..f6f0c95c7 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -161,8 +161,8 @@ The process of generating the `.stderr` file is the same, and prepending the
## Rustfix tests
If the lint you are working on is making use of structured suggestions, the test
-file should include a `//@run-rustfix` comment at the top. This will
-additionally run [rustfix] for that test. Rustfix will apply the suggestions
+will create a `.fixed` file by running [rustfix] for that test.
+Rustfix will apply the suggestions
from the lint to the code of the test file and compare that to the contents of a
`.fixed` file.
diff --git a/src/tools/clippy/book/src/development/defining_lints.md b/src/tools/clippy/book/src/development/defining_lints.md
new file mode 100644
index 000000000..7c4aa5d45
--- /dev/null
+++ b/src/tools/clippy/book/src/development/defining_lints.md
@@ -0,0 +1,205 @@
+# Define New Lints
+
+The first step in the journey of a new lint is the definition
+and registration of the lint in Clippy's codebase.
+We can use the Clippy dev tools to handle this step since setting up the
+lint involves some boilerplate code.
+
+#### Lint types
+
+A lint type is the category of items and expressions in which your lint focuses on.
+
+As of the writing of this documentation update, there are 12 _types_ of lints
+besides the numerous standalone lints living under `clippy_lints/src/`:
+
+- `cargo`
+- `casts`
+- `functions`
+- `loops`
+- `matches`
+- `methods`
+- `misc_early`
+- `operators`
+- `transmute`
+- `types`
+- `unit_types`
+- `utils / internal` (Clippy internal lints)
+
+These types group together lints that share some common behaviors. For instance,
+`functions` groups together lints that deal with some aspects of functions in
+Rust, like definitions, signatures and attributes.
+
+For more information, feel free to compare the lint files under any category
+with [All Clippy lints][all_lints] or ask one of the maintainers.
+
+## Lint name
+
+A good lint name is important, make sure to check the [lint naming
+guidelines][lint_naming]. Don't worry, if the lint name doesn't fit, a Clippy
+team member will alert you in the PR process.
+
+---
+
+We'll name our example lint that detects functions named "foo" `foo_functions`.
+Check the [lint naming guidelines][lint_naming] to see why this name makes
+sense.
+
+## Add and Register the Lint
+
+Now that a name is chosen, we shall register `foo_functions` as a lint to the
+codebase. There are two ways to register a lint.
+
+### Standalone
+
+If you believe that this new lint is a standalone lint (that doesn't belong to
+any specific [type](#lint-types) like `functions` or `loops`), you can run the
+following command in your Clippy project:
+
+```sh
+$ cargo dev new_lint --name=lint_name --pass=late --category=pedantic
+```
+
+There are two things to note here:
+
+1. `--pass`: We set `--pass=late` in this command to do a late lint pass. The
+ alternative is an `early` lint pass. We will discuss this difference in a
+ later chapter.
+ <!-- FIXME: Link that "later chapter" when lint_passes.md is merged -->
+2. `--category`: If not provided, the `category` of this new lint will default
+ to `nursery`.
+
+The `cargo dev new_lint` command will create a new file:
+`clippy_lints/src/foo_functions.rs` as well as [register the
+lint](#lint-registration).
+
+Overall, you should notice that the following files are modified or created:
+
+```sh
+$ git status
+On branch foo_functions
+Changes not staged for commit:
+ (use "git add <file>..." to update what will be committed)
+ (use "git restore <file>..." to discard changes in working directory)
+ modified: CHANGELOG.md
+ modified: clippy_lints/src/lib.register_lints.rs
+ modified: clippy_lints/src/lib.register_pedantic.rs
+ modified: clippy_lints/src/lib.rs
+
+Untracked files:
+ (use "git add <file>..." to include in what will be committed)
+ clippy_lints/src/foo_functions.rs
+ tests/ui/foo_functions.rs
+```
+
+
+### Specific Type
+
+> **Note**: Lint types are listed in the ["Lint types"](#lint-types) section
+
+If you believe that this new lint belongs to a specific type of lints,
+you can run `cargo dev new_lint` with a `--type` option.
+
+Since our `foo_functions` lint is related to function calls, one could
+argue that we should put it into a group of lints that detect some behaviors
+of functions, we can put it in the `functions` group.
+
+Let's run the following command in your Clippy project:
+
+```sh
+$ cargo dev new_lint --name=foo_functions --type=functions --category=pedantic
+```
+
+This command will create, among other things, a new file:
+`clippy_lints/src/{type}/foo_functions.rs`.
+In our case, the path will be `clippy_lints/src/functions/foo_functions.rs`.
+
+Notice how this command has a `--type` flag instead of `--pass`. Unlike a standalone
+definition, this lint won't be registered in the traditional sense. Instead, you will
+call your lint from within the type's lint pass, found in `clippy_lints/src/{type}/mod.rs`.
+
+A _type_ is just the name of a directory in `clippy_lints/src`, like `functions` in
+the example command. Clippy groups together some lints that share common behaviors,
+so if your lint falls into one, it would be best to add it to that type.
+
+Overall, you should notice that the following files are modified or created:
+
+```sh
+$ git status
+On branch foo_functions
+Changes not staged for commit:
+ (use "git add <file>..." to update what will be committed)
+ (use "git restore <file>..." to discard changes in working directory)
+ modified: CHANGELOG.md
+ modified: clippy_lints/src/declared_lints.rs
+ modified: clippy_lints/src/functions/mod.rs
+
+Untracked files:
+ (use "git add <file>..." to include in what will be committed)
+ clippy_lints/src/functions/foo_functions.rs
+ tests/ui/foo_functions.rs
+```
+
+
+## The `define_clippy_lints` macro
+
+After `cargo dev new_lint`, you should see a macro with the name
+`define_clippy_lints`. It will be in the same file if you defined a standalone
+lint, and it will be in `mod.rs` if you defined a type-specific lint.
+
+The macro looks something like this:
+
+```rust
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// // Describe here what does the lint do.
+ ///
+ /// Triggers when detects...
+ ///
+ /// ### Why is this bad?
+ ///
+ /// // Describe why this pattern would be bad
+ ///
+ /// It can lead to...
+ ///
+ /// ### Example
+ /// ```rust
+ /// // example code where clippy issues a warning
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// // example code which does not raise clippy warning
+ /// ```
+ #[clippy::version = "1.70.0"] // <- In which version was this implemented, keep it up to date!
+ pub LINT_NAME, // <- The lint name IN_ALL_CAPS
+ pedantic, // <- The lint group
+ "default lint description" // <- A lint description, e.g. "A function has an unit return type."
+}
+```
+
+## Lint registration
+
+If we run the `cargo dev new_lint` command for a new lint, the lint will be
+automatically registered and there is nothing more to do.
+
+However, sometimes we might want to declare a new lint by hand. In this case,
+we'd use `cargo dev update_lints` command afterwards.
+
+When a lint is manually declared, we might need to register the lint pass
+manually in the `register_plugins` function in `clippy_lints/src/lib.rs`:
+
+```rust
+store.register_late_pass(|_| Box::new(foo_functions::FooFunctions));
+```
+
+As you might have guessed, where there's something late, there is something
+early: in Clippy there is a `register_early_pass` method as well. More on early
+vs. late passes in a later chapter.
+<!-- FIXME: Link that "later chapter" when lint_passes.md is merged -->
+
+Without a call to one of `register_early_pass` or `register_late_pass`, the lint
+pass in question will not be run.
+
+
+[all_lints]: https://rust-lang.github.io/rust-clippy/master/
+[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
diff --git a/src/tools/clippy/book/src/development/emitting_lints.md b/src/tools/clippy/book/src/development/emitting_lints.md
new file mode 100644
index 000000000..a12f6aa91
--- /dev/null
+++ b/src/tools/clippy/book/src/development/emitting_lints.md
@@ -0,0 +1,217 @@
+# Emitting a lint
+
+Once we have [defined a lint](defining_lints.md), written [UI
+tests](writing_tests.md) and chosen [the lint pass](lint_passes.md) for the lint,
+we can begin the implementation of the lint logic so that we can emit it and
+gradually work towards a lint that behaves as expected.
+
+Note that we will not go into concrete implementation of a lint logic in this
+chapter. We will go into details in later chapters as well as in two examples of
+real Clippy lints.
+
+To emit a lint, we must implement a pass (see [Lint Passes](lint_passes.md)) for
+the lint that we have declared. In this example we'll implement a "late" lint,
+so take a look at the [LateLintPass][late_lint_pass] documentation, which
+provides an abundance of methods that we can implement for our lint.
+
+```rust
+pub trait LateLintPass<'tcx>: LintPass {
+ // Trait methods
+}
+```
+
+By far the most common method used for Clippy lints is [`check_expr`
+method][late_check_expr], this is because Rust is an expression language and,
+more often than not, the lint we want to work on must examine expressions.
+
+> _Note:_ If you don't fully understand what expressions are in Rust, take a
+> look at the official documentation on [expressions][rust_expressions]
+
+Other common ones include the [`check_fn` method][late_check_fn] and the
+[`check_item` method][late_check_item].
+
+### Emitting a lint
+
+Inside the trait method that we implement, we can write down the lint logic and
+emit the lint with suggestions.
+
+Clippy's [diagnostics] provides quite a few diagnostic functions that we can use
+to emit lints. Take a look at the documentation to pick one that suits your
+lint's needs the best. Some common ones you will encounter in the Clippy
+repository includes:
+
+- [`span_lint`]: Emits a lint without providing any other information
+- [`span_lint_and_note`]: Emits a lint and adds a note
+- [`span_lint_and_help`]: Emits a lint and provides a helpful message
+- [`span_lint_and_sugg`]: Emits a lint and provides a suggestion to fix the code
+- [`span_lint_and_then`]: Like `span_lint`, but allows for a lot of output
+ customization.
+
+```rust
+impl<'tcx> LateLintPass<'tcx> for LintName {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+ // Imagine that `some_lint_expr_logic` checks for requirements for emitting the lint
+ if some_lint_expr_logic(expr) {
+ span_lint_and_help(
+ cx, // < The context
+ LINT_NAME, // < The name of the lint in ALL CAPS
+ expr.span, // < The span to lint
+ "message on why the lint is emitted",
+ None, // < An optional help span (to highlight something in the lint)
+ "message that provides a helpful suggestion",
+ );
+ }
+ }
+}
+```
+
+> Note: The message should be matter of fact and avoid capitalization and
+> punctuation. If multiple sentences are needed, the messages should probably be
+> split up into an error + a help / note / suggestion message.
+
+## Suggestions: Automatic fixes
+
+Some lints know what to change in order to fix the code. For example, the lint
+[`range_plus_one`][range_plus_one] warns for ranges where the user wrote `x..y +
+1` instead of using an [inclusive range][inclusive_range] (`x..=y`). The fix to
+this code would be changing the `x..y + 1` expression to `x..=y`. **This is
+where suggestions come in**.
+
+A suggestion is a change that the lint provides to fix the issue it is linting.
+The output looks something like this (from the example earlier):
+
+```text
+error: an inclusive range would be more readable
+ --> $DIR/range_plus_minus_one.rs:37:14
+ |
+LL | for _ in 1..1 + 1 {}
+ | ^^^^^^^^ help: use: `1..=1`
+```
+
+**Not all suggestions are always right**, some of them require human
+supervision, that's why we have [Applicability][applicability].
+
+Applicability indicates confidence in the correctness of the suggestion, some
+are always right (`Applicability::MachineApplicable`), but we use
+`Applicability::MaybeIncorrect` and others when talking about a suggestion that
+may be incorrect.
+
+### Example
+
+The same lint `LINT_NAME` but that emits a suggestion would look something like this:
+
+```rust
+impl<'tcx> LateLintPass<'tcx> for LintName {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+ // Imagine that `some_lint_expr_logic` checks for requirements for emitting the lint
+ if some_lint_expr_logic(expr) {
+ span_lint_and_sugg( // < Note this change
+ cx,
+ LINT_NAME,
+ span,
+ "message on why the lint is emitted",
+ "use",
+ format!("foo + {} * bar", snippet(cx, expr.span, "<default>")), // < Suggestion
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+}
+```
+
+Suggestions generally use the [`format!`][format_macro] macro to interpolate the
+old values with the new ones. To get code snippets, use one of the `snippet*`
+functions from `clippy_utils::source`.
+
+## How to choose between notes, help messages and suggestions
+
+Notes are presented separately from the main lint message, they provide useful
+information that the user needs to understand why the lint was activated. They
+are the most helpful when attached to a span.
+
+Examples:
+
+### Notes
+
+```text
+error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing.
+ --> $DIR/drop_forget_ref.rs:10:5
+ |
+10 | forget(&SomeStruct);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::forget-ref` implied by `-D warnings`
+note: argument has type &SomeStruct
+ --> $DIR/drop_forget_ref.rs:10:12
+ |
+10 | forget(&SomeStruct);
+ | ^^^^^^^^^^^
+```
+
+### Help Messages
+
+Help messages are specifically to help the user. These are used in situation
+where you can't provide a specific machine applicable suggestion. They can also
+be attached to a span.
+
+Example:
+
+```text
+error: constant division of 0.0 with 0.0 will always result in NaN
+ --> $DIR/zero_div_zero.rs:6:25
+ |
+6 | let other_f64_nan = 0.0f64 / 0.0;
+ | ^^^^^^^^^^^^
+ |
+ = help: consider using `f64::NAN` if you would like a constant representing NaN
+```
+
+### Suggestions
+
+Suggestions are the most helpful, they are changes to the source code to fix the
+error. The magic in suggestions is that tools like `rustfix` can detect them and
+automatically fix your code.
+
+Example:
+
+```text
+error: This `.fold` can be more succinctly expressed as `.any`
+--> $DIR/methods.rs:390:13
+ |
+390 | let _ = (0..3).fold(false, |acc, x| acc || x > 2);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.any(|x| x > 2)`
+ |
+```
+
+### Snippets
+
+Snippets are pieces of the source code (as a string), they are extracted
+generally using the [`snippet`][snippet_fn] function.
+
+For example, if you want to know how an item looks (and you know the item's
+span), you could use `snippet(cx, span, "..")`.
+
+## Final: Run UI Tests to Emit the Lint
+
+Now, if we run our [UI test](writing_tests.md), we should see that Clippy now
+produces output that contains the lint message we designed.
+
+The next step is to implement the logic properly, which is a detail that we will
+cover in the next chapters.
+
+[diagnostics]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/index.html
+[late_check_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_expr
+[late_check_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_fn
+[late_check_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_item
+[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
+[rust_expressions]: https://doc.rust-lang.org/reference/expressions.html
+[`span_lint`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint.html
+[`span_lint_and_note`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_note.html
+[`span_lint_and_help`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_help.html
+[`span_lint_and_sugg`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html
+[`span_lint_and_then`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_then.html
+[range_plus_one]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one
+[inclusive_range]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html
+[applicability]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_errors/enum.Applicability.html
+[snippet_fn]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/source/fn.snippet.html
+[format_macro]: https://doc.rust-lang.org/std/macro.format.html
diff --git a/src/tools/clippy/book/src/development/method_checking.md b/src/tools/clippy/book/src/development/method_checking.md
new file mode 100644
index 000000000..56d1be375
--- /dev/null
+++ b/src/tools/clippy/book/src/development/method_checking.md
@@ -0,0 +1,93 @@
+# Method Checking
+
+In some scenarios we might want to check for methods when developing
+a lint. There are two kinds of questions that we might be curious about:
+
+- Invocation: Does an expression call a specific method?
+- Definition: Does an `impl` define a method?
+
+## Checking if an `expr` is calling a specific method
+
+Suppose we have an `expr`, we can check whether it calls a specific
+method, e.g. `our_fancy_method`, by performing a pattern match on
+the [`ExprKind`] that we can access from `expr.kind`:
+
+```rust
+use rustc_hir as hir;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_span::sym;
+use clippy_utils::is_trait_method;
+
+impl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
+ // Check our expr is calling a method with pattern matching
+ if let hir::ExprKind::MethodCall(path, _, [self_arg, ..]) = &expr.kind
+ // Check if the name of this method is `our_fancy_method`
+ && path.ident.name == sym!(our_fancy_method)
+ // We can check the type of the self argument whenever necessary.
+ // (It's necessary if we want to check that method is specifically belonging to a specific trait,
+ // for example, a `map` method could belong to user-defined trait instead of to `Iterator`)
+ // See the next section for more information.
+ && is_trait_method(cx, self_arg, sym::OurFancyTrait)
+ {
+ println!("`expr` is a method call for `our_fancy_method`");
+ }
+ }
+}
+```
+
+Take a closer look at the `ExprKind` enum variant [`MethodCall`] for more
+information on the pattern matching. As mentioned in [Define
+Lints](defining_lints.md#lint-types), the `methods` lint type is full of pattern
+matching with `MethodCall` in case the reader wishes to explore more.
+
+Additionally, we use the [`clippy_utils::sym!`][sym] macro to conveniently
+convert an input `our_fancy_method` into a `Symbol` and compare that symbol to
+the [`Ident`]'s name in the [`PathSegment`] in the [`MethodCall`].
+
+## Checking if a `impl` block implements a method
+
+While sometimes we want to check whether a method is being called or not, other
+times we want to know if our `Ty` defines a method.
+
+To check if our `impl` block defines a method `our_fancy_method`, we will
+utilize the [`check_impl_item`] method that is available in our beloved
+[`LateLintPass`] (for more information, refer to the ["Lint
+Passes"](lint_passes.md) chapter in the Clippy book). This method provides us
+with an [`ImplItem`] struct, which represents anything within an `impl` block.
+
+Let us take a look at how we might check for the implementation of
+`our_fancy_method` on a type:
+
+```rust
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::return_ty;
+use rustc_hir::{ImplItem, ImplItemKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_span::symbol::sym;
+
+impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
+ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
+ // Check if item is a method/function
+ if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
+ // Check the method is named `our_fancy_method`
+ && impl_item.ident.name == sym!(our_fancy_method)
+ // We can also check it has a parameter `self`
+ && signature.decl.implicit_self.has_implicit_self()
+ // We can go even further and even check if its return type is `String`
+ && is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym::String)
+ {
+ println!("`our_fancy_method` is implemented!");
+ }
+ }
+}
+```
+
+[`check_impl_item`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_impl_item
+[`ExprKind`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html
+[`Ident`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/struct.Ident.html
+[`ImplItem`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_hir/hir/struct.ImplItem.html
+[`LateLintPass`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html
+[`MethodCall`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html#variant.MethodCall
+[`PathSegment`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/struct.PathSegment.html
+[sym]: https://doc.rust-lang.org/stable/nightly-rustc/clippy_utils/macro.sym.html
diff --git a/src/tools/clippy/book/src/development/speedtest.md b/src/tools/clippy/book/src/development/speedtest.md
index 0db718e6a..4ea1c8e5c 100644
--- a/src/tools/clippy/book/src/development/speedtest.md
+++ b/src/tools/clippy/book/src/development/speedtest.md
@@ -9,16 +9,12 @@ accessed by the `SPEEDTEST` (and `SPEEDTEST_*`) environment variables.
To do a simple speed test of a lint (e.g. `allow_attributes`), use this command.
```sh
-$ SPEEDTEST=ui TESTNAME="allow_attributes" cargo uitest -- --nocapture
+$ SPEEDTEST=ui TESTNAME="allow_attributes" cargo uitest
```
This will test all `ui` tests (`SPEEDTEST=ui`) whose names start with `allow_attributes`. By default, `SPEEDTEST` will
iterate your test 1000 times. But you can change this with `SPEEDTEST_ITERATIONS`.
```sh
-$ SPEEDTEST=toml SPEEDTEST_ITERATIONS=100 TESTNAME="semicolon_block" cargo uitest -- --nocapture
+$ SPEEDTEST=toml SPEEDTEST_ITERATIONS=100 TESTNAME="semicolon_block" cargo uitest
```
-
-> **WARNING**: Be sure to use `-- --nocapture` at the end of the command to see the average test time. If you don't
-> use `-- --nocapture` (e.g. `SPEEDTEST=ui` `TESTNAME="let_underscore_untyped" cargo uitest -- --nocapture`), this
-> will not show up.
diff --git a/src/tools/clippy/book/src/development/trait_checking.md b/src/tools/clippy/book/src/development/trait_checking.md
new file mode 100644
index 000000000..fb263922c
--- /dev/null
+++ b/src/tools/clippy/book/src/development/trait_checking.md
@@ -0,0 +1,105 @@
+# Trait Checking
+
+Besides [type checking](type_checking.md), we might want to examine if
+a specific type `Ty` implements certain trait when implementing a lint.
+There are three approaches to achieve this, depending on if the target trait
+that we want to examine has a [diagnostic item][diagnostic_items],
+[lang item][lang_items], or neither.
+
+## Using Diagnostic Items
+
+As explained in the [Rust Compiler Development Guide][rustc_dev_guide], diagnostic items
+are introduced for identifying types via [Symbols][symbol].
+
+For instance, if we want to examine whether an expression implements
+the `Iterator` trait, we could simply write the following code,
+providing the `LateContext` (`cx`), our expression at hand, and
+the symbol of the trait in question:
+
+```rust
+use clippy_utils::is_trait_method;
+use rustc_hir::Expr;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_span::symbol::sym;
+
+impl LateLintPass<'_> for CheckIteratorTraitLint {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+ let implements_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
+ implements_trait(cx, cx.typeck_results().expr_ty(arg), id, &[])
+ });
+ if implements_iterator {
+ // [...]
+ }
+
+ }
+}
+```
+
+> **Note**: Refer to [this index][symbol_index] for all the defined `Symbol`s.
+
+## Using Lang Items
+
+Besides diagnostic items, we can also use [`lang_items`][lang_items].
+Take a look at the documentation to find that `LanguageItems` contains
+all language items defined in the compiler.
+
+Using one of its `*_trait` method, we could obtain the [DefId] of any
+specific item, such as `Clone`, `Copy`, `Drop`, `Eq`, which are familiar
+to many Rustaceans.
+
+For instance, if we want to examine whether an expression `expr` implements
+`Drop` trait, we could access `LanguageItems` via our `LateContext`'s
+[TyCtxt], which provides a `lang_items` method that will return the id of
+`Drop` trait to us. Then, by calling Clippy utils function `implements_trait`
+we can check that the `Ty` of the `expr` implements the trait:
+
+```rust
+use clippy_utils::implements_trait;
+use rustc_hir::Expr;
+use rustc_lint::{LateContext, LateLintPass};
+
+impl LateLintPass<'_> for CheckDropTraitLint {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+ let ty = cx.typeck_results().expr_ty(expr);
+ if cx.tcx.lang_items()
+ .drop_trait()
+ .map_or(false, |id| implements_trait(cx, ty, id, &[])) {
+ println!("`expr` implements `Drop` trait!");
+ }
+ }
+}
+```
+
+## Using Type Path
+
+If neither diagnostic item nor a language item is available, we can use
+[`clippy_utils::paths`][paths] with the `match_trait_method` to determine trait
+implementation.
+
+> **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.
+
+Below, we check if the given `expr` implements the `Iterator`'s trait method `cloned` :
+
+```rust
+use clippy_utils::{match_trait_method, paths};
+use rustc_hir::Expr;
+use rustc_lint::{LateContext, LateLintPass};
+
+impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+ if match_trait_method(cx, expr, &paths::CORE_ITER_CLONED) {
+ println!("`expr` implements `CORE_ITER_CLONED` trait!");
+ }
+ }
+}
+```
+
+[DefId]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
+[diagnostic_items]: https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html
+[lang_items]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/lang_items/struct.LanguageItems.html
+[paths]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_utils/src/paths.rs
+[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/
+[symbol]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html
+[symbol_index]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/sym/index.html
+[TyCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html
+[rust]: https://github.com/rust-lang/rust
diff --git a/src/tools/clippy/book/src/development/writing_tests.md b/src/tools/clippy/book/src/development/writing_tests.md
new file mode 100644
index 000000000..8937e0d8e
--- /dev/null
+++ b/src/tools/clippy/book/src/development/writing_tests.md
@@ -0,0 +1,218 @@
+# Testing
+
+Developing lints for Clippy is a Test-Driven Development (TDD) process because
+our first task before implementing any logic for a new lint is to write some test cases.
+
+## Develop Lints with Tests
+
+When we develop Clippy, we enter a complex and chaotic realm full of
+programmatic issues, stylistic errors, illogical code and non-adherence to convention.
+Tests are the first layer of order we can leverage to define when and where
+we want a new lint to trigger or not.
+
+Moreover, writing tests first help Clippy developers to find a balance for
+the first iteration of and further enhancements for a lint.
+With test cases on our side, we will not have to worry about over-engineering
+a lint on its first version nor missing out some obvious edge cases of the lint.
+This approach empowers us to iteratively enhance each lint.
+
+## Clippy UI Tests
+
+We use **UI tests** for testing in Clippy. These UI tests check that the output
+of Clippy is exactly as we expect it to be. Each test is just a plain Rust file
+that contains the code we want to check.
+
+The output of Clippy is compared against a `.stderr` file. Note that you don't
+have to create this file yourself. We'll get to generating the `.stderr` files
+with the command [`cargo bless`](#cargo-bless) (seen later on).
+
+### Write Test Cases
+
+Let us now think about some tests for our imaginary `foo_functions` lint. We
+start by opening the test file `tests/ui/foo_functions.rs` that was created by
+`cargo dev new_lint`.
+
+Update the file with some examples to get started:
+
+```rust
+#![warn(clippy::foo_functions)] // < Add this, so the lint is guaranteed to be enabled in this file
+
+// Impl methods
+struct A;
+impl A {
+ pub fn fo(&self) {}
+ pub fn foo(&self) {} //~ ERROR: function called "foo"
+ pub fn food(&self) {}
+}
+
+// Default trait methods
+trait B {
+ fn fo(&self) {}
+ fn foo(&self) {} //~ ERROR: function called "foo"
+ fn food(&self) {}
+}
+
+// Plain functions
+fn fo() {}
+fn foo() {} //~ ERROR: function called "foo"
+fn food() {}
+
+fn main() {
+ // We also don't want to lint method calls
+ foo();
+ let a = A;
+ a.foo();
+}
+```
+
+Without actual lint logic to emit the lint when we see a `foo` function name,
+this test will just pass, because no lint will be emitted. However, we can now
+run the test with the following command:
+
+```sh
+$ TESTNAME=foo_functions cargo uitest
+```
+
+Clippy will compile and it will conclude with an `ok` for the tests:
+
+```
+...Clippy warnings and test outputs...
+test compile_test ... ok
+test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.48s
+```
+
+This is normal. After all, we wrote a bunch of Rust code but we haven't really
+implemented any logic for Clippy to detect `foo` functions and emit a lint.
+
+As we gradually implement our lint logic, we will keep running this UI test command.
+Clippy will begin outputting information that allows us to check if the output is
+turning into what we want it to be.
+
+### Example output
+
+As our `foo_functions` lint is tested, the output would look something like this:
+
+```
+failures:
+---- compile_test stdout ----
+normalized stderr:
+error: function called "foo"
+ --> $DIR/foo_functions.rs:6:12
+ |
+LL | pub fn foo(&self) {}
+ | ^^^
+ |
+ = note: `-D clippy::foo-functions` implied by `-D warnings`
+error: function called "foo"
+ --> $DIR/foo_functions.rs:13:8
+ |
+LL | fn foo(&self) {}
+ | ^^^
+error: function called "foo"
+ --> $DIR/foo_functions.rs:19:4
+ |
+LL | fn foo() {}
+ | ^^^
+error: aborting due to 3 previous errors
+```
+
+Note the *failures* label at the top of the fragment, we'll get rid of it
+(saving this output) in the next section.
+
+> _Note:_ You can run multiple test files by specifying a comma separated list:
+> `TESTNAME=foo_functions,bar_methods,baz_structs`.
+
+### `cargo bless`
+
+Once we are satisfied with the output, we need to run this command to
+generate or update the `.stderr` file for our lint:
+
+```sh
+$ TESTNAME=foo_functions cargo uibless
+```
+
+This writes the emitted lint suggestions and fixes to the `.stderr` file, with
+the reason for the lint, suggested fixes, and line numbers, etc.
+
+Running `TESTNAME=foo_functions cargo uitest` should pass then. When we commit
+our lint, we need to commit the generated `.stderr` files, too.
+
+In general, you should only commit files changed by `cargo bless` for the
+specific lint you are creating/editing.
+
+> _Note:_ If the generated `.stderr`, and `.fixed` files are empty,
+> they should be removed.
+
+## `toml` Tests
+
+Some lints can be configured through a `clippy.toml` file. Those configuration
+values are tested in `tests/ui-toml`.
+
+To add a new test there, create a new directory and add the files:
+
+- `clippy.toml`: Put here the configuration value you want to test.
+- `lint_name.rs`: A test file where you put the testing code, that should see a
+ different lint behavior according to the configuration set in the
+ `clippy.toml` file.
+
+The potential `.stderr` and `.fixed` files can again be generated with `cargo
+bless`.
+
+## Cargo Lints
+
+The process of testing is different for Cargo lints in that now we are
+interested in the `Cargo.toml` manifest file. In this case, we also need a
+minimal crate associated with that manifest. Those tests are generated in
+`tests/ui-cargo`.
+
+Imagine we have a new example lint that is named `foo_categories`, we can run:
+
+```sh
+$ cargo dev new_lint --name=foo_categories --pass=late --category=cargo
+```
+
+After running `cargo dev new_lint` we will find by default two new crates,
+each with its manifest file:
+
+* `tests/ui-cargo/foo_categories/fail/Cargo.toml`: this file should cause the
+ new lint to raise an error.
+* `tests/ui-cargo/foo_categories/pass/Cargo.toml`: this file should not trigger
+ the lint.
+
+If you need more cases, you can copy one of those crates (under
+`foo_categories`) and rename it.
+
+The process of generating the `.stderr` file is the same as for other lints
+and prepending the `TESTNAME` variable to `cargo uitest` works for Cargo lints too.
+
+## Rustfix Tests
+
+If the lint you are working on is making use of structured suggestions,
+[`rustfix`] will apply the suggestions from the lint to the test file code and
+compare that to the contents of a `.fixed` file.
+
+Structured suggestions tell a user how to fix or re-write certain code that has
+been linted with [`span_lint_and_sugg`].
+
+Should `span_lint_and_sugg` be used to generate a suggestion, but not all
+suggestions lead to valid code, you can use the `//@no-rustfix` comment on top
+of the test file, to not run `rustfix` on that file.
+
+We'll talk about suggestions more in depth in a [later chapter](emitting_lints.md).
+
+Use `cargo bless` to automatically generate the `.fixed` file after running
+the tests.
+
+[`rustfix`]: https://github.com/rust-lang/rustfix
+[`span_lint_and_sugg`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html
+
+## Testing Manually
+
+Manually testing against an example file can be useful if you have added some
+`println!`s and the test suite output becomes unreadable.
+
+To try Clippy with your local modifications, run from the working copy root.
+
+```sh
+$ cargo dev lint input.rs
+```
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index caaad6d11..b980083f1 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -703,7 +703,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted.
## `accept-comment-above-statement`
Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
-**Default Value:** `false` (`bool`)
+**Default Value:** `true` (`bool`)
---
**Affected lints:**
@@ -713,7 +713,7 @@ Whether to accept a safety comment to be placed above the statement containing t
## `accept-comment-above-attributes`
Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
-**Default Value:** `false` (`bool`)
+**Default Value:** `true` (`bool`)
---
**Affected lints:**
@@ -751,3 +751,37 @@ Which crates to allow absolute paths from
* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
+## `allowed-dotfiles`
+Additional dotfiles (files or directories starting with a dot) to allow
+
+**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
+
+---
+**Affected lints:**
+* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
+
+
+## `enforce-iter-loop-reborrow`
+#### Example
+```
+let mut vec = vec![1, 2, 3];
+let rmvec = &mut vec;
+for _ in rmvec.iter() {}
+for _ in rmvec.iter_mut() {}
+```
+
+Use instead:
+```
+let mut vec = vec![1, 2, 3];
+let rmvec = &mut vec;
+for _ in &*rmvec {}
+for _ in &mut *rmvec {}
+```
+
+**Default Value:** `false` (`bool`)
+
+---
+**Affected lints:**
+* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop)
+
+
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index 7c2e06ea6..842aeed2a 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -690,7 +690,6 @@ fn gen_deprecated_lints_test(lints: &[DeprecatedLint]) -> String {
fn gen_renamed_lints_test(lints: &[RenamedLint]) -> String {
let mut seen_lints = HashSet::new();
let mut res: String = GENERATED_FILE_COMMENT.into();
- res.push_str("//@run-rustfix\n\n");
for lint in lints {
if seen_lints.insert(&lint.new_name) {
writeln!(res, "#![allow({})]", lint.new_name).unwrap();
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 11136867f..dcd9a4adc 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy_lints"
-version = "0.1.73"
+version = "0.1.74"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
@@ -15,7 +15,6 @@ clippy_utils = { path = "../clippy_utils" }
declare_clippy_lint = { path = "../declare_clippy_lint" }
if_chain = "1.0"
itertools = "0.10.1"
-pulldown-cmark = { version = "0.9", default-features = false }
quine-mc_cluskey = "0.2"
regex-syntax = "0.7"
serde = { version = "1.0", features = ["derive"] }
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index 2a5be2756..0546807ba 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -6,7 +6,11 @@ use clippy_utils::macros::{is_panic, macro_backtrace};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
use if_chain::if_chain;
-use rustc_ast::{AttrKind, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
+use rustc_ast::token::{Token, TokenKind};
+use rustc_ast::tokenstream::TokenTree;
+use rustc_ast::{
+ AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem,
+};
use rustc_errors::Applicability;
use rustc_hir::{
Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
@@ -341,6 +345,41 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
+ /// Checks for `#[should_panic]` attributes without specifying the expected panic message.
+ ///
+ /// ### Why is this bad?
+ /// The expected panic message should be specified to ensure that the test is actually
+ /// panicking with the expected message, and not another unrelated panic.
+ ///
+ /// ### Example
+ /// ```rust
+ /// fn random() -> i32 { 0 }
+ ///
+ /// #[should_panic]
+ /// #[test]
+ /// fn my_test() {
+ /// let _ = 1 / random();
+ /// }
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// fn random() -> i32 { 0 }
+ ///
+ /// #[should_panic = "attempt to divide by zero"]
+ /// #[test]
+ /// fn my_test() {
+ /// let _ = 1 / random();
+ /// }
+ /// ```
+ #[clippy::version = "1.73.0"]
+ pub SHOULD_PANIC_WITHOUT_EXPECT,
+ pedantic,
+ "ensures that all `should_panic` attributes specify its expected panic message"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
/// Checks for `any` and `all` combinators in `cfg` with only one condition.
///
/// ### Why is this bad?
@@ -395,6 +434,7 @@ declare_lint_pass!(Attributes => [
DEPRECATED_SEMVER,
USELESS_ATTRIBUTE,
BLANKET_CLIPPY_RESTRICTION_LINTS,
+ SHOULD_PANIC_WITHOUT_EXPECT,
]);
impl<'tcx> LateLintPass<'tcx> for Attributes {
@@ -442,6 +482,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
}
}
}
+ if attr.has_name(sym::should_panic) {
+ check_should_panic_reason(cx, attr);
+ }
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
@@ -550,6 +593,35 @@ fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
None
}
+fn check_should_panic_reason(cx: &LateContext<'_>, attr: &Attribute) {
+ if let AttrKind::Normal(normal_attr) = &attr.kind {
+ if let AttrArgs::Eq(_, AttrArgsEq::Hir(_)) = &normal_attr.item.args {
+ // `#[should_panic = ".."]` found, good
+ return;
+ }
+
+ if let AttrArgs::Delimited(args) = &normal_attr.item.args
+ && let mut tt_iter = args.tokens.trees()
+ && let Some(TokenTree::Token(Token { kind: TokenKind::Ident(sym::expected, _), .. }, _)) = tt_iter.next()
+ && let Some(TokenTree::Token(Token { kind: TokenKind::Eq, .. }, _)) = tt_iter.next()
+ && let Some(TokenTree::Token(Token { kind: TokenKind::Literal(_), .. }, _)) = tt_iter.next()
+ {
+ // `#[should_panic(expected = "..")]` found, good
+ return;
+ }
+
+ span_lint_and_sugg(
+ cx,
+ SHOULD_PANIC_WITHOUT_EXPECT,
+ attr.span,
+ "#[should_panic] attribute without a reason",
+ "consider specifying the expected panic",
+ "#[should_panic(expected = /* panic message */)]".into(),
+ Applicability::HasPlaceholders,
+ );
+ }
+}
+
fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
for lint in items {
if let Some(lint_name) = extract_clippy_lint(lint) {
diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
index d40a38543..7dd808a7b 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -2,9 +2,9 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{match_def_path, paths};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefId;
-use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind};
+use rustc_hir::{AsyncGeneratorKind, Body, GeneratorKind};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::GeneratorInteriorTypeCause;
+use rustc_middle::mir::GeneratorLayout;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{sym, Span};
@@ -197,28 +197,35 @@ impl LateLintPass<'_> for AwaitHolding {
fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
use AsyncGeneratorKind::{Block, Closure, Fn};
if let Some(GeneratorKind::Async(Block | Closure | Fn)) = body.generator_kind {
- let body_id = BodyId {
- hir_id: body.value.hir_id,
- };
- let typeck_results = cx.tcx.typeck_body(body_id);
- self.check_interior_types(
- cx,
- typeck_results.generator_interior_types.as_ref().skip_binder(),
- body.value.span,
- );
+ let def_id = cx.tcx.hir().body_owner_def_id(body.id());
+ if let Some(generator_layout) = cx.tcx.mir_generator_witnesses(def_id) {
+ self.check_interior_types(cx, generator_layout);
+ }
}
}
}
impl AwaitHolding {
- fn check_interior_types(&self, cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) {
- for ty_cause in ty_causes {
+ fn check_interior_types(&self, cx: &LateContext<'_>, generator: &GeneratorLayout<'_>) {
+ for (ty_index, ty_cause) in generator.field_tys.iter_enumerated() {
if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
+ let await_points = || {
+ generator
+ .variant_source_info
+ .iter_enumerated()
+ .filter_map(|(variant, source_info)| {
+ generator.variant_fields[variant]
+ .raw
+ .contains(&ty_index)
+ .then_some(source_info.span)
+ })
+ .collect::<Vec<_>>()
+ };
if is_mutex_guard(cx, adt.did()) {
span_lint_and_then(
cx,
AWAIT_HOLDING_LOCK,
- ty_cause.span,
+ ty_cause.source_info.span,
"this `MutexGuard` is held across an `await` point",
|diag| {
diag.help(
@@ -226,7 +233,7 @@ impl AwaitHolding {
`MutexGuard` is dropped before calling await",
);
diag.span_note(
- ty_cause.scope_span.unwrap_or(span),
+ await_points(),
"these are all the `await` points this lock is held through",
);
},
@@ -235,18 +242,18 @@ impl AwaitHolding {
span_lint_and_then(
cx,
AWAIT_HOLDING_REFCELL_REF,
- ty_cause.span,
+ ty_cause.source_info.span,
"this `RefCell` reference is held across an `await` point",
|diag| {
diag.help("ensure the reference is dropped before calling `await`");
diag.span_note(
- ty_cause.scope_span.unwrap_or(span),
+ await_points(),
"these are all the `await` points this reference is held through",
);
},
);
} else if let Some(disallowed) = self.def_ids.get(&adt.did()) {
- emit_invalid_type(cx, ty_cause.span, disallowed);
+ emit_invalid_type(cx, ty_cause.source_info.span, disallowed);
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
index cf07e050c..c586b572b 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -25,7 +25,7 @@ pub(super) fn check(
// The suggestion is to use a function call, so if the original expression
// has parens on the outside, they are no longer needed.
let mut applicability = Applicability::MachineApplicable;
- let opt = snippet_opt(cx, cast_op.span);
+ let opt = snippet_opt(cx, cast_op.span.source_callsite());
let sugg = opt.as_ref().map_or_else(
|| {
applicability = Applicability::HasPlaceholders;
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 84b99ad5c..f99a51e2b 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -44,7 +44,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
.unwrap_or(u64::max_value())
.min(apply_reductions(cx, nbits, left, signed)),
BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)
- .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))),
+ .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).unwrap_or_default())),
_ => nbits,
},
ExprKind::MethodCall(method, left, [right], _) => {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index 5bf467efa..1de691221 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -5,6 +5,7 @@ use rustc_hir::{Expr, ExprKind, GenericArg};
use rustc_lint::LateContext;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Ty};
+use rustc_span::sym;
use super::CAST_PTR_ALIGNMENT;
@@ -76,13 +77,14 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
ExprKind::Call(func, [arg, ..]) if arg.hir_id == e.hir_id => {
static PATHS: &[&[&str]] = &[
paths::PTR_READ_UNALIGNED.as_slice(),
- paths::PTR_WRITE_UNALIGNED.as_slice(),
paths::PTR_UNALIGNED_VOLATILE_LOAD.as_slice(),
paths::PTR_UNALIGNED_VOLATILE_STORE.as_slice(),
];
+
if let ExprKind::Path(path) = &func.kind
&& let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
- && match_any_def_paths(cx, def_id, PATHS).is_some()
+ && (match_any_def_paths(cx, def_id, PATHS).is_some()
+ || cx.tcx.is_diagnostic_item(sym::ptr_write_unaligned, def_id))
{
true
} else {
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index d34de305f..b00130ffd 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -20,6 +20,7 @@ mod ptr_as_ptr;
mod ptr_cast_constness;
mod unnecessary_cast;
mod utils;
+mod zero_ptr;
use clippy_utils::is_hir_ty_cfg_dependant;
use clippy_utils::msrvs::{self, Msrv};
@@ -418,7 +419,7 @@ declare_clippy_lint! {
/// let mut_ptr = ptr.cast_mut();
/// let ptr = mut_ptr.cast_const();
/// ```
- #[clippy::version = "1.71.0"]
+ #[clippy::version = "1.72.0"]
pub PTR_CAST_CONSTNESS,
pedantic,
"casting using `as` from and to raw pointers to change constness when specialized methods apply"
@@ -665,6 +666,29 @@ declare_clippy_lint! {
"casting a known floating-point NaN into an integer"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Catch casts from `0` to some pointer type
+ ///
+ /// ### Why is this bad?
+ /// This generally means `null` and is better expressed as
+ /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let a = 0 as *const u32;
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// let a = std::ptr::null::<u32>();
+ /// ```
+ #[clippy::version = "pre 1.29.0"]
+ pub ZERO_PTR,
+ style,
+ "using `0 as *{const, mut} T`"
+}
+
pub struct Casts {
msrv: Msrv,
}
@@ -699,6 +723,7 @@ impl_lint_pass!(Casts => [
CAST_SLICE_FROM_RAW_PARTS,
AS_PTR_CAST_MUT,
CAST_NAN_TO_INT,
+ ZERO_PTR,
]);
impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -729,6 +754,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
+ zero_ptr::check(cx, expr, cast_expr, cast_to_hir);
if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to, cast_to_hir.span);
diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
new file mode 100644
index 000000000..5071af5ec
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
@@ -0,0 +1,39 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_opt;
+use clippy_utils::{in_constant, is_integer_literal, std_or_core};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, Mutability, Ty, TyKind};
+use rustc_lint::LateContext;
+
+use super::ZERO_PTR;
+
+pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {
+ if let TyKind::Ptr(ref mut_ty) = to.kind
+ && is_integer_literal(from, 0)
+ && !in_constant(cx, from.hir_id)
+ && let Some(std_or_core) = std_or_core(cx)
+ {
+ let (msg, sugg_fn) = match mut_ty.mutbl {
+ Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
+ Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
+ };
+
+ let sugg = if let TyKind::Infer = mut_ty.ty.kind {
+ format!("{std_or_core}::{sugg_fn}()")
+ } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
+ format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()")
+ } else {
+ return;
+ };
+
+ span_lint_and_sugg(
+ cx,
+ ZERO_PTR,
+ expr.span,
+ msg,
+ "try",
+ sugg,
+ Applicability::MachineApplicable,
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index db114abfc..4d1281ec1 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -58,6 +58,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::attrs::MAYBE_MISUSED_CFG_INFO,
crate::attrs::MISMATCHED_TARGET_OS_INFO,
crate::attrs::NON_MINIMAL_CFG_INFO,
+ crate::attrs::SHOULD_PANIC_WITHOUT_EXPECT_INFO,
crate::attrs::USELESS_ATTRIBUTE_INFO,
crate::await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE_INFO,
crate::await_holding_invalid::AWAIT_HOLDING_LOCK_INFO,
@@ -96,6 +97,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::casts::PTR_AS_PTR_INFO,
crate::casts::PTR_CAST_CONSTNESS_INFO,
crate::casts::UNNECESSARY_CAST_INFO,
+ crate::casts::ZERO_PTR_INFO,
crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,
@@ -208,9 +210,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::implicit_return::IMPLICIT_RETURN_INFO,
crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
+ crate::implied_bounds_in_impls::IMPLIED_BOUNDS_IN_IMPLS_INFO,
crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
- crate::incorrect_impls::INCORRECT_CLONE_IMPL_ON_COPY_TYPE_INFO,
- crate::incorrect_impls::INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE_INFO,
crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
crate::indexing_slicing::INDEXING_SLICING_INFO,
crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO,
@@ -363,6 +364,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::methods::ITER_NTH_ZERO_INFO,
crate::methods::ITER_ON_EMPTY_COLLECTIONS_INFO,
crate::methods::ITER_ON_SINGLE_ITEMS_INFO,
+ crate::methods::ITER_OUT_OF_BOUNDS_INFO,
crate::methods::ITER_OVEREAGER_CLONED_INFO,
crate::methods::ITER_SKIP_NEXT_INFO,
crate::methods::ITER_SKIP_ZERO_INFO,
@@ -398,9 +400,11 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::methods::OR_FUN_CALL_INFO,
crate::methods::OR_THEN_UNWRAP_INFO,
crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,
+ crate::methods::PATH_ENDS_WITH_EXT_INFO,
crate::methods::RANGE_ZIP_WITH_LEN_INFO,
crate::methods::READONLY_WRITE_LOCK_INFO,
crate::methods::READ_LINE_WITHOUT_TRIM_INFO,
+ crate::methods::REDUNDANT_AS_STR_INFO,
crate::methods::REPEAT_ONCE_INFO,
crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,
crate::methods::SEARCH_IS_SOME_INFO,
@@ -440,7 +444,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
crate::misc::TOPLEVEL_REF_ARG_INFO,
crate::misc::USED_UNDERSCORE_BINDING_INFO,
- crate::misc::ZERO_PTR_INFO,
crate::misc_early::BUILTIN_TYPE_SHADOW_INFO,
crate::misc_early::DOUBLE_NEG_INFO,
crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO,
@@ -454,6 +457,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::misc_early::ZERO_PREFIXED_LITERAL_INFO,
crate::mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER_INFO,
crate::missing_assert_message::MISSING_ASSERT_MESSAGE_INFO,
+ crate::missing_asserts_for_indexing::MISSING_ASSERTS_FOR_INDEXING_INFO,
crate::missing_const_for_fn::MISSING_CONST_FOR_FN_INFO,
crate::missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS_INFO,
crate::missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES_INFO,
@@ -477,6 +481,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::needless_bool::NEEDLESS_BOOL_INFO,
crate::needless_bool::NEEDLESS_BOOL_ASSIGN_INFO,
crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO,
+ crate::needless_borrows_for_generic_args::NEEDLESS_BORROWS_FOR_GENERIC_ARGS_INFO,
crate::needless_continue::NEEDLESS_CONTINUE_INFO,
crate::needless_else::NEEDLESS_ELSE_INFO,
crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,
@@ -494,6 +499,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::no_effect::NO_EFFECT_UNDERSCORE_BINDING_INFO,
crate::no_effect::UNNECESSARY_OPERATION_INFO,
crate::no_mangle_with_rust_abi::NO_MANGLE_WITH_RUST_ABI_INFO,
+ crate::non_canonical_impls::NON_CANONICAL_CLONE_IMPL_INFO,
+ crate::non_canonical_impls::NON_CANONICAL_PARTIAL_ORD_IMPL_INFO,
crate::non_copy_const::BORROW_INTERIOR_MUTABLE_CONST_INFO,
crate::non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST_INFO,
crate::non_expressive_names::JUST_UNDERSCORES_AND_DIGITS_INFO,
@@ -578,6 +585,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::reference::DEREF_ADDROF_INFO,
crate::regex::INVALID_REGEX_INFO,
crate::regex::TRIVIAL_REGEX_INFO,
+ crate::reserve_after_initialization::RESERVE_AFTER_INITIALIZATION_INFO,
crate::return_self_not_must_use::RETURN_SELF_NOT_MUST_USE_INFO,
crate::returns::LET_AND_RETURN_INFO,
crate::returns::NEEDLESS_RETURN_INFO,
@@ -666,6 +674,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO,
crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO,
crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,
+ crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
crate::unnecessary_struct_initialization::UNNECESSARY_STRUCT_INITIALIZATION_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
index 03b5a2d6d..63ec81950 100644
--- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
@@ -1,8 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{self as hir, HirId, Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{HirId, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::ty::{self, FieldDef, GenericArg, List};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@@ -52,7 +52,10 @@ declare_lint_pass!(DefaultUnionRepresentation => [DEFAULT_UNION_REPRESENTATION])
impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
- if is_union_with_two_non_zst_fields(cx, item) && !has_c_repr_attr(cx, item.hir_id()) {
+ if !item.span.from_expansion()
+ && is_union_with_two_non_zst_fields(cx, item)
+ && !has_c_repr_attr(cx, item.hir_id())
+ {
span_lint_and_help(
cx,
DEFAULT_UNION_REPRESENTATION,
@@ -69,19 +72,21 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
}
/// Returns true if the given item is a union with at least two non-ZST fields.
+/// (ZST fields having an arbitrary offset is completely inconsequential, and
+/// if there is only one field left after ignoring ZST fields then the offset
+/// of that field does not matter either.)
fn is_union_with_two_non_zst_fields(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
- if let ItemKind::Union(data, _) = &item.kind {
- data.fields().iter().filter(|f| !is_zst(cx, f.ty)).count() >= 2
+ if let ItemKind::Union(..) = &item.kind
+ && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
+ {
+ adt_def.all_fields().filter(|f| !is_zst(cx, f, args)).count() >= 2
} else {
false
}
}
-fn is_zst(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) -> bool {
- if hir_ty.span.from_expansion() {
- return false;
- }
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: &'tcx List<GenericArg<'tcx>>) -> bool {
+ let ty = field.ty(cx.tcx, args);
if let Ok(layout) = cx.layout_of(ty) {
layout.is_zst()
} else {
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 58c278550..148773856 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1,42 +1,24 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
-use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::ty::{is_copy, peel_mid_ty_refs};
+use clippy_utils::ty::{implements_trait, peel_mid_ty_refs};
use clippy_utils::{
expr_use_ctxt, get_parent_expr, get_parent_node, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode,
};
-
-use hir::def::DefKind;
-use hir::MatchSource;
use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::graph::iterate::{CycleDetector, TriColorDepthFirstSearch};
use rustc_errors::Applicability;
-use rustc_hir::def::Res;
-use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{
- self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind,
- Path, QPath, TyKind, UnOp,
+ self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node,
+ Pat, PatKind, Path, QPath, TyKind, UnOp,
};
-use rustc_index::bit_set::BitSet;
-use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::{Rvalue, StatementKind};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
-use rustc_middle::ty::{
- self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, List, ParamEnv, ParamTy, ProjectionPredicate, Ty,
- TyCtxt, TypeVisitableExt, TypeckResults,
-};
+use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
-use rustc_trait_selection::infer::InferCtxtExt as _;
-use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
-use rustc_trait_selection::traits::{Obligation, ObligationCause};
-use std::collections::VecDeque;
declare_clippy_lint! {
/// ### What it does
@@ -184,24 +166,6 @@ pub struct Dereferencing<'tcx> {
///
/// e.g. `m!(x) | Foo::Bar(ref x)`
ref_locals: FxIndexMap<HirId, Option<RefPat>>,
-
- /// Stack of (body owner, `PossibleBorrowerMap`) pairs. Used by
- /// `needless_borrow_impl_arg_position` to determine when a borrowed expression can instead
- /// be moved.
- possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
-
- // `IntoIterator` for arrays requires Rust 1.53.
- msrv: Msrv,
-}
-
-impl<'tcx> Dereferencing<'tcx> {
- #[must_use]
- pub fn new(msrv: Msrv) -> Self {
- Self {
- msrv,
- ..Dereferencing::default()
- }
- }
}
#[derive(Debug)]
@@ -356,52 +320,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
));
},
(Some(use_cx), RefOp::AddrOf(mutability)) => {
- let defined_ty = use_cx.node.defined_ty(cx);
-
- // Check needless_borrow for generic arguments.
- if !use_cx.is_ty_unified
- && let Some(DefinedTy::Mir(ty)) = defined_ty
- && let ty::Param(ty) = *ty.value.skip_binder().kind()
- && let Some((hir_id, fn_id, i)) = match use_cx.node {
- ExprUseNode::MethodArg(_, _, 0) => None,
- ExprUseNode::MethodArg(hir_id, None, i) => {
- typeck.type_dependent_def_id(hir_id).map(|id| (hir_id, id, i))
- },
- ExprUseNode::FnArg(&Expr { kind: ExprKind::Path(ref p), hir_id, .. }, i)
- if !path_has_args(p) => match typeck.qpath_res(p, hir_id) {
- Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => {
- Some((hir_id, id, i))
- },
- _ => None,
- },
- _ => None,
- } && let count = needless_borrow_generic_arg_count(
- cx,
- &mut self.possible_borrowers,
- fn_id,
- typeck.node_args(hir_id),
- i,
- ty,
- expr,
- &self.msrv,
- ) && count != 0
- {
- self.state = Some((
- State::DerefedBorrow(DerefedBorrow {
- count: count - 1,
- msg: "the borrowed expression implements the required traits",
- stability: TyCoercionStability::None,
- for_field_access: None,
- }),
- StateData {
- span: expr.span,
- hir_id: expr.hir_id,
- adjusted_ty: use_cx.adjustments.last().map_or(expr_ty, |a| a.target),
- },
- ));
- return;
- }
-
// Find the number of times the borrow is auto-derefed.
let mut iter = use_cx.adjustments.iter();
let mut deref_count = 0usize;
@@ -420,7 +338,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
};
};
- let stability = defined_ty.map_or(TyCoercionStability::None, |ty| {
+ let stability = use_cx.node.defined_ty(cx).map_or(TyCoercionStability::None, |ty| {
TyCoercionStability::for_defined_ty(cx, ty, use_cx.node.is_return())
});
let can_auto_borrow = match use_cx.node {
@@ -452,13 +370,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
// Trait methods taking `self`
arg_ty
} && impl_ty.is_ref()
- && cx.tcx.infer_ctxt().build()
- .type_implements_trait(
- trait_id,
- [impl_ty.into()].into_iter().chain(args.iter().copied()),
- cx.param_env,
- )
- .must_apply_modulo_regions()
+ && implements_trait(
+ cx,
+ impl_ty,
+ trait_id,
+ &args[..cx.tcx.generics_of(trait_id).params.len() - 1],
+ )
{
false
} else {
@@ -609,12 +526,14 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
adjusted_ty,
},
));
- } else if stability.is_deref_stable() {
+ } else if stability.is_deref_stable()
+ && let Some(parent) = get_parent_expr(cx, expr)
+ {
self.state = Some((
State::ExplicitDeref { mutability: None },
StateData {
- span: expr.span,
- hir_id: expr.hir_id,
+ span: parent.span,
+ hir_id: parent.hir_id,
adjusted_ty,
},
));
@@ -700,12 +619,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
}
fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
- if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
- local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
- }) {
- self.possible_borrowers.pop();
- }
-
if Some(body.id()) == self.current_body {
for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {
let replacements = pat.replacements;
@@ -729,8 +642,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
self.current_body = None;
}
}
-
- extract_msrv_attr!(LateContext);
}
fn try_parse_ref_op<'tcx>(
@@ -788,13 +699,6 @@ fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
}
}
-fn path_has_args(p: &QPath<'_>) -> bool {
- match *p {
- QPath::Resolved(_, Path { segments: [.., s], .. }) | QPath::TypeRelative(_, s) => s.args.is_some(),
- _ => false,
- }
-}
-
fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
if let Some(parent) = get_parent_expr(cx, e)
&& parent.span.ctxt() == e.span.ctxt()
@@ -940,7 +844,6 @@ impl TyCoercionStability {
| ty::FnDef(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
- | ty::GeneratorWitnessMIR(..)
| ty::Closure(..)
| ty::Never
| ty::Tuple(_)
@@ -981,274 +884,6 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
v.0
}
-/// Checks for the number of borrow expressions which can be removed from the given expression
-/// where the expression is used as an argument to a function expecting a generic type.
-///
-/// The following constraints will be checked:
-/// * The borrowed expression meets all the generic type's constraints.
-/// * The generic type appears only once in the functions signature.
-/// * The borrowed value will not be moved if it is used later in the function.
-#[expect(clippy::too_many_arguments)]
-fn needless_borrow_generic_arg_count<'tcx>(
- cx: &LateContext<'tcx>,
- possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
- fn_id: DefId,
- callee_args: &'tcx List<GenericArg<'tcx>>,
- arg_index: usize,
- param_ty: ParamTy,
- mut expr: &Expr<'tcx>,
- msrv: &Msrv,
-) -> usize {
- let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
- let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
-
- let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
- let predicates = cx.tcx.param_env(fn_id).caller_bounds();
- let projection_predicates = predicates
- .iter()
- .filter_map(|predicate| {
- if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
- Some(projection_predicate)
- } else {
- None
- }
- })
- .collect::<Vec<_>>();
-
- let mut trait_with_ref_mut_self_method = false;
-
- // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.
- if predicates
- .iter()
- .filter_map(|predicate| {
- if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
- && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
- {
- Some(trait_predicate.trait_ref.def_id)
- } else {
- None
- }
- })
- .inspect(|trait_def_id| {
- trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);
- })
- .all(|trait_def_id| {
- Some(trait_def_id) == destruct_trait_def_id
- || Some(trait_def_id) == sized_trait_def_id
- || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
- })
- {
- return 0;
- }
-
- // See:
- // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
- // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
- if projection_predicates
- .iter()
- .any(|projection_predicate| is_mixed_projection_predicate(cx, fn_id, projection_predicate))
- {
- return 0;
- }
-
- // `args_with_referent_ty` can be constructed outside of `check_referent` because the same
- // elements are modified each time `check_referent` is called.
- let mut args_with_referent_ty = callee_args.to_vec();
-
- let mut check_reference_and_referent = |reference, referent| {
- let referent_ty = cx.typeck_results().expr_ty(referent);
-
- if !is_copy(cx, referent_ty)
- && (referent_ty.has_significant_drop(cx.tcx, cx.param_env)
- || !referent_used_exactly_once(cx, possible_borrowers, reference))
- {
- return false;
- }
-
- // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
- if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
- return false;
- }
-
- if !replace_types(
- cx,
- param_ty,
- referent_ty,
- fn_sig,
- arg_index,
- &projection_predicates,
- &mut args_with_referent_ty,
- ) {
- return false;
- }
-
- predicates.iter().all(|predicate| {
- if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
- && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
- && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
- && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack()
- && ty.is_array()
- && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
- {
- return false;
- }
-
- let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
- let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
- let infcx = cx.tcx.infer_ctxt().build();
- infcx.predicate_must_hold_modulo_regions(&obligation)
- })
- };
-
- let mut count = 0;
- while let ExprKind::AddrOf(_, _, referent) = expr.kind {
- if !check_reference_and_referent(expr, referent) {
- break;
- }
- expr = referent;
- count += 1;
- }
- count
-}
-
-fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
- cx.tcx
- .associated_items(trait_def_id)
- .in_definition_order()
- .any(|assoc_item| {
- if assoc_item.fn_has_self_parameter {
- let self_ty = cx
- .tcx
- .fn_sig(assoc_item.def_id)
- .instantiate_identity()
- .skip_binder()
- .inputs()[0];
- matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
- } else {
- false
- }
- })
-}
-
-fn is_mixed_projection_predicate<'tcx>(
- cx: &LateContext<'tcx>,
- callee_def_id: DefId,
- projection_predicate: &ProjectionPredicate<'tcx>,
-) -> bool {
- let generics = cx.tcx.generics_of(callee_def_id);
- // The predicate requires the projected type to equal a type parameter from the parent context.
- if let Some(term_ty) = projection_predicate.term.ty()
- && let ty::Param(term_param_ty) = term_ty.kind()
- && (term_param_ty.index as usize) < generics.parent_count
- {
- // The inner-most self type is a type parameter from the current function.
- let mut projection_ty = projection_predicate.projection_ty;
- loop {
- match projection_ty.self_ty().kind() {
- ty::Alias(ty::Projection, inner_projection_ty) => {
- projection_ty = *inner_projection_ty;
- }
- ty::Param(param_ty) => {
- return (param_ty.index as usize) >= generics.parent_count;
- }
- _ => {
- return false;
- }
- }
- }
- } else {
- false
- }
-}
-
-fn referent_used_exactly_once<'tcx>(
- cx: &LateContext<'tcx>,
- possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
- reference: &Expr<'tcx>,
-) -> bool {
- if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)
- && let Some(local) = expr_local(cx.tcx, reference)
- && let [location] = *local_assignments(mir, local).as_slice()
- && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
- && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
- && !place.is_indirect_first_projection()
- // Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
- && TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
- {
- let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
- if possible_borrowers
- .last()
- .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id)
- {
- possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));
- }
- let possible_borrower = &mut possible_borrowers.last_mut().unwrap().1;
- // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
- // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
- // itself. See the comment in that method for an explanation as to why.
- possible_borrower.bounded_borrowers(&[local], &[local, place.local], place.local, location)
- && used_exactly_once(mir, place.local).unwrap_or(false)
- } else {
- false
- }
-}
-
-// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
-// projected type that is a type parameter. Returns `false` if replacing the types would have an
-// effect on the function signature beyond substituting `new_ty` for `param_ty`.
-// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
-fn replace_types<'tcx>(
- cx: &LateContext<'tcx>,
- param_ty: ParamTy,
- new_ty: Ty<'tcx>,
- fn_sig: FnSig<'tcx>,
- arg_index: usize,
- projection_predicates: &[ProjectionPredicate<'tcx>],
- args: &mut [ty::GenericArg<'tcx>],
-) -> bool {
- let mut replaced = BitSet::new_empty(args.len());
-
- let mut deque = VecDeque::with_capacity(args.len());
- deque.push_back((param_ty, new_ty));
-
- while let Some((param_ty, new_ty)) = deque.pop_front() {
- // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
- if !fn_sig
- .inputs_and_output
- .iter()
- .enumerate()
- .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))
- {
- return false;
- }
-
- args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
-
- // The `replaced.insert(...)` check provides some protection against infinite loops.
- if replaced.insert(param_ty.index) {
- for projection_predicate in projection_predicates {
- if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
- && let Some(term_ty) = projection_predicate.term.ty()
- && let ty::Param(term_param_ty) = term_ty.kind()
- {
- let projection = cx.tcx.mk_ty_from_kind(ty::Alias(
- ty::Projection,
- projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty),
- ));
-
- if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
- && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
- {
- deque.push_back((*term_param_ty, projected_ty));
- }
- }
- }
- }
- }
-
- true
-}
-
fn ty_contains_field(ty: Ty<'_>, name: Symbol) -> bool {
if let ty::Adt(adt, _) = *ty.kind() {
adt.is_struct() && adt.all_fields().any(|f| f.name == name)
@@ -1399,6 +1034,13 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, state: State, data
return;
}
+ if let ExprKind::Field(parent_expr, _) = expr.kind
+ && let ty::Adt(adt, _) = cx.typeck_results().expr_ty(parent_expr).kind()
+ && adt.is_union()
+ {
+ // Auto deref does not apply on union field
+ return;
+ }
span_lint_hir_and_then(
cx,
EXPLICIT_AUTO_DEREF,
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 9a85cc4ce..d2bfc4f8e 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -217,8 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
if let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind();
if let attrs = cx.tcx.hir().attrs(item.hir_id());
if !attrs.iter().any(|attr| attr.doc_str().is_some());
- if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
- if !child_attrs.iter().any(|attr| attr.doc_str().is_some());
+ if cx.tcx.hir().attrs(impl_item_hir).is_empty();
then {
if adt_def.is_struct() {
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index d3311792c..2bdac1352 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -343,7 +343,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
// If the current self type doesn't implement Copy (due to generic constraints), search to see if
// there's a Copy impl for any instance of the adt.
if !is_copy(cx, ty) {
- if ty_subs.non_erasable_generics().next().is_some() {
+ if ty_subs.non_erasable_generics(cx.tcx, ty_adt.did()).next().is_some() {
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
impls.iter().any(|&id| {
matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index 1971cab64..7469f813e 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -1,8 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::macro_backtrace;
+use rustc_ast::Attribute;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::DefIdMap;
-use rustc_hir::{Expr, ForeignItem, HirId, ImplItem, Item, Pat, Path, Stmt, TraitItem, Ty};
+use rustc_hir::{Expr, ExprKind, ForeignItem, HirId, ImplItem, Item, Pat, Path, Stmt, TraitItem, Ty};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{ExpnId, Span};
@@ -111,6 +112,10 @@ impl LateLintPass<'_> for DisallowedMacros {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
self.check(cx, expr.span);
+ // `$t + $t` can have the context of $t, check also the span of the binary operator
+ if let ExprKind::Binary(op, ..) = expr.kind {
+ self.check(cx, op.span);
+ }
}
fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {
@@ -147,4 +152,8 @@ impl LateLintPass<'_> for DisallowedMacros {
fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, _: HirId) {
self.check(cx, path.span);
}
+
+ fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &Attribute) {
+ self.check(cx, attr.span);
+ }
}
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index e29ab634c..e789e0da6 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -1,18 +1,16 @@
use clippy_utils::attrs::is_doc_hidden;
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_then};
use clippy_utils::macros::{is_panic, root_macro_call_first_node};
-use clippy_utils::source::{first_line_of_span, snippet_with_applicability};
+use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
use clippy_utils::{is_entrypoint_fn, method_chain_args, return_ty};
use if_chain::if_chain;
-use itertools::Itertools;
use pulldown_cmark::Event::{
Code, End, FootnoteReference, HardBreak, Html, Rule, SoftBreak, Start, TaskListMarker, Text,
};
use pulldown_cmark::Tag::{CodeBlock, Heading, Item, Link, Paragraph};
use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options};
-use rustc_ast::ast::{Async, AttrKind, Attribute, Fn, FnRetTy, ItemKind};
-use rustc_ast::token::CommentKind;
+use rustc_ast::ast::{Async, Attribute, Fn, FnRetTy, ItemKind};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::EmitterWriter;
@@ -26,6 +24,9 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_parse::parser::ForceCollect;
+use rustc_resolve::rustdoc::{
+ add_doc_fragment, attrs_to_doc_fragments, main_body_opts, source_span_for_markdown_range, DocFragment,
+};
use rustc_session::parse::ParseSess;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::edition::Edition;
@@ -450,53 +451,16 @@ fn lint_for_missing_headers(
}
}
-/// Cleanup documentation decoration.
-///
-/// We can't use `rustc_ast::attr::AttributeMethods::with_desugared_doc` or
-/// `rustc_ast::parse::lexer::comments::strip_doc_comment_decoration` because we
-/// need to keep track of
-/// the spans but this function is inspired from the later.
-#[expect(clippy::cast_possible_truncation)]
-#[must_use]
-pub fn strip_doc_comment_decoration(doc: &str, comment_kind: CommentKind, span: Span) -> (String, Vec<(usize, Span)>) {
- // one-line comments lose their prefix
- if comment_kind == CommentKind::Line {
- let mut doc = doc.to_owned();
- doc.push('\n');
- let len = doc.len();
- // +3 skips the opening delimiter
- return (doc, vec![(len, span.with_lo(span.lo() + BytePos(3)))]);
- }
+#[derive(Copy, Clone)]
+struct Fragments<'a> {
+ doc: &'a str,
+ fragments: &'a [DocFragment],
+}
- let mut sizes = vec![];
- let mut contains_initial_stars = false;
- for line in doc.lines() {
- let offset = line.as_ptr() as usize - doc.as_ptr() as usize;
- debug_assert_eq!(offset as u32 as usize, offset);
- contains_initial_stars |= line.trim_start().starts_with('*');
- // +1 adds the newline, +3 skips the opening delimiter
- sizes.push((line.len() + 1, span.with_lo(span.lo() + BytePos(3 + offset as u32))));
- }
- if !contains_initial_stars {
- return (doc.to_string(), sizes);
- }
- // remove the initial '*'s if any
- let mut no_stars = String::with_capacity(doc.len());
- for line in doc.lines() {
- let mut chars = line.chars();
- for c in &mut chars {
- if c.is_whitespace() {
- no_stars.push(c);
- } else {
- no_stars.push(if c == '*' { ' ' } else { c });
- break;
- }
- }
- no_stars.push_str(chars.as_str());
- no_stars.push('\n');
+impl Fragments<'_> {
+ fn span(self, cx: &LateContext<'_>, range: Range<usize>) -> Option<Span> {
+ source_span_for_markdown_range(cx.tcx, self.doc, &range, self.fragments)
}
-
- (no_stars, sizes)
}
#[derive(Copy, Clone, Default)]
@@ -508,34 +472,23 @@ struct DocHeaders {
fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[Attribute]) -> Option<DocHeaders> {
/// We don't want the parser to choke on intra doc links. Since we don't
- /// actually care about rendering them, just pretend that all broken links are
+ /// actually care about rendering them, just pretend that all broken links
/// point to a fake address.
#[expect(clippy::unnecessary_wraps)] // we're following a type signature
fn fake_broken_link_callback<'a>(_: BrokenLink<'_>) -> Option<(CowStr<'a>, CowStr<'a>)> {
Some(("fake".into(), "fake".into()))
}
- let mut doc = String::new();
- let mut spans = vec![];
-
- for attr in attrs {
- if let AttrKind::DocComment(comment_kind, comment) = attr.kind {
- let (comment, current_spans) = strip_doc_comment_decoration(comment.as_str(), comment_kind, attr.span);
- spans.extend_from_slice(&current_spans);
- doc.push_str(&comment);
- } else if attr.has_name(sym::doc) {
- // ignore mix of sugared and non-sugared doc
- // don't trigger the safety or errors check
- return None;
- }
+ if is_doc_hidden(attrs) {
+ return None;
}
- let mut current = 0;
- for &mut (ref mut offset, _) in &mut spans {
- let offset_copy = *offset;
- *offset = current;
- current += offset_copy;
+ let (fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
+ let mut doc = String::new();
+ for fragment in &fragments {
+ add_doc_fragment(&mut doc, fragment);
}
+ doc.pop();
if doc.is_empty() {
return Some(DocHeaders::default());
@@ -543,32 +496,29 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
let mut cb = fake_broken_link_callback;
- let parser =
- pulldown_cmark::Parser::new_with_broken_link_callback(&doc, Options::empty(), Some(&mut cb)).into_offset_iter();
- // Iterate over all `Events` and combine consecutive events into one
- let events = parser.coalesce(|previous, current| {
- let previous_range = previous.1;
- let current_range = current.1;
-
- match (previous.0, current.0) {
- (Text(previous), Text(current)) => {
- let mut previous = previous.to_string();
- previous.push_str(&current);
- Ok((Text(previous.into()), previous_range))
- },
- (previous, current) => Err(((previous, previous_range), (current, current_range))),
- }
- });
- Some(check_doc(cx, valid_idents, events, &spans))
+ // disable smart punctuation to pick up ['link'] more easily
+ let opts = main_body_opts() - Options::ENABLE_SMART_PUNCTUATION;
+ let parser = pulldown_cmark::Parser::new_with_broken_link_callback(&doc, opts, Some(&mut cb));
+
+ Some(check_doc(
+ cx,
+ valid_idents,
+ parser.into_offset_iter(),
+ Fragments {
+ fragments: &fragments,
+ doc: &doc,
+ },
+ ))
}
const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail"];
+#[allow(clippy::too_many_lines)] // Only a big match statement
fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(
cx: &LateContext<'_>,
valid_idents: &FxHashSet<String>,
events: Events,
- spans: &[(usize, Span)],
+ fragments: Fragments<'_>,
) -> DocHeaders {
// true if a safety header was found
let mut headers = DocHeaders::default();
@@ -579,8 +529,8 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
let mut no_test = false;
let mut edition = None;
let mut ticks_unbalanced = false;
- let mut text_to_check: Vec<(CowStr<'_>, Span)> = Vec::new();
- let mut paragraph_span = spans.get(0).expect("function isn't called if doc comment is empty").1;
+ let mut text_to_check: Vec<(CowStr<'_>, Range<usize>)> = Vec::new();
+ let mut paragraph_range = 0..0;
for (event, range) in events {
match event {
Start(CodeBlock(ref kind)) => {
@@ -613,25 +563,28 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
in_heading = true;
}
ticks_unbalanced = false;
- let (_, span) = get_current_span(spans, range.start);
- paragraph_span = first_line_of_span(cx, span);
+ paragraph_range = range;
},
End(Heading(_, _, _) | Paragraph | Item) => {
if let End(Heading(_, _, _)) = event {
in_heading = false;
}
- if ticks_unbalanced {
+ if ticks_unbalanced
+ && let Some(span) = fragments.span(cx, paragraph_range.clone())
+ {
span_lint_and_help(
cx,
DOC_MARKDOWN,
- paragraph_span,
+ span,
"backticks are unbalanced",
None,
"a backtick may be missing a pair",
);
} else {
- for (text, span) in text_to_check {
- check_text(cx, valid_idents, &text, span);
+ for (text, range) in text_to_check {
+ if let Some(span) = fragments.span(cx, range) {
+ check_text(cx, valid_idents, &text, span);
+ }
}
}
text_to_check = Vec::new();
@@ -640,8 +593,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
Html(_html) => (), // HTML is weird, just ignore it
SoftBreak | HardBreak | TaskListMarker(_) | Code(_) | Rule => (),
FootnoteReference(text) | Text(text) => {
- let (begin, span) = get_current_span(spans, range.start);
- paragraph_span = paragraph_span.with_hi(span.hi());
+ paragraph_range.end = range.end;
ticks_unbalanced |= text.contains('`') && !in_code;
if Some(&text) == in_link.as_ref() || ticks_unbalanced {
// Probably a link of the form `<http://example.com>`
@@ -658,19 +610,19 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
if in_code {
if is_rust && !no_test {
let edition = edition.unwrap_or_else(|| cx.tcx.sess.edition());
- check_code(cx, &text, edition, span);
+ check_code(cx, &text, edition, range.clone(), fragments);
}
} else {
- check_link_quotes(cx, in_link.is_some(), trimmed_text, span, &range, begin, text.len());
- // Adjust for the beginning of the current `Event`
- let span = span.with_lo(span.lo() + BytePos::from_usize(range.start - begin));
+ if in_link.is_some() {
+ check_link_quotes(cx, trimmed_text, range.clone(), fragments);
+ }
if let Some(link) = in_link.as_ref()
&& let Ok(url) = Url::parse(link)
&& (url.scheme() == "https" || url.scheme() == "http") {
// Don't check the text associated with external URLs
continue;
}
- text_to_check.push((text, span));
+ text_to_check.push((text, range));
}
},
}
@@ -678,36 +630,21 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
headers
}
-fn check_link_quotes(
- cx: &LateContext<'_>,
- in_link: bool,
- trimmed_text: &str,
- span: Span,
- range: &Range<usize>,
- begin: usize,
- text_len: usize,
-) {
- if in_link && trimmed_text.starts_with('\'') && trimmed_text.ends_with('\'') {
- // fix the span to only point at the text within the link
- let lo = span.lo() + BytePos::from_usize(range.start - begin);
+fn check_link_quotes(cx: &LateContext<'_>, trimmed_text: &str, range: Range<usize>, fragments: Fragments<'_>) {
+ if trimmed_text.starts_with('\'')
+ && trimmed_text.ends_with('\'')
+ && let Some(span) = fragments.span(cx, range)
+ {
span_lint(
cx,
DOC_LINK_WITH_QUOTES,
- span.with_lo(lo).with_hi(lo + BytePos::from_usize(text_len)),
+ span,
"possible intra-doc link using quotes instead of backticks",
);
}
}
-fn get_current_span(spans: &[(usize, Span)], idx: usize) -> (usize, Span) {
- let index = match spans.binary_search_by(|c| c.0.cmp(&idx)) {
- Ok(o) => o,
- Err(e) => e - 1,
- };
- spans[index]
-}
-
-fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
+fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, range: Range<usize>, fragments: Fragments<'_>) {
fn has_needless_main(code: String, edition: Edition) -> bool {
rustc_driver::catch_fatal_errors(|| {
rustc_span::create_session_globals_then(edition, || {
@@ -774,12 +711,13 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
.unwrap_or_default()
}
+ let trailing_whitespace = text.len() - text.trim_end().len();
+
// Because of the global session, we need to create a new session in a different thread with
// the edition we need.
let text = text.to_owned();
- if thread::spawn(move || has_needless_main(text, edition))
- .join()
- .expect("thread::spawn failed")
+ if thread::spawn(move || has_needless_main(text, edition)).join().expect("thread::spawn failed")
+ && let Some(span) = fragments.span(cx, range.start..range.end - trailing_whitespace)
{
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
}
diff --git a/src/tools/clippy/clippy_lints/src/endian_bytes.rs b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
index dda14b4df..affd08221 100644
--- a/src/tools/clippy/clippy_lints/src/endian_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
@@ -21,7 +21,7 @@ declare_clippy_lint! {
/// let _x = 2i32.to_ne_bytes();
/// let _y = 2i64.to_ne_bytes();
/// ```
- #[clippy::version = "1.71.0"]
+ #[clippy::version = "1.72.0"]
pub HOST_ENDIAN_BYTES,
restriction,
"disallows usage of the `to_ne_bytes` method"
@@ -40,7 +40,7 @@ declare_clippy_lint! {
/// let _x = 2i32.to_le_bytes();
/// let _y = 2i64.to_le_bytes();
/// ```
- #[clippy::version = "1.71.0"]
+ #[clippy::version = "1.72.0"]
pub LITTLE_ENDIAN_BYTES,
restriction,
"disallows usage of the `to_le_bytes` method"
@@ -59,7 +59,7 @@ declare_clippy_lint! {
/// let _x = 2i32.to_be_bytes();
/// let _y = 2i64.to_be_bytes();
/// ```
- #[clippy::version = "1.71.0"]
+ #[clippy::version = "1.72.0"]
pub BIG_ENDIAN_BYTES,
restriction,
"disallows usage of the `to_be_bytes` method"
diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs
index 96c5c7fc5..3f60e5a7c 100644
--- a/src/tools/clippy/clippy_lints/src/enum_clike.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs
@@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
.tcx
.const_eval_poly(def_id.to_def_id())
.ok()
- .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty));
+ .map(|val| rustc_middle::mir::Const::from_value(val, ty));
if let Some(Constant::Int(val)) = constant.and_then(|c| miri_to_const(cx, c)) {
if let ty::Adt(adt, _) = ty.kind() {
if adt.is_enum() {
diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs
index d4df6f7aa..e332f681b 100644
--- a/src/tools/clippy/clippy_lints/src/enum_variants.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs
@@ -167,7 +167,10 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n
return;
}
- let first = &def.variants[0].ident.name.as_str();
+ let first = match def.variants.first() {
+ Some(variant) => variant.ident.name.as_str(),
+ None => return,
+ };
let mut pre = camel_case_split(first);
let mut post = pre.clone();
post.reverse();
diff --git a/src/tools/clippy/clippy_lints/src/error_impl_error.rs b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
index 379af9b22..f24577c73 100644
--- a/src/tools/clippy/clippy_lints/src/error_impl_error.rs
+++ b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
@@ -3,7 +3,6 @@ use clippy_utils::path_res;
use clippy_utils::ty::implements_trait;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Visibility;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -42,9 +41,10 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
};
match item.kind {
- ItemKind::TyAlias(ty, _) if implements_trait(cx, hir_ty_to_ty(cx.tcx, ty), error_def_id, &[])
- && item.ident.name == sym::Error
- && is_visible_outside_module(cx, item.owner_id.def_id) =>
+ ItemKind::TyAlias(..) if item.ident.name == sym::Error
+ && is_visible_outside_module(cx, item.owner_id.def_id)
+ && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
+ && implements_trait(cx, ty, error_def_id, &[]) =>
{
span_lint(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
index 8911f1872..83480fc5e 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
@@ -56,7 +56,7 @@ declare_clippy_lint! {
/// // lib.rs
/// pub mod a;
/// ```
- #[clippy::version = "1.70.0"]
+ #[clippy::version = "1.72.0"]
pub EXCESSIVE_NESTING,
complexity,
"checks for blocks nested beyond a certain threshold"
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 4b9ca8c91..b612cc00b 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -57,54 +57,52 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
} else {
None
}
+ && let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root())
{
- find_format_args(cx, write_arg, ExpnId::root(), |format_args| {
- let calling_macro =
- // ordering is important here, since `writeln!` uses `write!` internally
- if is_expn_of(write_call.span, "writeln").is_some() {
- Some("writeln")
- } else if is_expn_of(write_call.span, "write").is_some() {
- Some("write")
- } else {
- None
- };
- let prefix = if dest_name == "stderr" {
- "e"
- } else {
- ""
- };
+ // ordering is important here, since `writeln!` uses `write!` internally
+ let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() {
+ Some("writeln")
+ } else if is_expn_of(write_call.span, "write").is_some() {
+ Some("write")
+ } else {
+ None
+ };
+ let prefix = if dest_name == "stderr" {
+ "e"
+ } else {
+ ""
+ };
- // We need to remove the last trailing newline from the string because the
- // underlying `fmt::write` function doesn't know whether `println!` or `print!` was
- // used.
- let (used, sugg_mac) = if let Some(macro_name) = calling_macro {
- (
- format!("{macro_name}!({dest_name}(), ...)"),
- macro_name.replace("write", "print"),
- )
- } else {
- (
- format!("{dest_name}().write_fmt(...)"),
- "print".into(),
- )
- };
- let mut applicability = Applicability::MachineApplicable;
- let inputs_snippet = snippet_with_applicability(
- cx,
- format_args_inputs_span(format_args),
- "..",
- &mut applicability,
- );
- span_lint_and_sugg(
- cx,
- EXPLICIT_WRITE,
- expr.span,
- &format!("use of `{used}.unwrap()`"),
- "try",
- format!("{prefix}{sugg_mac}!({inputs_snippet})"),
- applicability,
- );
- });
+ // We need to remove the last trailing newline from the string because the
+ // underlying `fmt::write` function doesn't know whether `println!` or `print!` was
+ // used.
+ let (used, sugg_mac) = if let Some(macro_name) = calling_macro {
+ (
+ format!("{macro_name}!({dest_name}(), ...)"),
+ macro_name.replace("write", "print"),
+ )
+ } else {
+ (
+ format!("{dest_name}().write_fmt(...)"),
+ "print".into(),
+ )
+ };
+ let mut applicability = Applicability::MachineApplicable;
+ let inputs_snippet = snippet_with_applicability(
+ cx,
+ format_args_inputs_span(&format_args),
+ "..",
+ &mut applicability,
+ );
+ span_lint_and_sugg(
+ cx,
+ EXPLICIT_WRITE,
+ expr.span,
+ &format!("use of `{used}.unwrap()`"),
+ "try",
+ format!("{prefix}{sugg_mac}!({inputs_snippet})"),
+ applicability,
+ );
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index c18006a71..0a885984a 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -246,8 +246,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for TypeWalker<'cx, 'tcx> {
{
self.ty_params.remove(&def_id);
}
+ } else {
+ // If the bounded type isn't a generic param, but is instead a concrete generic
+ // type, any params we find nested inside of it are being used as concrete types,
+ // and can therefore can be considered used. So, we're fine to walk the left-hand
+ // side of the where bound.
+ walk_ty(self, predicate.bounded_ty);
}
- // Only walk the right-hand side of where bounds
for bound in predicate.bounds {
walk_param_bound(self, bound);
}
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index f4f8bdc2c..b748d3293 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -43,14 +43,10 @@ declare_lint_pass!(UselessFormat => [USELESS_FORMAT]);
impl<'tcx> LateLintPass<'tcx> for UselessFormat {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
- return;
- };
- if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
- return;
- }
-
- find_format_args(cx, expr, macro_call.expn, |format_args| {
+ if let Some(macro_call) = root_macro_call_first_node(cx, expr)
+ && cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
+ && let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
+ {
let mut applicability = Applicability::MachineApplicable;
let call_site = macro_call.span;
@@ -91,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
},
_ => {},
}
- });
+ }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 01c714c41..39abf5c2d 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -186,15 +186,10 @@ impl FormatArgs {
impl<'tcx> LateLintPass<'tcx> for FormatArgs {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
- return;
- };
- if !is_format_macro(cx, macro_call.def_id) {
- return;
- }
- let name = cx.tcx.item_name(macro_call.def_id);
-
- find_format_args(cx, expr, macro_call.expn, |format_args| {
+ if let Some(macro_call) = root_macro_call_first_node(cx, expr)
+ && is_format_macro(cx, macro_call.def_id)
+ && let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
+ {
for piece in &format_args.template {
if let FormatArgsPiece::Placeholder(placeholder) = piece
&& let Ok(index) = placeholder.argument.index
@@ -206,12 +201,13 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
if placeholder.format_trait != FormatTrait::Display
|| placeholder.format_options != FormatOptions::default()
- || is_aliased(format_args, index)
+ || is_aliased(&format_args, index)
{
continue;
}
if let Ok(arg_hir_expr) = arg_expr {
+ let name = cx.tcx.item_name(macro_call.def_id);
check_format_in_format_args(cx, macro_call.span, name, arg_hir_expr);
check_to_string_in_format_args(cx, name, arg_hir_expr);
}
@@ -219,9 +215,9 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
}
if self.msrv.meets(msrvs::FORMAT_ARGS_CAPTURE) {
- check_uninlined_args(cx, format_args, macro_call.span, macro_call.def_id, self.ignore_mixed);
+ check_uninlined_args(cx, &format_args, macro_call.span, macro_call.def_id, self.ignore_mixed);
}
- });
+ }
}
extract_msrv_attr!(LateContext);
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index 76369bccf..1d2f7cb71 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -170,30 +170,29 @@ fn check_self_in_format_args<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>,
if let Some(outer_macro) = root_macro_call_first_node(cx, expr)
&& let macro_def_id = outer_macro.def_id
&& is_format_macro(cx, macro_def_id)
+ && let Some(format_args) = find_format_args(cx, expr, outer_macro.expn)
{
- find_format_args(cx, expr, outer_macro.expn, |format_args| {
- for piece in &format_args.template {
- if let FormatArgsPiece::Placeholder(placeholder) = piece
- && let trait_name = match placeholder.format_trait {
- FormatTrait::Display => sym::Display,
- FormatTrait::Debug => sym::Debug,
- FormatTrait::LowerExp => sym!(LowerExp),
- FormatTrait::UpperExp => sym!(UpperExp),
- FormatTrait::Octal => sym!(Octal),
- FormatTrait::Pointer => sym::Pointer,
- FormatTrait::Binary => sym!(Binary),
- FormatTrait::LowerHex => sym!(LowerHex),
- FormatTrait::UpperHex => sym!(UpperHex),
- }
- && trait_name == impl_trait.name
- && let Ok(index) = placeholder.argument.index
- && let Some(arg) = format_args.arguments.all_args().get(index)
- && let Ok(arg_expr) = find_format_arg_expr(expr, arg)
- {
- check_format_arg_self(cx, expr.span, arg_expr, impl_trait);
+ for piece in &format_args.template {
+ if let FormatArgsPiece::Placeholder(placeholder) = piece
+ && let trait_name = match placeholder.format_trait {
+ FormatTrait::Display => sym::Display,
+ FormatTrait::Debug => sym::Debug,
+ FormatTrait::LowerExp => sym!(LowerExp),
+ FormatTrait::UpperExp => sym!(UpperExp),
+ FormatTrait::Octal => sym!(Octal),
+ FormatTrait::Pointer => sym::Pointer,
+ FormatTrait::Binary => sym!(Binary),
+ FormatTrait::LowerHex => sym!(LowerHex),
+ FormatTrait::UpperHex => sym!(UpperHex),
}
+ && trait_name == impl_trait.name
+ && let Ok(index) = placeholder.argument.index
+ && let Some(arg) = format_args.arguments.all_args().get(index)
+ && let Ok(arg_expr) = find_format_arg_expr(expr, arg)
+ {
+ check_format_arg_self(cx, expr.span, arg_expr, impl_trait);
}
- });
+ }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index ab6ad3f3b..e2d19e245 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -6,7 +6,7 @@ use clippy_utils::sugg::Sugg;
use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks};
use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionNone, OptionSome};
-use rustc_hir::{Expr, ExprKind, Stmt, StmtKind};
+use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
&& then_expr.span.ctxt() == ctxt
&& is_res_lang_ctor(cx, path_res(cx, then_call), OptionSome)
&& is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
- && !stmts_contains_early_return(then_block.stmts)
+ && !contains_return(then_block.stmts)
{
let mut app = Applicability::Unspecified;
let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app).maybe_par().to_string();
@@ -116,17 +116,3 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
extract_msrv_attr!(LateContext);
}
-
-fn stmts_contains_early_return(stmts: &[Stmt<'_>]) -> bool {
- stmts.iter().any(|stmt| {
- let Stmt {
- kind: StmtKind::Semi(e),
- ..
- } = stmt
- else {
- return false;
- };
-
- contains_return(e)
- })
-}
diff --git a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
index c635120b8..d8ead1c9d 100644
--- a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use hir::PatKind;
+use hir::{Node, PatKind};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
@@ -37,6 +37,17 @@ declare_lint_pass!(IgnoredUnitPatterns => [IGNORED_UNIT_PATTERNS]);
impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns {
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx hir::Pat<'tcx>) {
+ match cx.tcx.hir().get_parent(pat.hir_id) {
+ Node::Param(param) if matches!(cx.tcx.hir().get_parent(param.hir_id), Node::Item(_)) => {
+ // Ignore function parameters
+ return;
+ },
+ Node::Local(local) if local.ty.is_some() => {
+ // Ignore let bindings with explicit type
+ return;
+ },
+ _ => {},
+ }
if matches!(pat.kind, PatKind::Wild) && cx.typeck_results().pat_ty(pat).is_unit() {
span_lint_and_sugg(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
new file mode 100644
index 000000000..ec9044bba
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -0,0 +1,318 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet;
+use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::intravisit::FnKind;
+use rustc_hir::{
+ Body, FnDecl, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, ItemKind, TraitBoundModifier, TraitItem,
+ TraitItemKind, TyKind,
+};
+use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::Span;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Looks for bounds in `impl Trait` in return position that are implied by other bounds.
+ /// This can happen when a trait is specified that another trait already has as a supertrait
+ /// (e.g. `fn() -> impl Deref + DerefMut<Target = i32>` has an unnecessary `Deref` bound,
+ /// because `Deref` is a supertrait of `DerefMut`)
+ ///
+ /// ### Why is this bad?
+ /// Specifying more bounds than necessary adds needless complexity for the reader.
+ ///
+ /// ### Limitations
+ /// This lint does not check for implied bounds transitively. Meaning that
+ /// it does't check for implied bounds from supertraits of supertraits
+ /// (e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`)
+ ///
+ /// ### Example
+ /// ```rust
+ /// # use std::ops::{Deref,DerefMut};
+ /// fn f() -> impl Deref<Target = i32> + DerefMut<Target = i32> {
+ /// // ^^^^^^^^^^^^^^^^^^^ unnecessary bound, already implied by the `DerefMut` trait bound
+ /// Box::new(123)
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # use std::ops::{Deref,DerefMut};
+ /// fn f() -> impl DerefMut<Target = i32> {
+ /// Box::new(123)
+ /// }
+ /// ```
+ #[clippy::version = "1.73.0"]
+ pub IMPLIED_BOUNDS_IN_IMPLS,
+ nursery,
+ "specifying bounds that are implied by other bounds in `impl Trait` type"
+}
+declare_lint_pass!(ImpliedBoundsInImpls => [IMPLIED_BOUNDS_IN_IMPLS]);
+
+#[allow(clippy::too_many_arguments)]
+fn emit_lint(
+ cx: &LateContext<'_>,
+ poly_trait: &rustc_hir::PolyTraitRef<'_>,
+ opaque_ty: &rustc_hir::OpaqueTy<'_>,
+ index: usize,
+ // The bindings that were implied
+ implied_bindings: &[rustc_hir::TypeBinding<'_>],
+ // The original bindings that `implied_bindings` are implied from
+ implied_by_bindings: &[rustc_hir::TypeBinding<'_>],
+ implied_by_args: &[GenericArg<'_>],
+ implied_by_span: Span,
+) {
+ let implied_by = snippet(cx, implied_by_span, "..");
+
+ span_lint_and_then(
+ cx,
+ IMPLIED_BOUNDS_IN_IMPLS,
+ poly_trait.span,
+ &format!("this bound is already specified as the supertrait of `{implied_by}`"),
+ |diag| {
+ // If we suggest removing a bound, we may also need to extend the span
+ // to include the `+` token that is ahead or behind,
+ // so we don't end up with something like `impl + B` or `impl A + `
+
+ let implied_span_extended = if let Some(next_bound) = opaque_ty.bounds.get(index + 1) {
+ poly_trait.span.to(next_bound.span().shrink_to_lo())
+ } else if index > 0
+ && let Some(prev_bound) = opaque_ty.bounds.get(index - 1)
+ {
+ prev_bound.span().shrink_to_hi().to(poly_trait.span.shrink_to_hi())
+ } else {
+ poly_trait.span
+ };
+
+ let mut sugg = vec![(implied_span_extended, String::new())];
+
+ // We also might need to include associated type binding that were specified in the implied bound,
+ // but omitted in the implied-by bound:
+ // `fn f() -> impl Deref<Target = u8> + DerefMut`
+ // If we're going to suggest removing `Deref<..>`, we'll need to put `<Target = u8>` on `DerefMut`
+ let omitted_assoc_tys: Vec<_> = implied_bindings
+ .iter()
+ .filter(|binding| !implied_by_bindings.iter().any(|b| b.ident == binding.ident))
+ .collect();
+
+ if !omitted_assoc_tys.is_empty() {
+ // `<>` needs to be added if there aren't yet any generic arguments or bindings
+ let needs_angle_brackets = implied_by_args.is_empty() && implied_by_bindings.is_empty();
+ let insert_span = match (implied_by_args, implied_by_bindings) {
+ ([.., arg], [.., binding]) => arg.span().max(binding.span).shrink_to_hi(),
+ ([.., arg], []) => arg.span().shrink_to_hi(),
+ ([], [.., binding]) => binding.span.shrink_to_hi(),
+ ([], []) => implied_by_span.shrink_to_hi(),
+ };
+
+ let mut associated_tys_sugg = if needs_angle_brackets {
+ "<".to_owned()
+ } else {
+ // If angle brackets aren't needed (i.e., there are already generic arguments or bindings),
+ // we need to add a comma:
+ // `impl A<B, C >`
+ // ^ if we insert `Assoc=i32` without a comma here, that'd be invalid syntax:
+ // `impl A<B, C Assoc=i32>`
+ ", ".to_owned()
+ };
+
+ for (index, binding) in omitted_assoc_tys.into_iter().enumerate() {
+ if index > 0 {
+ associated_tys_sugg += ", ";
+ }
+ associated_tys_sugg += &snippet(cx, binding.span, "..");
+ }
+ if needs_angle_brackets {
+ associated_tys_sugg += ">";
+ }
+ sugg.push((insert_span, associated_tys_sugg));
+ }
+
+ diag.multipart_suggestion_with_style(
+ "try removing this bound",
+ sugg,
+ Applicability::MachineApplicable,
+ SuggestionStyle::ShowAlways,
+ );
+ },
+ );
+}
+
+/// Tries to "resolve" a type.
+/// The index passed to this function must start with `Self=0`, i.e. it must be a valid
+/// type parameter index.
+/// If the index is out of bounds, it means that the generic parameter has a default type.
+fn try_resolve_type<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ args: &'tcx [GenericArg<'tcx>],
+ generics: &'tcx Generics,
+ index: usize,
+) -> Option<Ty<'tcx>> {
+ match args.get(index - 1) {
+ Some(GenericArg::Type(ty)) => Some(hir_ty_to_ty(tcx, ty)),
+ Some(_) => None,
+ None => Some(tcx.type_of(generics.params[index].def_id).skip_binder()),
+ }
+}
+
+/// This function tries to, for all generic type parameters in a supertrait predicate `trait ...<U>:
+/// GenericTrait<U>`, check if the substituted type in the implied-by bound matches with what's
+/// subtituted in the implied bound.
+///
+/// Consider this example.
+/// ```rust,ignore
+/// trait GenericTrait<T> {}
+/// trait GenericSubTrait<T, U, V>: GenericTrait<U> {}
+/// ^^^^^^^^^^^^^^^ trait_predicate_args: [Self#0, U#2]
+/// (the Self#0 is implicit: `<Self as GenericTrait<U>>`)
+/// impl GenericTrait<i32> for () {}
+/// impl GenericSubTrait<(), i32, ()> for () {}
+/// impl GenericSubTrait<(), i64, ()> for () {}
+///
+/// fn f() -> impl GenericTrait<i32> + GenericSubTrait<(), i64, ()> {
+/// ^^^ implied_args ^^^^^^^^^^^ implied_by_args
+/// (we are interested in `i64` specifically, as that
+/// is what `U` in `GenericTrait<U>` is substituted with)
+/// }
+/// ```
+/// Here i32 != i64, so this will return false.
+fn is_same_generics<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ trait_predicate_args: &'tcx [ty::GenericArg<'tcx>],
+ implied_by_args: &'tcx [GenericArg<'tcx>],
+ implied_args: &'tcx [GenericArg<'tcx>],
+ implied_by_def_id: DefId,
+ implied_def_id: DefId,
+) -> bool {
+ // Get the generics of the two traits to be able to get default generic parameter.
+ let implied_by_generics = tcx.generics_of(implied_by_def_id);
+ let implied_generics = tcx.generics_of(implied_def_id);
+
+ trait_predicate_args
+ .iter()
+ .enumerate()
+ .skip(1) // skip `Self` implicit arg
+ .all(|(arg_index, arg)| {
+ if let Some(ty) = arg.as_type() {
+ if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind()
+ // `index == 0` means that it's referring to `Self`,
+ // in which case we don't try to substitute it
+ && index != 0
+ && let Some(ty_a) = try_resolve_type(tcx, implied_by_args, implied_by_generics, index as usize)
+ && let Some(ty_b) = try_resolve_type(tcx, implied_args, implied_generics, arg_index)
+ {
+ ty_a == ty_b
+ } else if let Some(ty_b) = try_resolve_type(tcx, implied_args, implied_generics, arg_index) {
+ ty == ty_b
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ })
+}
+
+fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
+ if let FnRetTy::Return(ty) = decl.output
+ &&let TyKind::OpaqueDef(item_id, ..) = ty.kind
+ && let item = cx.tcx.hir().item(item_id)
+ && let ItemKind::OpaqueTy(opaque_ty) = item.kind
+ // Very often there is only a single bound, e.g. `impl Deref<..>`, in which case
+ // we can avoid doing a bunch of stuff unnecessarily.
+ && opaque_ty.bounds.len() > 1
+ {
+ // Get all the (implied) trait predicates in the bounds.
+ // For `impl Deref + DerefMut` this will contain [`Deref`].
+ // The implied `Deref` comes from `DerefMut` because `trait DerefMut: Deref {}`.
+ // N.B. (G)ATs are fine to disregard, because they must be the same for all of its supertraits.
+ // Example:
+ // `impl Deref<Target = i32> + DerefMut<Target = u32>` is not allowed.
+ // `DerefMut::Target` needs to match `Deref::Target`.
+ let implied_bounds: Vec<_> = opaque_ty.bounds.iter().filter_map(|bound| {
+ if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
+ && let [.., path] = poly_trait.trait_ref.path.segments
+ && poly_trait.bound_generic_params.is_empty()
+ && let Some(trait_def_id) = path.res.opt_def_id()
+ && let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates
+ && !predicates.is_empty() // If the trait has no supertrait, there is nothing to add.
+ {
+ Some((bound.span(), path, predicates, trait_def_id))
+ } else {
+ None
+ }
+ }).collect();
+
+ // Lint all bounds in the `impl Trait` type that are also in the `implied_bounds` vec.
+ // This involves some extra logic when generic arguments are present, since
+ // simply comparing trait `DefId`s won't be enough. We also need to compare the generics.
+ for (index, bound) in opaque_ty.bounds.iter().enumerate() {
+ if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
+ && let [.., path] = poly_trait.trait_ref.path.segments
+ && let implied_args = path.args.map_or([].as_slice(), |a| a.args)
+ && let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings)
+ && let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
+ && let Some((implied_by_span, implied_by_args, implied_by_bindings)) = implied_bounds
+ .iter()
+ .find_map(|&(span, implied_by_path, preds, implied_by_def_id)| {
+ let implied_by_args = implied_by_path.args.map_or([].as_slice(), |a| a.args);
+ let implied_by_bindings = implied_by_path.args.map_or([].as_slice(), |a| a.bindings);
+
+ preds.iter().find_map(|(clause, _)| {
+ if let ClauseKind::Trait(tr) = clause.kind().skip_binder()
+ && tr.def_id() == def_id
+ && is_same_generics(
+ cx.tcx,
+ tr.trait_ref.args,
+ implied_by_args,
+ implied_args,
+ implied_by_def_id,
+ def_id,
+ )
+ {
+ Some((span, implied_by_args, implied_by_bindings))
+ } else {
+ None
+ }
+ })
+ })
+ {
+ emit_lint(
+ cx,
+ poly_trait,
+ opaque_ty,
+ index,
+ implied_bindings,
+ implied_by_bindings,
+ implied_by_args,
+ implied_by_span
+ );
+ }
+ }
+ }
+}
+
+impl LateLintPass<'_> for ImpliedBoundsInImpls {
+ fn check_fn(
+ &mut self,
+ cx: &LateContext<'_>,
+ _: FnKind<'_>,
+ decl: &FnDecl<'_>,
+ _: &Body<'_>,
+ _: Span,
+ _: LocalDefId,
+ ) {
+ check(cx, decl);
+ }
+ fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {
+ if let TraitItemKind::Fn(sig, ..) = &item.kind {
+ check(cx, sig.decl);
+ }
+ }
+ fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &ImplItem<'_>) {
+ if let ImplItemKind::Fn(sig, ..) = &item.kind {
+ check(cx, sig.decl);
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
index b00fa104f..f95d2c2ed 100644
--- a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
+++ b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
@@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for NumberedFields {
&& fields
.iter()
.all(|f| f.ident.as_str().as_bytes().iter().all(u8::is_ascii_digit))
- && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias { .. }, ..))
+ && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias, ..))
{
let expr_spans = fields
.iter()
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index 9b26c3573..a4f3d4983 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, ConstKind};
@@ -50,12 +49,12 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if_chain! {
if !item.span.from_expansion();
- if let ItemKind::Const(hir_ty, generics, _) = &item.kind;
+ if let ItemKind::Const(_, generics, _) = &item.kind;
// Since static items may not have generics, skip generic const items.
// FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it
// doesn't account for empty where-clauses that only consist of keyword `where` IINM.
if generics.params.is_empty() && !generics.has_where_clause_predicates;
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
if let ty::Array(element_type, cst) = ty.kind();
if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind();
if let Ok(element_count) = element_count.try_to_target_usize(cx.tcx);
diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs
index d67d58993..19f1e08b5 100644
--- a/src/tools/clippy/clippy_lints/src/large_futures.rs
+++ b/src/tools/clippy/clippy_lints/src/large_futures.rs
@@ -17,26 +17,20 @@ declare_clippy_lint! {
///
/// ### Example
/// ```rust
- /// async fn wait(f: impl std::future::Future<Output = ()>) {}
+ /// async fn large_future(_x: [u8; 16 * 1024]) {}
///
- /// async fn big_fut(arg: [u8; 1024]) {}
- ///
- /// pub async fn test() {
- /// let fut = big_fut([0u8; 1024]);
- /// wait(fut).await;
+ /// pub async fn trigger() {
+ /// large_future([0u8; 16 * 1024]).await;
/// }
/// ```
///
/// `Box::pin` the big future instead.
///
/// ```rust
- /// async fn wait(f: impl std::future::Future<Output = ()>) {}
- ///
- /// async fn big_fut(arg: [u8; 1024]) {}
+ /// async fn large_future(_x: [u8; 16 * 1024]) {}
///
- /// pub async fn test() {
- /// let fut = Box::pin(big_fut([0u8; 1024]));
- /// wait(fut).await;
+ /// pub async fn trigger() {
+ /// Box::pin(large_future([0u8; 16 * 1024])).await;
/// }
/// ```
#[clippy::version = "1.70.0"]
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
index 7aa1446d5..1d28d7dd0 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
@@ -72,7 +72,7 @@ declare_clippy_lint! {
/// // ...
/// }
/// ```
- #[clippy::version = "1.71.0"]
+ #[clippy::version = "1.72.0"]
pub LARGE_STACK_FRAMES,
nursery,
"checks for functions that allocate a lot of stack space"
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index deba232bd..c06b35ca0 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -424,6 +424,14 @@ fn check_for_is_empty(
item_name: Symbol,
item_kind: &str,
) {
+ // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to
+ // find the correct inherent impls.
+ let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() {
+ adt.did()
+ } else {
+ return;
+ };
+
let is_empty = Symbol::intern("is_empty");
let is_empty = cx
.tcx
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 358004cf4..1271be2fd 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -21,6 +21,7 @@
// FIXME: switch to something more ergonomic here, once available.
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
+extern crate pulldown_cmark;
extern crate rustc_arena;
extern crate rustc_ast;
extern crate rustc_ast_pretty;
@@ -37,6 +38,7 @@ extern crate rustc_lexer;
extern crate rustc_lint;
extern crate rustc_middle;
extern crate rustc_parse;
+extern crate rustc_resolve;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;
@@ -152,8 +154,8 @@ mod implicit_hasher;
mod implicit_return;
mod implicit_saturating_add;
mod implicit_saturating_sub;
+mod implied_bounds_in_impls;
mod inconsistent_struct_constructor;
-mod incorrect_impls;
mod index_refutable_slice;
mod indexing_slicing;
mod infinite_iter;
@@ -209,6 +211,7 @@ mod misc;
mod misc_early;
mod mismatching_type_param_order;
mod missing_assert_message;
+mod missing_asserts_for_indexing;
mod missing_const_for_fn;
mod missing_doc;
mod missing_enforced_import_rename;
@@ -227,6 +230,7 @@ mod mutex_atomic;
mod needless_arbitrary_self_type;
mod needless_bool;
mod needless_borrowed_ref;
+mod needless_borrows_for_generic_args;
mod needless_continue;
mod needless_else;
mod needless_for_each;
@@ -242,6 +246,7 @@ mod neg_multiply;
mod new_without_default;
mod no_effect;
mod no_mangle_with_rust_abi;
+mod non_canonical_impls;
mod non_copy_const;
mod non_expressive_names;
mod non_octal_unix_permissions;
@@ -285,6 +290,7 @@ mod ref_option_ref;
mod ref_patterns;
mod reference;
mod regex;
+mod reserve_after_initialization;
mod return_self_not_must_use;
mod returns;
mod same_name_method;
@@ -326,6 +332,7 @@ mod unit_return_expecting_ord;
mod unit_types;
mod unnamed_address;
mod unnecessary_box_returns;
+mod unnecessary_map_on_constructor;
mod unnecessary_owned_empty_strings;
mod unnecessary_self_imports;
mod unnecessary_struct_initialization;
@@ -605,7 +612,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
.collect(),
))
});
- store.register_early_pass(|| Box::new(utils::format_args_collector::FormatArgsCollector));
+ store.register_early_pass(|| Box::<utils::format_args_collector::FormatArgsCollector>::default());
store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
store.register_late_pass(|_| Box::new(utils::author::Author));
let await_holding_invalid_types = conf.await_holding_invalid_types.clone();
@@ -632,7 +639,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
- store.register_late_pass(|_| Box::<misc::LintPass>::default());
+ store.register_late_pass(|_| Box::new(misc::LintPass));
store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
store.register_late_pass(|_| Box::new(mut_mut::MutMut));
store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
@@ -658,12 +665,19 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
let suppress_restriction_lint_in_const = conf.suppress_restriction_lint_in_const;
store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv())));
+ let allowed_dotfiles = conf
+ .allowed_dotfiles
+ .iter()
+ .cloned()
+ .chain(methods::DEFAULT_ALLOWED_DOTFILES.iter().copied().map(ToOwned::to_owned))
+ .collect::<FxHashSet<_>>();
store.register_late_pass(move |_| {
Box::new(methods::Methods::new(
avoid_breaking_exported_api,
msrv(),
allow_expect_in_tests,
allow_unwrap_in_tests,
+ allowed_dotfiles.clone(),
))
});
store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv())));
@@ -693,7 +707,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
store.register_late_pass(|_| Box::<shadow::Shadow>::default());
store.register_late_pass(|_| Box::new(unit_types::UnitTypes));
- store.register_late_pass(move |_| Box::new(loops::Loops::new(msrv())));
+ let enforce_iter_loop_reborrow = conf.enforce_iter_loop_reborrow;
+ store.register_late_pass(move |_| Box::new(loops::Loops::new(msrv(), enforce_iter_loop_reborrow)));
store.register_late_pass(|_| Box::<main_recursion::MainRecursion>::default());
store.register_late_pass(|_| Box::new(lifetimes::Lifetimes));
store.register_late_pass(|_| Box::new(entry::HashMapPass));
@@ -875,7 +890,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
- store.register_late_pass(move |_| Box::new(dereference::Dereferencing::new(msrv())));
+ store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
let future_size_threshold = conf.future_size_threshold;
@@ -1066,7 +1081,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
avoid_breaking_exported_api,
))
});
- store.register_late_pass(|_| Box::new(incorrect_impls::IncorrectImpls));
+ store.register_late_pass(|_| Box::new(non_canonical_impls::NonCanonicalImpls));
store.register_late_pass(move |_| {
Box::new(single_call_fn::SingleCallFn {
avoid_breaking_exported_api,
@@ -1095,6 +1110,15 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
store.register_late_pass(|_| Box::new(redundant_locals::RedundantLocals));
store.register_late_pass(|_| Box::new(ignored_unit_patterns::IgnoredUnitPatterns));
+ store.register_late_pass(|_| Box::<reserve_after_initialization::ReserveAfterInitialization>::default());
+ store.register_late_pass(|_| Box::new(implied_bounds_in_impls::ImpliedBoundsInImpls));
+ store.register_late_pass(|_| Box::new(missing_asserts_for_indexing::MissingAssertsForIndexing));
+ store.register_late_pass(|_| Box::new(unnecessary_map_on_constructor::UnnecessaryMapOnConstructor));
+ store.register_late_pass(move |_| {
+ Box::new(needless_borrows_for_generic_args::NeedlessBorrowsForGenericArgs::new(
+ msrv(),
+ ))
+ });
// add lints here, do not remove this comment, it's used in `new_lint`
}
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
index 7b8c88235..6ab256ef0 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -13,8 +13,14 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMut
use rustc_middle::ty::{self, EarlyBinder, Ty, TypeAndMut};
use rustc_span::sym;
-pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>, msrv: &Msrv) {
- let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr) else {
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ self_arg: &Expr<'_>,
+ call_expr: &Expr<'_>,
+ msrv: &Msrv,
+ enforce_iter_loop_reborrow: bool,
+) {
+ let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr, enforce_iter_loop_reborrow) else {
return;
};
if let ty::Array(_, count) = *ty.peel_refs().kind() {
@@ -102,6 +108,7 @@ fn is_ref_iterable<'tcx>(
cx: &LateContext<'tcx>,
self_arg: &Expr<'_>,
call_expr: &Expr<'_>,
+ enforce_iter_loop_reborrow: bool,
) -> Option<(AdjustKind, Ty<'tcx>)> {
let typeck = cx.typeck_results();
if let Some(trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
@@ -142,7 +149,8 @@ fn is_ref_iterable<'tcx>(
{
return Some((AdjustKind::None, self_ty));
}
- } else if let ty::Ref(region, ty, Mutability::Mut) = *self_ty.kind()
+ } else if enforce_iter_loop_reborrow
+ && let ty::Ref(region, ty, Mutability::Mut) = *self_ty.kind()
&& let Some(mutbl) = mutbl
{
// Attempt to reborrow the mutable reference
@@ -186,7 +194,8 @@ fn is_ref_iterable<'tcx>(
},
..
] => {
- if target != self_ty
+ if enforce_iter_loop_reborrow
+ && target != self_ty
&& implements_trait(cx, target, trait_id, &[])
&& let Some(ty) =
make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [target])
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index ffd29ab76..1fb16adad 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -609,10 +609,14 @@ declare_clippy_lint! {
pub struct Loops {
msrv: Msrv,
+ enforce_iter_loop_reborrow: bool,
}
impl Loops {
- pub fn new(msrv: Msrv) -> Self {
- Self { msrv }
+ pub fn new(msrv: Msrv, enforce_iter_loop_reborrow: bool) -> Self {
+ Self {
+ msrv,
+ enforce_iter_loop_reborrow,
+ }
}
}
impl_lint_pass!(Loops => [
@@ -719,7 +723,7 @@ impl Loops {
if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind {
match method.ident.as_str() {
"iter" | "iter_mut" => {
- explicit_iter_loop::check(cx, self_arg, arg, &self.msrv);
+ explicit_iter_loop::check(cx, self_arg, arg, &self.msrv, self.enforce_iter_loop_reborrow);
},
"into_iter" => {
explicit_into_iter_loop::check(cx, self_arg, arg);
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index cc19ac55e..3d8a4cd94 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -1,13 +1,13 @@
use super::utils::make_iterator_snippet;
use super::NEVER_LOOP;
-use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::ForLoop;
+use clippy_utils::macros::root_macro_call_first_node;
use clippy_utils::source::snippet;
use rustc_errors::Applicability;
use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
use rustc_lint::LateContext;
-use rustc_span::Span;
+use rustc_span::{sym, Span};
use std::iter::{once, Iterator};
pub(super) fn check<'tcx>(
@@ -18,7 +18,7 @@ pub(super) fn check<'tcx>(
for_loop: Option<&ForLoop<'_>>,
) {
match never_loop_block(cx, block, &mut Vec::new(), loop_id) {
- NeverLoopResult::AlwaysBreak => {
+ NeverLoopResult::Diverging => {
span_lint_and_then(cx, NEVER_LOOP, span, "this loop never actually loops", |diag| {
if let Some(ForLoop {
arg: iterator,
@@ -39,67 +39,76 @@ pub(super) fn check<'tcx>(
}
});
},
- NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Otherwise => (),
- NeverLoopResult::IgnoreUntilEnd(_) => unreachable!(),
+ NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Normal => (),
}
}
+/// The `never_loop` analysis keeps track of three things:
+///
+/// * Has any (reachable) code path hit a `continue` of the main loop?
+/// * Is the current code path diverging (that is, the next expression is not reachable)
+/// * For each block label `'a` inside the main loop, has any (reachable) code path encountered a
+/// `break 'a`?
+///
+/// The first two bits of information are in this enum, and the last part is in the
+/// `local_labels` variable, which contains a list of `(block_id, reachable)` pairs ordered by
+/// scope.
#[derive(Copy, Clone)]
enum NeverLoopResult {
- // A break/return always get triggered but not necessarily for the main loop.
- AlwaysBreak,
- // A continue may occur for the main loop.
+ /// A continue may occur for the main loop.
MayContinueMainLoop,
- // Ignore everything until the end of the block with this id
- IgnoreUntilEnd(HirId),
- Otherwise,
+ /// We have not encountered any main loop continue,
+ /// but we are diverging (subsequent control flow is not reachable)
+ Diverging,
+ /// We have not encountered any main loop continue,
+ /// and subsequent control flow is (possibly) reachable
+ Normal,
}
#[must_use]
fn absorb_break(arg: NeverLoopResult) -> NeverLoopResult {
match arg {
- NeverLoopResult::AlwaysBreak | NeverLoopResult::Otherwise => NeverLoopResult::Otherwise,
+ NeverLoopResult::Diverging | NeverLoopResult::Normal => NeverLoopResult::Normal,
NeverLoopResult::MayContinueMainLoop => NeverLoopResult::MayContinueMainLoop,
- NeverLoopResult::IgnoreUntilEnd(id) => NeverLoopResult::IgnoreUntilEnd(id),
}
}
// Combine two results for parts that are called in order.
#[must_use]
-fn combine_seq(first: NeverLoopResult, second: NeverLoopResult) -> NeverLoopResult {
+fn combine_seq(first: NeverLoopResult, second: impl FnOnce() -> NeverLoopResult) -> NeverLoopResult {
match first {
- NeverLoopResult::AlwaysBreak | NeverLoopResult::MayContinueMainLoop | NeverLoopResult::IgnoreUntilEnd(_) => {
- first
- },
- NeverLoopResult::Otherwise => second,
+ NeverLoopResult::Diverging | NeverLoopResult::MayContinueMainLoop => first,
+ NeverLoopResult::Normal => second(),
+ }
+}
+
+// Combine an iterator of results for parts that are called in order.
+#[must_use]
+fn combine_seq_many(iter: impl IntoIterator<Item = NeverLoopResult>) -> NeverLoopResult {
+ for e in iter {
+ if let NeverLoopResult::Diverging | NeverLoopResult::MayContinueMainLoop = e {
+ return e;
+ }
}
+ NeverLoopResult::Normal
}
// Combine two results where only one of the part may have been executed.
#[must_use]
-fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult, ignore_ids: &[HirId]) -> NeverLoopResult {
+fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult {
match (b1, b2) {
- (NeverLoopResult::IgnoreUntilEnd(a), NeverLoopResult::IgnoreUntilEnd(b)) => {
- if ignore_ids.iter().find(|&e| e == &a || e == &b).unwrap() == &a {
- NeverLoopResult::IgnoreUntilEnd(b)
- } else {
- NeverLoopResult::IgnoreUntilEnd(a)
- }
- },
- (i @ NeverLoopResult::IgnoreUntilEnd(_), NeverLoopResult::AlwaysBreak)
- | (NeverLoopResult::AlwaysBreak, i @ NeverLoopResult::IgnoreUntilEnd(_)) => i,
- (NeverLoopResult::AlwaysBreak, NeverLoopResult::AlwaysBreak) => NeverLoopResult::AlwaysBreak,
(NeverLoopResult::MayContinueMainLoop, _) | (_, NeverLoopResult::MayContinueMainLoop) => {
NeverLoopResult::MayContinueMainLoop
},
- (NeverLoopResult::Otherwise, _) | (_, NeverLoopResult::Otherwise) => NeverLoopResult::Otherwise,
+ (NeverLoopResult::Normal, _) | (_, NeverLoopResult::Normal) => NeverLoopResult::Normal,
+ (NeverLoopResult::Diverging, NeverLoopResult::Diverging) => NeverLoopResult::Diverging,
}
}
fn never_loop_block<'tcx>(
cx: &LateContext<'tcx>,
block: &Block<'tcx>,
- ignore_ids: &mut Vec<HirId>,
+ local_labels: &mut Vec<(HirId, bool)>,
main_loop_id: HirId,
) -> NeverLoopResult {
let iter = block
@@ -107,15 +116,21 @@ fn never_loop_block<'tcx>(
.iter()
.filter_map(stmt_to_expr)
.chain(block.expr.map(|expr| (expr, None)));
-
- iter.map(|(e, els)| {
- let e = never_loop_expr(cx, e, ignore_ids, main_loop_id);
+ combine_seq_many(iter.map(|(e, els)| {
+ let e = never_loop_expr(cx, e, local_labels, main_loop_id);
// els is an else block in a let...else binding
els.map_or(e, |els| {
- combine_branches(e, never_loop_block(cx, els, ignore_ids, main_loop_id), ignore_ids)
+ combine_seq(e, || match never_loop_block(cx, els, local_labels, main_loop_id) {
+ // Returning MayContinueMainLoop here means that
+ // we will not evaluate the rest of the body
+ NeverLoopResult::MayContinueMainLoop => NeverLoopResult::MayContinueMainLoop,
+ // An else block always diverges, so the Normal case should not happen,
+ // but the analysis is approximate so it might return Normal anyway.
+ // Returning Normal here says that nothing more happens on the main path
+ NeverLoopResult::Diverging | NeverLoopResult::Normal => NeverLoopResult::Normal,
+ })
})
- })
- .fold(NeverLoopResult::Otherwise, combine_seq)
+ }))
}
fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'tcx Block<'tcx>>)> {
@@ -131,76 +146,69 @@ fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'t
fn never_loop_expr<'tcx>(
cx: &LateContext<'tcx>,
expr: &Expr<'tcx>,
- ignore_ids: &mut Vec<HirId>,
+ local_labels: &mut Vec<(HirId, bool)>,
main_loop_id: HirId,
) -> NeverLoopResult {
- match expr.kind {
+ let result = match expr.kind {
ExprKind::Unary(_, e)
| ExprKind::Cast(e, _)
| ExprKind::Type(e, _)
| ExprKind::Field(e, _)
| ExprKind::AddrOf(_, _, e)
| ExprKind::Repeat(e, _)
- | ExprKind::DropTemps(e) => never_loop_expr(cx, e, ignore_ids, main_loop_id),
- ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, ignore_ids, main_loop_id),
- ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, &mut es.iter(), ignore_ids, main_loop_id),
+ | ExprKind::DropTemps(e) => never_loop_expr(cx, e, local_labels, main_loop_id),
+ ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id),
+ ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id),
ExprKind::MethodCall(_, receiver, es, _) => never_loop_expr_all(
cx,
- &mut std::iter::once(receiver).chain(es.iter()),
- ignore_ids,
+ std::iter::once(receiver).chain(es.iter()),
+ local_labels,
main_loop_id,
),
ExprKind::Struct(_, fields, base) => {
- let fields = never_loop_expr_all(cx, &mut fields.iter().map(|f| f.expr), ignore_ids, main_loop_id);
+ let fields = never_loop_expr_all(cx, fields.iter().map(|f| f.expr), local_labels, main_loop_id);
if let Some(base) = base {
- combine_seq(fields, never_loop_expr(cx, base, ignore_ids, main_loop_id))
+ combine_seq(fields, || never_loop_expr(cx, base, local_labels, main_loop_id))
} else {
fields
}
},
- ExprKind::Call(e, es) => never_loop_expr_all(cx, &mut once(e).chain(es.iter()), ignore_ids, main_loop_id),
+ ExprKind::Call(e, es) => never_loop_expr_all(cx, once(e).chain(es.iter()), local_labels, main_loop_id),
ExprKind::Binary(_, e1, e2)
| ExprKind::Assign(e1, e2, _)
| ExprKind::AssignOp(_, e1, e2)
- | ExprKind::Index(e1, e2, _) => {
- never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id)
- },
+ | ExprKind::Index(e1, e2, _) => never_loop_expr_all(cx, [e1, e2].iter().copied(), local_labels, main_loop_id),
ExprKind::Loop(b, _, _, _) => {
- // Break can come from the inner loop so remove them.
- absorb_break(never_loop_block(cx, b, ignore_ids, main_loop_id))
+ // We don't attempt to track reachability after a loop,
+ // just assume there may have been a break somewhere
+ absorb_break(never_loop_block(cx, b, local_labels, main_loop_id))
},
ExprKind::If(e, e2, e3) => {
- let e1 = never_loop_expr(cx, e, ignore_ids, main_loop_id);
- let e2 = never_loop_expr(cx, e2, ignore_ids, main_loop_id);
- // If we know the `if` condition evaluates to `true`, don't check everything past it; it
- // should just return whatever's evaluated for `e1` and `e2` since `e3` is unreachable
- if let Some(Constant::Bool(true)) = constant(cx, cx.typeck_results(), e) {
- return combine_seq(e1, e2);
- }
- let e3 = e3.as_ref().map_or(NeverLoopResult::Otherwise, |e| {
- never_loop_expr(cx, e, ignore_ids, main_loop_id)
- });
- combine_seq(e1, combine_branches(e2, e3, ignore_ids))
+ let e1 = never_loop_expr(cx, e, local_labels, main_loop_id);
+ combine_seq(e1, || {
+ let e2 = never_loop_expr(cx, e2, local_labels, main_loop_id);
+ let e3 = e3.as_ref().map_or(NeverLoopResult::Normal, |e| {
+ never_loop_expr(cx, e, local_labels, main_loop_id)
+ });
+ combine_branches(e2, e3)
+ })
},
ExprKind::Match(e, arms, _) => {
- let e = never_loop_expr(cx, e, ignore_ids, main_loop_id);
- if arms.is_empty() {
- e
- } else {
- let arms = never_loop_expr_branch(cx, &mut arms.iter().map(|a| a.body), ignore_ids, main_loop_id);
- combine_seq(e, arms)
- }
+ let e = never_loop_expr(cx, e, local_labels, main_loop_id);
+ combine_seq(e, || {
+ arms.iter().fold(NeverLoopResult::Diverging, |a, b| {
+ combine_branches(a, never_loop_expr(cx, b.body, local_labels, main_loop_id))
+ })
+ })
},
ExprKind::Block(b, l) => {
if l.is_some() {
- ignore_ids.push(b.hir_id);
- }
- let ret = never_loop_block(cx, b, ignore_ids, main_loop_id);
- if l.is_some() {
- ignore_ids.pop();
+ local_labels.push((b.hir_id, false));
}
+ let ret = never_loop_block(cx, b, local_labels, main_loop_id);
+ let jumped_to = l.is_some() && local_labels.pop().unwrap().1;
match ret {
- NeverLoopResult::IgnoreUntilEnd(a) if a == b.hir_id => NeverLoopResult::Otherwise,
+ NeverLoopResult::Diverging if jumped_to => NeverLoopResult::Normal,
_ => ret,
}
},
@@ -211,74 +219,78 @@ fn never_loop_expr<'tcx>(
if id == main_loop_id {
NeverLoopResult::MayContinueMainLoop
} else {
- NeverLoopResult::AlwaysBreak
+ NeverLoopResult::Diverging
}
},
- // checks if break targets a block instead of a loop
- ExprKind::Break(Destination { target_id: Ok(t), .. }, e) if ignore_ids.contains(&t) => e
- .map_or(NeverLoopResult::IgnoreUntilEnd(t), |e| {
- never_loop_expr(cx, e, ignore_ids, main_loop_id)
- }),
- ExprKind::Break(_, e) | ExprKind::Ret(e) => e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| {
- combine_seq(
- never_loop_expr(cx, e, ignore_ids, main_loop_id),
- NeverLoopResult::AlwaysBreak,
- )
- }),
- ExprKind::Become(e) => combine_seq(
- never_loop_expr(cx, e, ignore_ids, main_loop_id),
- NeverLoopResult::AlwaysBreak,
- ),
- ExprKind::InlineAsm(asm) => asm
- .operands
- .iter()
- .map(|(o, _)| match o {
- InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
- never_loop_expr(cx, expr, ignore_ids, main_loop_id)
- },
- InlineAsmOperand::Out { expr, .. } => {
- never_loop_expr_all(cx, &mut expr.iter().copied(), ignore_ids, main_loop_id)
- },
- InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => never_loop_expr_all(
- cx,
- &mut once(*in_expr).chain(out_expr.iter().copied()),
- ignore_ids,
- main_loop_id,
- ),
- InlineAsmOperand::Const { .. }
- | InlineAsmOperand::SymFn { .. }
- | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise,
+ ExprKind::Break(_, e) | ExprKind::Ret(e) => {
+ let first = e.as_ref().map_or(NeverLoopResult::Normal, |e| {
+ never_loop_expr(cx, e, local_labels, main_loop_id)
+ });
+ combine_seq(first, || {
+ // checks if break targets a block instead of a loop
+ if let ExprKind::Break(Destination { target_id: Ok(t), .. }, _) = expr.kind {
+ if let Some((_, reachable)) = local_labels.iter_mut().find(|(label, _)| *label == t) {
+ *reachable = true;
+ }
+ }
+ NeverLoopResult::Diverging
})
- .fold(NeverLoopResult::Otherwise, combine_seq),
+ },
+ ExprKind::Become(e) => combine_seq(never_loop_expr(cx, e, local_labels, main_loop_id), || {
+ NeverLoopResult::Diverging
+ }),
+ ExprKind::InlineAsm(asm) => combine_seq_many(asm.operands.iter().map(|(o, _)| match o {
+ InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
+ never_loop_expr(cx, expr, local_labels, main_loop_id)
+ },
+ InlineAsmOperand::Out { expr, .. } => {
+ never_loop_expr_all(cx, expr.iter().copied(), local_labels, main_loop_id)
+ },
+ InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => never_loop_expr_all(
+ cx,
+ once(*in_expr).chain(out_expr.iter().copied()),
+ local_labels,
+ main_loop_id,
+ ),
+ InlineAsmOperand::Const { .. } | InlineAsmOperand::SymFn { .. } | InlineAsmOperand::SymStatic { .. } => {
+ NeverLoopResult::Normal
+ },
+ })),
ExprKind::OffsetOf(_, _)
| ExprKind::Yield(_, _)
| ExprKind::Closure { .. }
| ExprKind::Path(_)
| ExprKind::ConstBlock(_)
| ExprKind::Lit(_)
- | ExprKind::Err(_) => NeverLoopResult::Otherwise,
+ | ExprKind::Err(_) => NeverLoopResult::Normal,
+ };
+ let result = combine_seq(result, || {
+ if cx.typeck_results().expr_ty(expr).is_never() {
+ NeverLoopResult::Diverging
+ } else {
+ NeverLoopResult::Normal
+ }
+ });
+ if let NeverLoopResult::Diverging = result &&
+ let Some(macro_call) = root_macro_call_first_node(cx, expr) &&
+ let Some(sym::todo_macro) = cx.tcx.get_diagnostic_name(macro_call.def_id)
+ {
+ // We return MayContinueMainLoop here because we treat `todo!()`
+ // as potentially containing any code, including a continue of the main loop.
+ // This effectively silences the lint whenever a loop contains this macro anywhere.
+ NeverLoopResult::MayContinueMainLoop
+ } else {
+ result
}
}
fn never_loop_expr_all<'tcx, T: Iterator<Item = &'tcx Expr<'tcx>>>(
cx: &LateContext<'tcx>,
- es: &mut T,
- ignore_ids: &mut Vec<HirId>,
- main_loop_id: HirId,
-) -> NeverLoopResult {
- es.map(|e| never_loop_expr(cx, e, ignore_ids, main_loop_id))
- .fold(NeverLoopResult::Otherwise, combine_seq)
-}
-
-fn never_loop_expr_branch<'tcx, T: Iterator<Item = &'tcx Expr<'tcx>>>(
- cx: &LateContext<'tcx>,
- e: &mut T,
- ignore_ids: &mut Vec<HirId>,
+ es: T,
+ local_labels: &mut Vec<(HirId, bool)>,
main_loop_id: HirId,
) -> NeverLoopResult {
- e.fold(NeverLoopResult::AlwaysBreak, |a, b| {
- combine_branches(a, never_loop_expr(cx, b, ignore_ids, main_loop_id), ignore_ids)
- })
+ combine_seq_many(es.map(|e| never_loop_expr(cx, e, local_labels, main_loop_id)))
}
fn for_to_if_let_sugg(cx: &LateContext<'_>, iterator: &Expr<'_>, pat: &Pat<'_>) -> String {
diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs
index 6edca2d55..0a2bd89eb 100644
--- a/src/tools/clippy/clippy_lints/src/loops/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs
@@ -5,7 +5,6 @@ use rustc_ast::ast::{LitIntType, LitKind};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, walk_local, walk_pat, walk_stmt, Visitor};
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, Pat, PatKind, Stmt};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, Ty};
@@ -150,7 +149,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
if l.pat.hir_id == self.var_id;
if let PatKind::Binding(.., ident, _) = l.pat.kind;
then {
- let ty = l.ty.map(|ty| hir_ty_to_ty(self.cx.tcx, ty));
+ let ty = l.ty.map(|_| self.cx.typeck_results().pat_ty(l.pat));
self.state = l.init.map_or(InitializeVisitorState::Declared(ident.name, ty), |init| {
InitializeVisitorState::Initialized {
diff --git a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
index 39d8b20d3..90557b555 100644
--- a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
@@ -1,4 +1,5 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet_opt;
use rustc_ast::LitKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
@@ -6,6 +7,7 @@ use rustc_hir::{Expr, ExprKind, PatKind, RangeEnd, UnOp};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::{Span, DUMMY_SP};
declare_clippy_lint! {
/// ### What it does
@@ -49,6 +51,29 @@ fn expr_as_i128(expr: &Expr<'_>) -> Option<i128> {
}
}
+#[derive(Copy, Clone)]
+struct Num {
+ val: i128,
+ span: Span,
+}
+
+impl Num {
+ fn new(expr: &Expr<'_>) -> Option<Self> {
+ Some(Self {
+ val: expr_as_i128(expr)?,
+ span: expr.span,
+ })
+ }
+
+ fn dummy(val: i128) -> Self {
+ Self { val, span: DUMMY_SP }
+ }
+
+ fn min(self, other: Self) -> Self {
+ if self.val < other.val { self } else { other }
+ }
+}
+
impl LateLintPass<'_> for ManualRangePatterns {
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &'_ rustc_hir::Pat<'_>) {
if in_external_macro(cx.sess(), pat.span) {
@@ -56,71 +81,83 @@ impl LateLintPass<'_> for ManualRangePatterns {
}
// a pattern like 1 | 2 seems fine, lint if there are at least 3 alternatives
+ // or at least one range
if let PatKind::Or(pats) = pat.kind
- && pats.len() >= 3
+ && (pats.len() >= 3 || pats.iter().any(|p| matches!(p.kind, PatKind::Range(..))))
{
- let mut min = i128::MAX;
- let mut max = i128::MIN;
+ let mut min = Num::dummy(i128::MAX);
+ let mut max = Num::dummy(i128::MIN);
+ let mut range_kind = RangeEnd::Included;
let mut numbers_found = FxHashSet::default();
let mut ranges_found = Vec::new();
for pat in pats {
if let PatKind::Lit(lit) = pat.kind
- && let Some(num) = expr_as_i128(lit)
+ && let Some(num) = Num::new(lit)
{
- numbers_found.insert(num);
+ numbers_found.insert(num.val);
min = min.min(num);
- max = max.max(num);
+ if num.val >= max.val {
+ max = num;
+ range_kind = RangeEnd::Included;
+ }
} else if let PatKind::Range(Some(left), Some(right), end) = pat.kind
- && let Some(left) = expr_as_i128(left)
- && let Some(right) = expr_as_i128(right)
- && right >= left
+ && let Some(left) = Num::new(left)
+ && let Some(mut right) = Num::new(right)
{
+ if let RangeEnd::Excluded = end {
+ right.val -= 1;
+ }
+
min = min.min(left);
- max = max.max(right);
- ranges_found.push(left..=match end {
- RangeEnd::Included => right,
- RangeEnd::Excluded => right - 1,
- });
+ if right.val > max.val {
+ max = right;
+ range_kind = end;
+ }
+ ranges_found.push(left.val..=right.val);
} else {
return;
}
}
- let contains_whole_range = 'contains: {
- let mut num = min;
- while num <= max {
- if numbers_found.contains(&num) {
- num += 1;
- }
- // Given a list of (potentially overlapping) ranges like:
- // 1..=5, 3..=7, 6..=10
- // We want to find the range with the highest end that still contains the current number
- else if let Some(range) = ranges_found
- .iter()
- .filter(|range| range.contains(&num))
- .max_by_key(|range| range.end())
- {
- num = range.end() + 1;
- } else {
- break 'contains false;
- }
+ let mut num = min.val;
+ while num <= max.val {
+ if numbers_found.contains(&num) {
+ num += 1;
+ }
+ // Given a list of (potentially overlapping) ranges like:
+ // 1..=5, 3..=7, 6..=10
+ // We want to find the range with the highest end that still contains the current number
+ else if let Some(range) = ranges_found
+ .iter()
+ .filter(|range| range.contains(&num))
+ .max_by_key(|range| range.end())
+ {
+ num = range.end() + 1;
+ } else {
+ return;
}
- break 'contains true;
- };
-
- if contains_whole_range {
- span_lint_and_sugg(
- cx,
- MANUAL_RANGE_PATTERNS,
- pat.span,
- "this OR pattern can be rewritten using a range",
- "try",
- format!("{min}..={max}"),
- Applicability::MachineApplicable,
- );
}
+
+ span_lint_and_then(
+ cx,
+ MANUAL_RANGE_PATTERNS,
+ pat.span,
+ "this OR pattern can be rewritten using a range",
+ |diag| {
+ if let Some(min) = snippet_opt(cx, min.span)
+ && let Some(max) = snippet_opt(cx, max.span)
+ {
+ diag.span_suggestion(
+ pat.span,
+ "try",
+ format!("{min}{range_kind}{max}"),
+ Applicability::MachineApplicable,
+ );
+ }
+ },
+ );
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index 5259066eb..1a69a48c5 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -12,13 +12,15 @@ use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::sym;
-const ACCEPTABLE_METHODS: [&[&str]; 4] = [
+const ACCEPTABLE_METHODS: [&[&str]; 5] = [
+ &paths::BINARYHEAP_ITER,
&paths::HASHSET_ITER,
&paths::BTREESET_ITER,
&paths::SLICE_INTO,
&paths::VEC_DEQUE_ITER,
];
-const ACCEPTABLE_TYPES: [(rustc_span::Symbol, Option<RustcVersion>); 6] = [
+const ACCEPTABLE_TYPES: [(rustc_span::Symbol, Option<RustcVersion>); 7] = [
+ (sym::BinaryHeap, Some(msrvs::BINARY_HEAP_RETAIN)),
(sym::BTreeSet, Some(msrvs::BTREE_SET_RETAIN)),
(sym::BTreeMap, Some(msrvs::BTREE_MAP_RETAIN)),
(sym::HashSet, Some(msrvs::HASH_SET_RETAIN)),
diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
index c4f6852ae..44dc29c36 100644
--- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
@@ -8,8 +8,7 @@ use clippy_utils::{
};
use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, Guard, ItemKind, Node, Pat, PatKind, Path, QPath};
use rustc_lint::LateContext;
use rustc_span::sym;
@@ -141,11 +140,15 @@ fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>
return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
},
// compare match_expr ty with RetTy in `fn foo() -> RetTy`
- Node::Item(..) => {
- if let Some(fn_decl) = p_node.fn_decl() {
- if let FnRetTy::Return(ret_ty) = fn_decl.output {
- return same_type_and_consts(hir_ty_to_ty(cx.tcx, ret_ty), cx.typeck_results().expr_ty(expr));
- }
+ Node::Item(item) => {
+ if let ItemKind::Fn(..) = item.kind {
+ let output = cx
+ .tcx
+ .fn_sig(item.owner_id)
+ .instantiate_identity()
+ .output()
+ .skip_binder();
+ return same_type_and_consts(output, cx.typeck_results().expr_ty(expr));
}
},
// check the parent expr for this whole block `{ match match_expr {..} }`
diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
index 8be3c178a..7c0485914 100644
--- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
@@ -37,22 +37,14 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
Some(lhs) => constant(cx, cx.typeck_results(), lhs)?,
None => {
let min_val_const = ty.numeric_min_val(cx.tcx)?;
- let min_constant = mir::ConstantKind::from_value(
- cx.tcx.valtree_to_const_val((ty, min_val_const.to_valtree())),
- ty,
- );
- miri_to_const(cx, min_constant)?
+ miri_to_const(cx, mir::Const::from_ty_const(min_val_const, cx.tcx))?
},
};
let rhs_const = match rhs {
Some(rhs) => constant(cx, cx.typeck_results(), rhs)?,
None => {
let max_val_const = ty.numeric_max_val(cx.tcx)?;
- let max_constant = mir::ConstantKind::from_value(
- cx.tcx.valtree_to_const_val((ty, max_val_const.to_valtree())),
- ty,
- );
- miri_to_const(cx, max_constant)?
+ miri_to_const(cx, mir::Const::from_ty_const(max_val_const, cx.tcx))?
},
};
let lhs_val = lhs_const.int_value(cx, ty)?;
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index 29af48123..0efeeacc9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -2,11 +2,12 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::path_to_local;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::visitors::{for_each_expr, is_local_used};
-use rustc_ast::LitKind;
+use rustc_ast::{BorrowKind, LitKind};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, Guard, MatchSource, Node, Pat, PatKind};
use rustc_lint::LateContext;
+use rustc_span::symbol::Ident;
use rustc_span::Span;
use std::ops::ControlFlow;
@@ -34,32 +35,45 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
],
MatchSource::Normal,
) = if_expr.kind
+ && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm)
{
+ let pat_span = match (arm.pat.kind, binding.byref_ident) {
+ (PatKind::Ref(pat, _), Some(_)) => pat.span,
+ (PatKind::Ref(..), None) | (_, Some(_)) => continue,
+ _ => arm.pat.span,
+ };
emit_redundant_guards(
cx,
outer_arm,
if_expr.span,
- scrutinee,
- arm.pat.span,
+ pat_span,
+ &binding,
arm.guard,
);
}
// `Some(x) if let Some(2) = x`
- else if let Guard::IfLet(let_expr) = guard {
+ else if let Guard::IfLet(let_expr) = guard
+ && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm)
+ {
+ let pat_span = match (let_expr.pat.kind, binding.byref_ident) {
+ (PatKind::Ref(pat, _), Some(_)) => pat.span,
+ (PatKind::Ref(..), None) | (_, Some(_)) => continue,
+ _ => let_expr.pat.span,
+ };
emit_redundant_guards(
cx,
outer_arm,
let_expr.span,
- let_expr.init,
- let_expr.pat.span,
+ pat_span,
+ &binding,
None,
);
}
// `Some(x) if x == Some(2)`
+ // `Some(x) if Some(2) == x`
else if let Guard::If(if_expr) = guard
&& let ExprKind::Binary(bin_op, local, pat) = if_expr.kind
&& matches!(bin_op.node, BinOpKind::Eq)
- && expr_can_be_pat(cx, pat)
// Ensure they have the same type. If they don't, we'd need deref coercion which isn't
// possible (currently) in a pattern. In some cases, you can use something like
// `as_deref` or similar but in general, we shouldn't lint this as it'd create an
@@ -67,43 +81,68 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
//
// This isn't necessary in the other two checks, as they must be a pattern already.
&& cx.typeck_results().expr_ty(local) == cx.typeck_results().expr_ty(pat)
+ // Since we want to lint on both `x == Some(2)` and `Some(2) == x`, we might have to "swap"
+ // `local` and `pat`, depending on which side they are.
+ && let Some((binding, pat)) = get_pat_binding(cx, local, outer_arm)
+ .map(|binding| (binding, pat))
+ .or_else(|| get_pat_binding(cx, pat, outer_arm).map(|binding| (binding, local)))
+ && expr_can_be_pat(cx, pat)
{
+ let pat_span = match (pat.kind, binding.byref_ident) {
+ (ExprKind::AddrOf(BorrowKind::Ref, _, expr), Some(_)) => expr.span,
+ (ExprKind::AddrOf(..), None) | (_, Some(_)) => continue,
+ _ => pat.span,
+ };
emit_redundant_guards(
cx,
outer_arm,
if_expr.span,
- local,
- pat.span,
+ pat_span,
+ &binding,
None,
);
}
}
}
-fn get_pat_binding<'tcx>(cx: &LateContext<'tcx>, guard_expr: &Expr<'_>, outer_arm: &Arm<'tcx>) -> Option<(Span, bool)> {
+struct PatBindingInfo {
+ span: Span,
+ byref_ident: Option<Ident>,
+ is_field: bool,
+}
+
+fn get_pat_binding<'tcx>(
+ cx: &LateContext<'tcx>,
+ guard_expr: &Expr<'_>,
+ outer_arm: &Arm<'tcx>,
+) -> Option<PatBindingInfo> {
if let Some(local) = path_to_local(guard_expr) && !is_local_used(cx, outer_arm.body, local) {
let mut span = None;
+ let mut byref_ident = None;
let mut multiple_bindings = false;
// `each_binding` gives the `HirId` of the `Pat` itself, not the binding
outer_arm.pat.walk(|pat| {
- if let PatKind::Binding(_, hir_id, _, _) = pat.kind
+ if let PatKind::Binding(bind_annot, hir_id, ident, _) = pat.kind
&& hir_id == local
- && span.replace(pat.span).is_some()
{
- multiple_bindings = true;
- return false;
+ if matches!(bind_annot.0, rustc_ast::ByRef::Yes) {
+ let _ = byref_ident.insert(ident);
+ }
+ // the second call of `replace()` returns a `Some(span)`, meaning a multi-binding pattern
+ if span.replace(pat.span).is_some() {
+ multiple_bindings = true;
+ return false;
+ }
}
-
true
});
// Ignore bindings from or patterns, like `First(x) | Second(x, _) | Third(x, _, _)`
if !multiple_bindings {
- return span.map(|span| {
- (
- span,
- !matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
- )
+ return span.map(|span| PatBindingInfo {
+ span,
+ byref_ident,
+ is_field: matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
});
}
}
@@ -115,14 +154,11 @@ fn emit_redundant_guards<'tcx>(
cx: &LateContext<'tcx>,
outer_arm: &Arm<'tcx>,
guard_span: Span,
- local: &Expr<'_>,
pat_span: Span,
+ pat_binding: &PatBindingInfo,
inner_guard: Option<Guard<'_>>,
) {
let mut app = Applicability::MaybeIncorrect;
- let Some((pat_binding, can_use_shorthand)) = get_pat_binding(cx, local, outer_arm) else {
- return;
- };
span_lint_and_then(
cx,
@@ -131,14 +167,21 @@ fn emit_redundant_guards<'tcx>(
"redundant guard",
|diag| {
let binding_replacement = snippet_with_applicability(cx, pat_span, "<binding_repl>", &mut app);
+ let suggestion_span = match *pat_binding {
+ PatBindingInfo {
+ span,
+ byref_ident: Some(ident),
+ is_field: true,
+ } => (span, format!("{ident}: {binding_replacement}")),
+ PatBindingInfo {
+ span, is_field: true, ..
+ } => (span.shrink_to_hi(), format!(": {binding_replacement}")),
+ PatBindingInfo { span, .. } => (span, binding_replacement.into_owned()),
+ };
diag.multipart_suggestion_verbose(
"try",
vec![
- if can_use_shorthand {
- (pat_binding, binding_replacement.into_owned())
- } else {
- (pat_binding.shrink_to_hi(), format!(": {binding_replacement}"))
- },
+ suggestion_span,
(
guard_span.source_callsite().with_lo(outer_arm.pat.span.hi()),
inner_guard.map_or_else(String::new, |guard| {
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
index d3e90e4bb..40e487bf6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
@@ -131,13 +131,12 @@ pub(super) fn check<'tcx>(
let mut applicability = Applicability::MachineApplicable;
- //Special handling for `format!` as arg_root
+ // Special handling for `format!` as arg_root
if let Some(macro_call) = root_macro_call_first_node(cx, arg_root) {
- if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
- return;
- }
- find_format_args(cx, arg_root, macro_call.expn, |format_args| {
- let span = format_args_inputs_span(format_args);
+ if cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
+ && let Some(format_args) = find_format_args(cx, arg_root, macro_call.expn)
+ {
+ let span = format_args_inputs_span(&format_args);
let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
span_lint_and_sugg(
cx,
@@ -148,7 +147,7 @@ pub(super) fn check<'tcx>(
format!("unwrap_or_else({closure_args} panic!({sugg}))"),
applicability,
);
- });
+ }
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index fafc97097..336572549 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -8,6 +8,7 @@ use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::Binder;
use rustc_span::{sym, Span};
@@ -36,6 +37,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
&& let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id)
&& match_def_path(cx, def_id, &BOOL_THEN)
&& !is_from_proc_macro(cx, expr)
+ // Count the number of derefs needed to get to the bool because we need those in the suggestion
+ && let needed_derefs = cx.typeck_results().expr_adjustments(recv)
+ .iter()
+ .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
+ .count()
&& let Some(param_snippet) = snippet_opt(cx, param.span)
&& let Some(filter) = snippet_opt(cx, recv.span)
&& let Some(map) = snippet_opt(cx, then_body.span)
@@ -46,7 +52,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
call_span,
"usage of `bool::then` in `filter_map`",
"use `filter` then `map` instead",
- format!("filter(|&{param_snippet}| {filter}).map(|{param_snippet}| {map})"),
+ format!(
+ "filter(|&{param_snippet}| {derefs}{filter}).map(|{param_snippet}| {map})",
+ derefs="*".repeat(needed_derefs)
+ ),
Applicability::MachineApplicable,
);
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
index 043425300..e91ce64d8 100644
--- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
@@ -17,6 +17,7 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv
let return_type = cx.typeck_results().expr_ty(expr);
let input_type = cx.typeck_results().expr_ty(recv);
let (input_type, ref_count) = peel_mid_ty_refs(input_type);
+ if !(ref_count > 0 && is_diag_trait_item(cx, method_def_id, sym::ToOwned));
if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did()));
if return_type == input_type;
if let Some(clone_trait) = cx.tcx.lang_items().clone_trait();
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
new file mode 100644
index 000000000..79c6d6325
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
@@ -0,0 +1,106 @@
+use clippy_utils::diagnostics::span_lint_and_note;
+use clippy_utils::higher::VecArgs;
+use clippy_utils::{expr_or_init, is_trait_method, match_def_path, paths};
+use rustc_ast::LitKind;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self};
+use rustc_span::sym;
+
+use super::ITER_OUT_OF_BOUNDS;
+
+fn expr_as_u128(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<u128> {
+ if let ExprKind::Lit(lit) = expr_or_init(cx, e).kind
+ && let LitKind::Int(n, _) = lit.node
+ {
+ Some(n)
+ } else {
+ None
+ }
+}
+
+/// Attempts to extract the length out of an iterator expression.
+fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) -> Option<u128> {
+ let ty::Adt(adt, substs) = cx.typeck_results().expr_ty(iter).kind() else {
+ return None;
+ };
+ let did = adt.did();
+
+ if match_def_path(cx, did, &paths::ARRAY_INTO_ITER) {
+ // For array::IntoIter<T, const N: usize>, the length is the second generic
+ // parameter.
+ substs
+ .const_at(1)
+ .try_eval_target_usize(cx.tcx, cx.param_env)
+ .map(u128::from)
+ } else if match_def_path(cx, did, &paths::SLICE_ITER)
+ && let ExprKind::MethodCall(_, recv, ..) = iter.kind
+ {
+ if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() {
+ // For slice::Iter<'_, T>, the receiver might be an array literal: [1,2,3].iter().skip(..)
+ len.try_eval_target_usize(cx.tcx, cx.param_env).map(u128::from)
+ } else if let Some(args) = VecArgs::hir(cx, expr_or_init(cx, recv)) {
+ match args {
+ VecArgs::Vec(vec) => vec.len().try_into().ok(),
+ VecArgs::Repeat(_, len) => expr_as_u128(cx, len),
+ }
+ } else {
+ None
+ }
+ } else if match_def_path(cx, did, &paths::ITER_EMPTY) {
+ Some(0)
+ } else if match_def_path(cx, did, &paths::ITER_ONCE) {
+ Some(1)
+ } else {
+ None
+ }
+}
+
+fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'tcx>,
+ recv: &'tcx Expr<'tcx>,
+ arg: &'tcx Expr<'tcx>,
+ message: &'static str,
+ note: &'static str,
+) {
+ if is_trait_method(cx, expr, sym::Iterator)
+ && let Some(len) = get_iterator_length(cx, recv)
+ && let Some(skipped) = expr_as_u128(cx, arg)
+ && skipped > len
+ {
+ span_lint_and_note(cx, ITER_OUT_OF_BOUNDS, expr.span, message, None, note);
+ }
+}
+
+pub(super) fn check_skip<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'tcx>,
+ recv: &'tcx Expr<'tcx>,
+ arg: &'tcx Expr<'tcx>,
+) {
+ check(
+ cx,
+ expr,
+ recv,
+ arg,
+ "this `.skip()` call skips more items than the iterator will produce",
+ "this operation is useless and will create an empty iterator",
+ );
+}
+
+pub(super) fn check_take<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'tcx>,
+ recv: &'tcx Expr<'tcx>,
+ arg: &'tcx Expr<'tcx>,
+) {
+ check(
+ cx,
+ expr,
+ recv,
+ arg,
+ "this `.take()` call takes more items than the iterator will produce",
+ "this operation is useless and the returned iterator will simply yield the same items",
+ );
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
index 9f7ec19aa..a49dd98db 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
@@ -1,21 +1,45 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{implements_trait, is_copy};
+use rustc_ast::BindingAnnotation;
use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Body, Expr, ExprKind, HirId, HirIdSet, PatKind};
+use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use rustc_lint::LateContext;
-use rustc_middle::ty;
+use rustc_middle::mir::{FakeReadCause, Mutability};
+use rustc_middle::ty::{self, BorrowKind};
use rustc_span::sym;
use super::ITER_OVEREAGER_CLONED;
use crate::redundant_clone::REDUNDANT_CLONE;
+use crate::rustc_trait_selection::infer::TyCtxtInferExt;
+
+#[derive(Clone, Copy)]
+pub(super) enum Op<'a> {
+ // rm `.cloned()`
+ // e.g. `count`
+ RmCloned,
+
+ // rm `.cloned()`
+ // e.g. `map` `for_each` `all` `any`
+ NeedlessMove(&'a str, &'a Expr<'a>),
+
+ // later `.cloned()`
+ // and add `&` to the parameter of closure parameter
+ // e.g. `find` `filter`
+ FixClosure(&'a str, &'a Expr<'a>),
+
+ // later `.cloned()`
+ // e.g. `skip` `take`
+ LaterCloned,
+}
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'_>,
cloned_call: &'tcx Expr<'_>,
cloned_recv: &'tcx Expr<'_>,
- is_count: bool,
+ op: Op<'tcx>,
needs_into_iter: bool,
) {
let typeck = cx.typeck_results();
@@ -35,10 +59,47 @@ pub(super) fn check<'tcx>(
return;
}
- let (lint, msg, trailing_clone) = if is_count {
- (REDUNDANT_CLONE, "unneeded cloning of iterator items", "")
- } else {
- (ITER_OVEREAGER_CLONED, "unnecessarily eager cloning of iterator items", ".cloned()")
+ if let Op::NeedlessMove(_, expr) = op {
+ let rustc_hir::ExprKind::Closure(closure) = expr.kind else { return } ;
+ let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else { return };
+ let mut delegate = MoveDelegate {used_move : HirIdSet::default()};
+ let infcx = cx.tcx.infer_ctxt().build();
+
+ ExprUseVisitor::new(
+ &mut delegate,
+ &infcx,
+ closure.body.hir_id.owner.def_id,
+ cx.param_env,
+ cx.typeck_results(),
+ )
+ .consume_body(body);
+
+ let mut to_be_discarded = false;
+
+ p.pat.walk(|it| {
+ if delegate.used_move.contains(&it.hir_id){
+ to_be_discarded = true;
+ return false;
+ }
+
+ match it.kind {
+ PatKind::Binding(BindingAnnotation(_, Mutability::Mut), _, _, _)
+ | PatKind::Ref(_, Mutability::Mut) => {
+ to_be_discarded = true;
+ false
+ }
+ _ => { true }
+ }
+ });
+
+ if to_be_discarded {
+ return;
+ }
+ }
+
+ let (lint, msg, trailing_clone) = match op {
+ Op::RmCloned | Op::NeedlessMove(_, _) => (REDUNDANT_CLONE, "unneeded cloning of iterator items", ""),
+ Op::LaterCloned | Op::FixClosure(_, _) => (ITER_OVEREAGER_CLONED, "unnecessarily eager cloning of iterator items", ".cloned()"),
};
span_lint_and_then(
@@ -47,13 +108,54 @@ pub(super) fn check<'tcx>(
expr.span,
msg,
|diag| {
- let method_span = expr.span.with_lo(cloned_call.span.hi());
- if let Some(mut snip) = snippet_opt(cx, method_span) {
- snip.push_str(trailing_clone);
- let replace_span = expr.span.with_lo(cloned_recv.span.hi());
- diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable);
+ match op {
+ Op::RmCloned | Op::LaterCloned => {
+ let method_span = expr.span.with_lo(cloned_call.span.hi());
+ if let Some(mut snip) = snippet_opt(cx, method_span) {
+ snip.push_str(trailing_clone);
+ let replace_span = expr.span.with_lo(cloned_recv.span.hi());
+ diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable);
+ }
+ }
+ Op::FixClosure(name, predicate_expr) => {
+ if let Some(predicate) = snippet_opt(cx, predicate_expr.span) {
+ let new_closure = if let ExprKind::Closure(_) = predicate_expr.kind {
+ predicate.replacen('|', "|&", 1)
+ } else {
+ format!("|&x| {predicate}(x)")
+ };
+ let snip = format!(".{name}({new_closure}).cloned()" );
+ let replace_span = expr.span.with_lo(cloned_recv.span.hi());
+ diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable);
+ }
+ }
+ Op::NeedlessMove(_, _) => {
+ let method_span = expr.span.with_lo(cloned_call.span.hi());
+ if let Some(snip) = snippet_opt(cx, method_span) {
+ let replace_span = expr.span.with_lo(cloned_recv.span.hi());
+ diag.span_suggestion(replace_span, "try", snip, Applicability::MaybeIncorrect);
+ }
+ }
}
}
);
}
}
+
+struct MoveDelegate {
+ used_move: HirIdSet,
+}
+
+impl<'tcx> Delegate<'tcx> for MoveDelegate {
+ fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, _: HirId) {
+ if let PlaceBase::Local(l) = place_with_id.place.base {
+ self.used_move.insert(l);
+ }
+ }
+
+ fn borrow(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: BorrowKind) {}
+
+ fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
+
+ fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 42756b27d..e7fcef9e9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -43,6 +43,7 @@ mod iter_next_slice;
mod iter_nth;
mod iter_nth_zero;
mod iter_on_single_or_empty_collections;
+mod iter_out_of_bounds;
mod iter_overeager_cloned;
mod iter_skip_next;
mod iter_skip_zero;
@@ -73,9 +74,11 @@ mod option_map_unwrap_or;
mod or_fun_call;
mod or_then_unwrap;
mod path_buf_push_overwrite;
+mod path_ends_with_ext;
mod range_zip_with_len;
mod read_line_without_trim;
mod readonly_write_lock;
+mod redundant_as_str;
mod repeat_once;
mod search_is_some;
mod seek_from_current;
@@ -119,9 +122,10 @@ use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
use if_chain::if_chain;
+pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
+use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, TraitRef, Ty};
@@ -301,7 +305,7 @@ declare_clippy_lint! {
/// let val2 = 1;
/// let val3 = 1;
/// ```
- #[clippy::version = "1.69.0"]
+ #[clippy::version = "1.72.0"]
pub UNNECESSARY_LITERAL_UNWRAP,
complexity,
"using `unwrap()` related calls on `Result` and `Option` constructors"
@@ -3054,12 +3058,12 @@ declare_clippy_lint! {
///
/// ### Example
/// ```rust
- /// vec!(1, 2, 3, 4, 5).resize(0, 5)
+ /// vec![1, 2, 3, 4, 5].resize(0, 5)
/// ```
///
/// Use instead:
/// ```rust
- /// vec!(1, 2, 3, 4, 5).clear()
+ /// vec![1, 2, 3, 4, 5].clear()
/// ```
#[clippy::version = "1.46.0"]
pub VEC_RESIZE_TO_ZERO,
@@ -3328,7 +3332,7 @@ declare_clippy_lint! {
/// mem::take(v)
/// }
/// ```
- #[clippy::version = "1.71.0"]
+ #[clippy::version = "1.72.0"]
pub DRAIN_COLLECT,
perf,
"calling `.drain(..).collect()` to move all elements into a new collection"
@@ -3538,11 +3542,101 @@ declare_clippy_lint! {
"acquiring a write lock when a read lock would work"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Looks for iterator combinator calls such as `.take(x)` or `.skip(x)`
+ /// where `x` is greater than the amount of items that an iterator will produce.
+ ///
+ /// ### Why is this bad?
+ /// Taking or skipping more items than there are in an iterator either creates an iterator
+ /// with all items from the original iterator or an iterator with no items at all.
+ /// This is most likely not what the user intended to do.
+ ///
+ /// ### Example
+ /// ```rust
+ /// for _ in [1, 2, 3].iter().take(4) {}
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// for _ in [1, 2, 3].iter() {}
+ /// ```
+ #[clippy::version = "1.74.0"]
+ pub ITER_OUT_OF_BOUNDS,
+ suspicious,
+ "calls to `.take()` or `.skip()` that are out of bounds"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Looks for calls to `Path::ends_with` calls where the argument looks like a file extension.
+ ///
+ /// By default, Clippy has a short list of known filenames that start with a dot
+ /// but aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default.
+ /// The `allowed-dotfiles` configuration can be used to allow additional
+ /// file extensions that Clippy should not lint.
+ ///
+ /// ### Why is this bad?
+ /// This doesn't actually compare file extensions. Rather, `ends_with` compares the given argument
+ /// to the last **component** of the path and checks if it matches exactly.
+ ///
+ /// ### Known issues
+ /// File extensions are often at most three characters long, so this only lints in those cases
+ /// in an attempt to avoid false positives.
+ /// Any extension names longer than that are assumed to likely be real path components and are
+ /// therefore ignored.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # use std::path::Path;
+ /// fn is_markdown(path: &Path) -> bool {
+ /// path.ends_with(".md")
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # use std::path::Path;
+ /// fn is_markdown(path: &Path) -> bool {
+ /// path.extension().is_some_and(|ext| ext == "md")
+ /// }
+ /// ```
+ #[clippy::version = "1.74.0"]
+ pub PATH_ENDS_WITH_EXT,
+ suspicious,
+ "attempting to compare file extensions using `Path::ends_with`"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for usage of `as_str()` on a `String`` chained with a method available on the `String` itself.
+ ///
+ /// ### Why is this bad?
+ /// The `as_str()` conversion is pointless and can be removed for simplicity and cleanliness.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # #![allow(unused)]
+ /// let owned_string = "This is a string".to_owned();
+ /// owned_string.as_str().as_bytes();
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// # #![allow(unused)]
+ /// let owned_string = "This is a string".to_owned();
+ /// owned_string.as_bytes();
+ /// ```
+ #[clippy::version = "1.74.0"]
+ pub REDUNDANT_AS_STR,
+ complexity,
+ "`as_str` used to call a method on `str` that is also available on `String`"
+}
+
pub struct Methods {
avoid_breaking_exported_api: bool,
msrv: Msrv,
allow_expect_in_tests: bool,
allow_unwrap_in_tests: bool,
+ allowed_dotfiles: FxHashSet<String>,
}
impl Methods {
@@ -3552,12 +3646,14 @@ impl Methods {
msrv: Msrv,
allow_expect_in_tests: bool,
allow_unwrap_in_tests: bool,
+ allowed_dotfiles: FxHashSet<String>,
) -> Self {
Self {
avoid_breaking_exported_api,
msrv,
allow_expect_in_tests,
allow_unwrap_in_tests,
+ allowed_dotfiles,
}
}
}
@@ -3676,7 +3772,10 @@ impl_lint_pass!(Methods => [
STRING_LIT_CHARS_ANY,
ITER_SKIP_ZERO,
FILTER_MAP_BOOL_THEN,
- READONLY_WRITE_LOCK
+ READONLY_WRITE_LOCK,
+ ITER_OUT_OF_BOUNDS,
+ PATH_ENDS_WITH_EXT,
+ REDUNDANT_AS_STR,
]);
/// Extracts a method call name, args, and `Span` of the method name.
@@ -3826,18 +3925,20 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if_chain! {
if let TraitItemKind::Fn(ref sig, _) = item.kind;
if sig.decl.implicit_self.has_implicit_self();
- if let Some(first_arg_ty) = sig.decl.inputs.iter().next();
-
+ if let Some(first_arg_hir_ty) = sig.decl.inputs.first();
+ if let Some(&first_arg_ty) = cx.tcx.fn_sig(item.owner_id)
+ .instantiate_identity()
+ .inputs()
+ .skip_binder()
+ .first();
then {
- let first_arg_span = first_arg_ty.span;
- let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty();
wrong_self_convention::check(
cx,
item.ident.name.as_str(),
self_ty,
first_arg_ty,
- first_arg_span,
+ first_arg_hir_ty.span,
false,
true,
);
@@ -3873,6 +3974,12 @@ impl Methods {
("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
zst_offset::check(cx, expr, recv);
},
+ ("all", [arg]) => {
+ if let Some(("cloned", recv2, [], _, _)) = method_call(recv) {
+ iter_overeager_cloned::check(cx, expr, recv, recv2,
+ iter_overeager_cloned::Op::NeedlessMove(name, arg), false);
+ }
+ }
("and_then", [arg]) => {
let biom_option_linted = bind_instead_of_map::OptionAndThenSome::check(cx, expr, recv, arg);
let biom_result_linted = bind_instead_of_map::ResultAndThenOk::check(cx, expr, recv, arg);
@@ -3880,12 +3987,16 @@ impl Methods {
unnecessary_lazy_eval::check(cx, expr, recv, arg, "and");
}
},
- ("any", [arg]) if let ExprKind::Closure(arg) = arg.kind
- && let body = cx.tcx.hir().body(arg.body)
- && let [param] = body.params
- && let Some(("chars", recv, _, _, _)) = method_call(recv) =>
- {
- string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv);
+ ("any", [arg]) => {
+ match method_call(recv) {
+ Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::NeedlessMove(name, arg), false),
+ Some(("chars", recv, _, _, _)) if let ExprKind::Closure(arg) = arg.kind
+ && let body = cx.tcx.hir().body(arg.body)
+ && let [param] = body.params => {
+ string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv);
+ }
+ _ => {}
+ }
}
("arg", [arg]) => {
suspicious_command_arg_space::check(cx, recv, arg, span);
@@ -3893,6 +4004,7 @@ impl Methods {
("as_deref" | "as_deref_mut", []) => {
needless_option_as_deref::check(cx, expr, recv, name);
},
+ ("as_bytes" | "is_empty", []) => if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) { redundant_as_str::check(cx, expr, recv, as_str_span, span); },
("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
@@ -3919,7 +4031,7 @@ impl Methods {
}
},
("count", []) if is_trait_method(cx, expr, sym::Iterator) => match method_call(recv) {
- Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, true, false),
+ Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::RmCloned , false),
Some((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _, _)) => {
iter_count::check(cx, expr, recv2, name2);
},
@@ -3942,6 +4054,7 @@ impl Methods {
if let ExprKind::MethodCall(.., span) = expr.kind {
case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg);
}
+ path_ends_with_ext::check(cx, recv, arg, expr, &self.msrv, &self.allowed_dotfiles);
},
("expect", [_]) => {
match method_call(recv) {
@@ -3973,6 +4086,13 @@ impl Methods {
string_extend_chars::check(cx, expr, recv, arg);
extend_with_drain::check(cx, expr, recv, arg);
},
+ (name @ ( "filter" | "find" ) , [arg]) => {
+ if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) {
+ // if `arg` has side-effect, the semantic will change
+ iter_overeager_cloned::check(cx, expr, recv, recv2,
+ iter_overeager_cloned::Op::FixClosure(name, arg), false);
+ }
+ }
("filter_map", [arg]) => {
unnecessary_filter_map::check(cx, expr, arg, name);
filter_map_bool_then::check(cx, expr, arg, call_span);
@@ -3987,16 +4107,18 @@ impl Methods {
},
("flatten", []) => match method_call(recv) {
Some(("map", recv, [map_arg], map_span, _)) => map_flatten::check(cx, expr, recv, map_arg, map_span),
- Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, true),
+ Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::LaterCloned , true),
_ => {},
},
("fold", [init, acc]) => {
manual_try_fold::check(cx, expr, init, acc, call_span, &self.msrv);
unnecessary_fold::check(cx, expr, init, acc, span);
},
- ("for_each", [_]) => {
- if let Some(("inspect", _, [_], span2, _)) = method_call(recv) {
- inspect_for_each::check(cx, expr, span2);
+ ("for_each", [arg]) => {
+ match method_call(recv) {
+ Some(("inspect", _, [_], span2, _)) => inspect_for_each::check(cx, expr, span2),
+ Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::NeedlessMove(name, arg), false),
+ _ => {}
}
},
("get", [arg]) => {
@@ -4021,7 +4143,8 @@ impl Methods {
},
("last", []) => {
if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) {
- iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
+ iter_overeager_cloned::check(cx, expr, recv, recv2,
+ iter_overeager_cloned::Op::LaterCloned , false);
}
},
("lock", []) => {
@@ -4030,8 +4153,10 @@ impl Methods {
(name @ ("map" | "map_err"), [m_arg]) => {
if name == "map" {
map_clone::check(cx, expr, recv, m_arg, &self.msrv);
- if let Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) = method_call(recv) {
- iter_kv_map::check(cx, map_name, expr, recv2, m_arg);
+ match method_call(recv) {
+ Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => iter_kv_map::check(cx, map_name, expr, recv2, m_arg),
+ Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::NeedlessMove(name, m_arg), false),
+ _ => {}
}
} else {
map_err_ignore::check(cx, expr, m_arg);
@@ -4058,7 +4183,7 @@ impl Methods {
("next", []) => {
if let Some((name2, recv2, args2, _, _)) = method_call(recv) {
match (name2, args2) {
- ("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
+ ("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::LaterCloned, false),
("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, &self.msrv),
("iter", []) => iter_next_slice::check(cx, expr, recv2),
@@ -4071,7 +4196,7 @@ impl Methods {
},
("nth", [n_arg]) => match method_call(recv) {
Some(("bytes", recv2, [], _, _)) => bytes_nth::check(cx, expr, recv2, n_arg),
- Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
+ Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::LaterCloned , false),
Some(("iter", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, false),
Some(("iter_mut", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, true),
_ => iter_nth_zero::check(cx, expr, recv, n_arg),
@@ -4124,9 +4249,11 @@ impl Methods {
},
("skip", [arg]) => {
iter_skip_zero::check(cx, expr, arg);
+ iter_out_of_bounds::check_skip(cx, expr, recv, arg);
if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) {
- iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
+ iter_overeager_cloned::check(cx, expr, recv, recv2,
+ iter_overeager_cloned::Op::LaterCloned , false);
}
}
("sort", []) => {
@@ -4150,9 +4277,11 @@ impl Methods {
}
},
("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
- ("take", [_arg]) => {
+ ("take", [arg]) => {
+ iter_out_of_bounds::check_take(cx, expr, recv, arg);
if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) {
- iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
+ iter_overeager_cloned::check(cx, expr, recv, recv2,
+ iter_overeager_cloned::Op::LaterCloned, false);
}
},
("take", []) => needless_option_take::check(cx, expr, recv),
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 8b2f57160..942f3bd79 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -65,11 +65,26 @@ pub(super) fn check<'tcx>(
};
let sugg = match (name, call_expr.is_some()) {
- ("unwrap_or", true) | ("unwrap_or_else", false) => "unwrap_or_default",
- ("or_insert", true) | ("or_insert_with", false) => "or_default",
+ ("unwrap_or", true) | ("unwrap_or_else", false) => sym!(unwrap_or_default),
+ ("or_insert", true) | ("or_insert_with", false) => sym!(or_default),
_ => return false,
};
+ let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs();
+ let has_suggested_method = receiver_ty.ty_adt_def().is_some_and(|adt_def| {
+ cx.tcx
+ .inherent_impls(adt_def.did())
+ .iter()
+ .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
+ .any(|assoc| {
+ assoc.fn_has_self_parameter
+ && cx.tcx.fn_sig(assoc.def_id).skip_binder().inputs().skip_binder().len() == 1
+ })
+ });
+ if !has_suggested_method {
+ return false;
+ }
+
// needs to target Default::default in particular or be *::new and have a Default impl
// available
if (is_new(fun) && output_type_implements_default(fun))
diff --git a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
new file mode 100644
index 000000000..3347c8c16
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
@@ -0,0 +1,53 @@
+use super::PATH_ENDS_WITH_EXT;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs;
+use clippy_utils::msrvs::Msrv;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_ast::{LitKind, StrStyle};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+use std::fmt::Write;
+
+pub const DEFAULT_ALLOWED_DOTFILES: &[&str] = &[
+ "git", "svn", "gem", "npm", "vim", "env", "rnd", "ssh", "vnc", "smb", "nvm", "bin",
+];
+
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ recv: &Expr<'_>,
+ path: &Expr<'_>,
+ expr: &Expr<'_>,
+ msrv: &Msrv,
+ allowed_dotfiles: &FxHashSet<String>,
+) {
+ if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv).peel_refs(), sym::Path)
+ && !path.span.from_expansion()
+ && let ExprKind::Lit(lit) = path.kind
+ && let LitKind::Str(path, StrStyle::Cooked) = lit.node
+ && let Some(path) = path.as_str().strip_prefix('.')
+ && (1..=3).contains(&path.len())
+ && !allowed_dotfiles.contains(path)
+ && path.chars().all(char::is_alphanumeric)
+ {
+ let mut sugg = snippet(cx, recv.span, "..").into_owned();
+ if msrv.meets(msrvs::OPTION_IS_SOME_AND) {
+ let _ = write!(sugg, r#".extension().is_some_and(|ext| ext == "{path}")"#);
+ } else {
+ let _ = write!(sugg, r#".extension().map_or(false, |ext| ext == "{path}")"#);
+ };
+
+ span_lint_and_sugg(
+ cx,
+ PATH_ENDS_WITH_EXT,
+ expr.span,
+ "this looks like a failed attempt at checking for the file extension",
+ "try",
+ sugg,
+ Applicability::MaybeIncorrect
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs b/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs
new file mode 100644
index 000000000..98cd6afc2
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs
@@ -0,0 +1,34 @@
+use super::REDUNDANT_AS_STR;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_middle::query::Key;
+use rustc_span::Span;
+
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ _expr: &Expr<'_>,
+ recv: &Expr<'_>,
+ as_str_span: Span,
+ other_method_span: Span,
+) {
+ if cx
+ .tcx
+ .lang_items()
+ .string()
+ .is_some_and(|id| Some(id) == cx.typeck_results().expr_ty(recv).ty_adt_id())
+ {
+ let mut applicability = Applicability::MachineApplicable;
+ span_lint_and_sugg(
+ cx,
+ REDUNDANT_AS_STR,
+ as_str_span.to(other_method_span),
+ "this `as_str` is redundant and can be removed as the method immediately following exists on `String` too",
+ "try",
+ snippet_with_applicability(cx, other_method_span, "..", &mut applicability).into_owned(),
+ applicability,
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 5c5ee2620..50d6f3b7e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -401,7 +401,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
= get_callee_generic_args_and_args(cx, parent_expr)
{
// FIXME: the `instantiate_identity()` below seems incorrect, since we eventually
- // call `tcx.try_subst_and_normalize_erasing_regions` further down
+ // call `tcx.try_instantiate_and_normalize_erasing_regions` further down
// (i.e., we are explicitly not in the identity context).
let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
@@ -452,7 +452,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
let output_ty = fn_sig.output();
if output_ty.contains(*param_ty) {
- if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions(
+ if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions(
new_subst, cx.param_env, EarlyBinder::bind(output_ty)) {
expr = parent_expr;
ty = new_ty;
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index 303f01256..9c8b47fb3 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -1,24 +1,22 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::source::{snippet, snippet_opt, snippet_with_context};
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::source::{snippet, snippet_with_context};
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{
+ any_parent_is_automatically_derived, fulfill_or_allowed, get_parent_expr, is_lint_allowed, iter_input_pats,
+ last_path_segment, SpanlessEq,
+};
use if_chain::if_chain;
use rustc_errors::Applicability;
+use rustc_hir::def::Res;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{
- self as hir, def, BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, Stmt,
- StmtKind, TyKind,
+ BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::def_id::LocalDefId;
-use rustc_span::hygiene::DesugaringKind;
-use rustc_span::source_map::{ExpnKind, Span};
-
-use clippy_utils::sugg::Sugg;
-use clippy_utils::{
- get_parent_expr, in_constant, is_integer_literal, is_lint_allowed, is_no_std_crate, iter_input_pats,
- last_path_segment, SpanlessEq,
-};
+use rustc_span::source_map::Span;
use crate::ref_patterns::REF_PATTERNS;
@@ -56,6 +54,7 @@ declare_clippy_lint! {
style,
"an entire binding declared as `ref`, in a function argument or a `let` statement"
}
+
declare_clippy_lint! {
/// ### What it does
/// Checks for the use of bindings with a single leading
@@ -103,51 +102,13 @@ declare_clippy_lint! {
"using a short circuit boolean condition as a statement"
}
-declare_clippy_lint! {
- /// ### What it does
- /// Catch casts from `0` to some pointer type
- ///
- /// ### Why is this bad?
- /// This generally means `null` and is better expressed as
- /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
- ///
- /// ### Example
- /// ```rust
- /// let a = 0 as *const u32;
- /// ```
- ///
- /// Use instead:
- /// ```rust
- /// let a = std::ptr::null::<u32>();
- /// ```
- #[clippy::version = "pre 1.29.0"]
- pub ZERO_PTR,
- style,
- "using `0 as *{const, mut} T`"
-}
-
-pub struct LintPass {
- std_or_core: &'static str,
-}
-impl Default for LintPass {
- fn default() -> Self {
- Self { std_or_core: "std" }
- }
-}
-impl_lint_pass!(LintPass => [
+declare_lint_pass!(LintPass => [
TOPLEVEL_REF_ARG,
USED_UNDERSCORE_BINDING,
SHORT_CIRCUIT_STATEMENT,
- ZERO_PTR,
]);
impl<'tcx> LateLintPass<'tcx> for LintPass {
- fn check_crate(&mut self, cx: &LateContext<'_>) {
- if is_no_std_crate(cx) {
- self.std_or_core = "core";
- }
- }
-
fn check_fn(
&mut self,
cx: &LateContext<'tcx>,
@@ -253,50 +214,56 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if let ExprKind::Cast(e, ty) = expr.kind {
- self.check_cast(cx, expr.span, e, ty);
- return;
- }
- if in_attributes_expansion(expr) || expr.span.is_desugaring(DesugaringKind::Await) {
- // Don't lint things expanded by #[derive(...)], etc or `await` desugaring
+ if in_external_macro(cx.sess(), expr.span)
+ || expr.span.desugaring_kind().is_some()
+ || any_parent_is_automatically_derived(cx.tcx, expr.hir_id)
+ {
return;
}
- let sym;
- let binding = match expr.kind {
- ExprKind::Path(ref qpath) if !matches!(qpath, hir::QPath::LangItem(..)) => {
- let binding = last_path_segment(qpath).ident.as_str();
- if binding.starts_with('_') &&
- !binding.starts_with("__") &&
- binding != "_result" && // FIXME: #944
- is_used(cx, expr) &&
- // don't lint if the declaration is in a macro
- non_macro_local(cx, cx.qpath_res(qpath, expr.hir_id))
+ let (definition_hir_id, ident) = match expr.kind {
+ ExprKind::Path(ref qpath) => {
+ if let QPath::Resolved(None, path) = qpath
+ && let Res::Local(id) = path.res
+ && is_used(cx, expr)
{
- Some(binding)
+ (id, last_path_segment(qpath).ident)
} else {
- None
+ return;
}
},
- ExprKind::Field(_, ident) => {
- sym = ident.name;
- let name = sym.as_str();
- if name.starts_with('_') && !name.starts_with("__") {
- Some(name)
+ ExprKind::Field(recv, ident) => {
+ if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def()
+ && let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name)
+ && let Some(local_did) = field.did.as_local()
+ && let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(local_did)
+ && !cx.tcx.type_of(field.did).skip_binder().is_phantom_data()
+ {
+ (hir_id, ident)
} else {
- None
+ return;
}
},
- _ => None,
+ _ => return,
};
- if let Some(binding) = binding {
- span_lint(
+
+ let name = ident.name.as_str();
+ if name.starts_with('_')
+ && !name.starts_with("__")
+ && let definition_span = cx.tcx.hir().span(definition_hir_id)
+ && !definition_span.from_expansion()
+ && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id])
+ {
+ span_lint_and_then(
cx,
USED_UNDERSCORE_BINDING,
expr.span,
&format!(
- "used binding `{binding}` which is prefixed with an underscore. A leading \
+ "used binding `{name}` which is prefixed with an underscore. A leading \
underscore signals that a binding will not be used"
),
+ |diag| {
+ diag.span_note(definition_span, format!("`{name}` is defined here"));
+ }
);
}
}
@@ -311,50 +278,3 @@ fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
_ => is_used(cx, parent),
})
}
-
-/// Tests whether an expression is in a macro expansion (e.g., something
-/// generated by `#[derive(...)]` or the like).
-fn in_attributes_expansion(expr: &Expr<'_>) -> bool {
- use rustc_span::hygiene::MacroKind;
- if expr.span.from_expansion() {
- let data = expr.span.ctxt().outer_expn_data();
- matches!(data.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, _))
- } else {
- false
- }
-}
-
-/// Tests whether `res` is a variable defined outside a macro.
-fn non_macro_local(cx: &LateContext<'_>, res: def::Res) -> bool {
- if let def::Res::Local(id) = res {
- !cx.tcx.hir().span(id).from_expansion()
- } else {
- false
- }
-}
-
-impl LintPass {
- fn check_cast(&self, cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
- if_chain! {
- if let TyKind::Ptr(ref mut_ty) = ty.kind;
- if is_integer_literal(e, 0);
- if !in_constant(cx, e.hir_id);
- then {
- let (msg, sugg_fn) = match mut_ty.mutbl {
- Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
- Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
- };
-
- let (sugg, appl) = if let TyKind::Infer = mut_ty.ty.kind {
- (format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MachineApplicable)
- } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
- (format!("{}::{sugg_fn}::<{mut_ty_snip}>()", self.std_or_core), Applicability::MachineApplicable)
- } else {
- // `MaybeIncorrect` as type inference may not work with the suggested code
- (format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MaybeIncorrect)
- };
- span_lint_and_sugg(cx, ZERO_PTR, span, msg, "try", sugg, appl);
- }
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
new file mode 100644
index 000000000..08fec2b8e
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
@@ -0,0 +1,391 @@
+use std::mem;
+use std::ops::ControlFlow;
+
+use clippy_utils::comparisons::{normalize_comparison, Rel};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet;
+use clippy_utils::visitors::for_each_expr;
+use clippy_utils::{eq_expr_value, hash_expr, higher};
+use rustc_ast::{LitKind, RangeLimits};
+use rustc_data_structures::unhash::UnhashMap;
+use rustc_errors::{Applicability, Diagnostic};
+use rustc_hir::{BinOp, Block, Expr, ExprKind, UnOp};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::source_map::Spanned;
+use rustc_span::{sym, Span};
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for repeated slice indexing without asserting beforehand that the length
+ /// is greater than the largest index used to index into the slice.
+ ///
+ /// ### Why is this bad?
+ /// In the general case where the compiler does not have a lot of information
+ /// about the length of a slice, indexing it repeatedly will generate a bounds check
+ /// for every single index.
+ ///
+ /// Asserting that the length of the slice is at least as large as the largest value
+ /// to index beforehand gives the compiler enough information to elide the bounds checks,
+ /// effectively reducing the number of bounds checks from however many times
+ /// the slice was indexed to just one (the assert).
+ ///
+ /// ### Drawbacks
+ /// False positives. It is, in general, very difficult to predict how well
+ /// the optimizer will be able to elide bounds checks and it very much depends on
+ /// the surrounding code. For example, indexing into the slice yielded by the
+ /// [`slice::chunks_exact`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.chunks_exact)
+ /// iterator will likely have all of the bounds checks elided even without an assert
+ /// if the `chunk_size` is a constant.
+ ///
+ /// Asserts are not tracked across function calls. Asserting the length of a slice
+ /// in a different function likely gives the optimizer enough information
+ /// about the length of a slice, but this lint will not detect that.
+ ///
+ /// ### Example
+ /// ```rust
+ /// fn sum(v: &[u8]) -> u8 {
+ /// // 4 bounds checks
+ /// v[0] + v[1] + v[2] + v[3]
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// fn sum(v: &[u8]) -> u8 {
+ /// assert!(v.len() > 4);
+ /// // no bounds checks
+ /// v[0] + v[1] + v[2] + v[3]
+ /// }
+ /// ```
+ #[clippy::version = "1.70.0"]
+ pub MISSING_ASSERTS_FOR_INDEXING,
+ restriction,
+ "indexing into a slice multiple times without an `assert`"
+}
+declare_lint_pass!(MissingAssertsForIndexing => [MISSING_ASSERTS_FOR_INDEXING]);
+
+fn report_lint<F>(cx: &LateContext<'_>, full_span: Span, msg: &str, indexes: &[Span], f: F)
+where
+ F: FnOnce(&mut Diagnostic),
+{
+ span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, full_span, msg, |diag| {
+ f(diag);
+ for span in indexes {
+ diag.span_note(*span, "slice indexed here");
+ }
+ diag.note("asserting the length before indexing will elide bounds checks");
+ });
+}
+
+#[derive(Copy, Clone, Debug)]
+enum LengthComparison {
+ /// `v.len() < 5`
+ LengthLessThanInt,
+ /// `5 < v.len()`
+ IntLessThanLength,
+ /// `v.len() <= 5`
+ LengthLessThanOrEqualInt,
+ /// `5 <= v.len()`
+ IntLessThanOrEqualLength,
+}
+
+/// Extracts parts out of a length comparison expression.
+///
+/// E.g. for `v.len() > 5` this returns `Some((LengthComparison::IntLessThanLength, 5, `v.len()`))`
+fn len_comparison<'hir>(
+ bin_op: BinOp,
+ left: &'hir Expr<'hir>,
+ right: &'hir Expr<'hir>,
+) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> {
+ macro_rules! int_lit_pat {
+ ($id:ident) => {
+ ExprKind::Lit(Spanned {
+ node: LitKind::Int($id, _),
+ ..
+ })
+ };
+ }
+
+ // normalize comparison, `v.len() > 4` becomes `4 < v.len()`
+ // this simplifies the logic a bit
+ let (op, left, right) = normalize_comparison(bin_op.node, left, right)?;
+ match (op, &left.kind, &right.kind) {
+ (Rel::Lt, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanLength, *left as usize, right)),
+ (Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, *right as usize, left)),
+ (Rel::Le, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanOrEqualLength, *left as usize, right)),
+ (Rel::Le, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanOrEqualInt, *right as usize, left)),
+ _ => None,
+ }
+}
+
+/// Attempts to extract parts out of an `assert!`-like expression
+/// in the form `assert!(some_slice.len() > 5)`.
+///
+/// `assert!` has expanded to an if expression at the HIR, so this
+/// actually works not just with `assert!` specifically, but anything
+/// that has a never type expression in the `then` block (e.g. `panic!`).
+fn assert_len_expr<'hir>(
+ cx: &LateContext<'_>,
+ expr: &'hir Expr<'hir>,
+) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> {
+ if let Some(higher::If { cond, then, .. }) = higher::If::hir(expr)
+ && let ExprKind::Unary(UnOp::Not, condition) = &cond.kind
+ && let ExprKind::Binary(bin_op, left, right) = &condition.kind
+
+ && let Some((cmp, asserted_len, slice_len)) = len_comparison(*bin_op, left, right)
+ && let ExprKind::MethodCall(method, recv, ..) = &slice_len.kind
+ && cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice()
+ && method.ident.name == sym::len
+
+ // check if `then` block has a never type expression
+ && let ExprKind::Block(Block { expr: Some(then_expr), .. }, _) = then.kind
+ && cx.typeck_results().expr_ty(then_expr).is_never()
+ {
+ Some((cmp, asserted_len, recv))
+ } else {
+ None
+ }
+}
+
+#[derive(Debug)]
+enum IndexEntry<'hir> {
+ /// `assert!` without any indexing (so far)
+ StrayAssert {
+ asserted_len: usize,
+ comparison: LengthComparison,
+ assert_span: Span,
+ slice: &'hir Expr<'hir>,
+ },
+ /// `assert!` with indexing
+ ///
+ /// We also store the highest index to be able to check
+ /// if the `assert!` asserts the right length.
+ AssertWithIndex {
+ highest_index: usize,
+ asserted_len: usize,
+ assert_span: Span,
+ slice: &'hir Expr<'hir>,
+ indexes: Vec<Span>,
+ comparison: LengthComparison,
+ },
+ /// Indexing without an `assert!`
+ IndexWithoutAssert {
+ highest_index: usize,
+ indexes: Vec<Span>,
+ slice: &'hir Expr<'hir>,
+ },
+}
+
+impl<'hir> IndexEntry<'hir> {
+ pub fn slice(&self) -> &'hir Expr<'hir> {
+ match self {
+ IndexEntry::StrayAssert { slice, .. }
+ | IndexEntry::AssertWithIndex { slice, .. }
+ | IndexEntry::IndexWithoutAssert { slice, .. } => slice,
+ }
+ }
+
+ pub fn index_spans(&self) -> Option<&[Span]> {
+ match self {
+ IndexEntry::StrayAssert { .. } => None,
+ IndexEntry::AssertWithIndex { indexes, .. } | IndexEntry::IndexWithoutAssert { indexes, .. } => {
+ Some(indexes)
+ },
+ }
+ }
+}
+
+/// Extracts the upper index of a slice indexing expression.
+///
+/// E.g. for `5` this returns `Some(5)`, for `..5` this returns `Some(4)`,
+/// for `..=5` this returns `Some(5)`
+fn upper_index_expr(expr: &Expr<'_>) -> Option<usize> {
+ if let ExprKind::Lit(lit) = &expr.kind && let LitKind::Int(index, _) = lit.node {
+ Some(index as usize)
+ } else if let Some(higher::Range { end: Some(end), limits, .. }) = higher::Range::hir(expr)
+ && let ExprKind::Lit(lit) = &end.kind
+ && let LitKind::Int(index @ 1.., _) = lit.node
+ {
+ match limits {
+ RangeLimits::HalfOpen => Some(index as usize - 1),
+ RangeLimits::Closed => Some(index as usize),
+ }
+ } else {
+ None
+ }
+}
+
+/// Checks if the expression is an index into a slice and adds it to `indexes`
+fn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut UnhashMap<u64, Vec<IndexEntry<'hir>>>) {
+ if let ExprKind::Index(slice, index_lit, _) = expr.kind
+ && cx.typeck_results().expr_ty_adjusted(slice).peel_refs().is_slice()
+ && let Some(index) = upper_index_expr(index_lit)
+ {
+ let hash = hash_expr(cx, slice);
+
+ let indexes = map.entry(hash).or_default();
+ let entry = indexes.iter_mut().find(|entry| eq_expr_value(cx, entry.slice(), slice));
+
+ if let Some(entry) = entry {
+ match entry {
+ IndexEntry::StrayAssert { asserted_len, comparison, assert_span, slice } => {
+ *entry = IndexEntry::AssertWithIndex {
+ highest_index: index,
+ asserted_len: *asserted_len,
+ assert_span: *assert_span,
+ slice,
+ indexes: vec![expr.span],
+ comparison: *comparison,
+ };
+ },
+ IndexEntry::IndexWithoutAssert { highest_index, indexes, .. }
+ | IndexEntry::AssertWithIndex { highest_index, indexes, .. } => {
+ indexes.push(expr.span);
+ *highest_index = (*highest_index).max(index);
+ },
+ }
+ } else {
+ indexes.push(IndexEntry::IndexWithoutAssert {
+ highest_index: index,
+ indexes: vec![expr.span],
+ slice,
+ });
+ }
+ }
+}
+
+/// Checks if the expression is an `assert!` expression and adds it to `asserts`
+fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut UnhashMap<u64, Vec<IndexEntry<'hir>>>) {
+ if let Some((comparison, asserted_len, slice)) = assert_len_expr(cx, expr) {
+ let hash = hash_expr(cx, slice);
+ let indexes = map.entry(hash).or_default();
+
+ let entry = indexes.iter_mut().find(|entry| eq_expr_value(cx, entry.slice(), slice));
+
+ if let Some(entry) = entry {
+ if let IndexEntry::IndexWithoutAssert {
+ highest_index,
+ indexes,
+ slice,
+ } = entry
+ {
+ *entry = IndexEntry::AssertWithIndex {
+ highest_index: *highest_index,
+ indexes: mem::take(indexes),
+ slice,
+ assert_span: expr.span,
+ comparison,
+ asserted_len,
+ };
+ }
+ } else {
+ indexes.push(IndexEntry::StrayAssert {
+ asserted_len,
+ comparison,
+ assert_span: expr.span,
+ slice,
+ });
+ }
+ }
+}
+
+/// Inspects indexes and reports lints.
+///
+/// Called at the end of this lint after all indexing and `assert!` expressions have been collected.
+fn report_indexes(cx: &LateContext<'_>, map: &UnhashMap<u64, Vec<IndexEntry<'_>>>) {
+ for bucket in map.values() {
+ for entry in bucket {
+ let Some(full_span) = entry
+ .index_spans()
+ .and_then(|spans| spans.first().zip(spans.last()))
+ .map(|(low, &high)| low.to(high))
+ else {
+ continue;
+ };
+
+ match entry {
+ IndexEntry::AssertWithIndex {
+ highest_index,
+ asserted_len,
+ indexes,
+ comparison,
+ assert_span,
+ slice,
+ } if indexes.len() > 1 => {
+ // if we have found an `assert!`, let's also check that it's actually right
+ // and if it convers the highest index and if not, suggest the correct length
+ let sugg = match comparison {
+ // `v.len() < 5` and `v.len() <= 5` does nothing in terms of bounds checks.
+ // The user probably meant `v.len() > 5`
+ LengthComparison::LengthLessThanInt | LengthComparison::LengthLessThanOrEqualInt => Some(
+ format!("assert!({}.len() > {highest_index})", snippet(cx, slice.span, "..")),
+ ),
+ // `5 < v.len()` == `v.len() > 5`
+ LengthComparison::IntLessThanLength if asserted_len < highest_index => Some(format!(
+ "assert!({}.len() > {highest_index})",
+ snippet(cx, slice.span, "..")
+ )),
+ // `5 <= v.len() == `v.len() >= 5`
+ LengthComparison::IntLessThanOrEqualLength if asserted_len <= highest_index => Some(format!(
+ "assert!({}.len() > {highest_index})",
+ snippet(cx, slice.span, "..")
+ )),
+ _ => None,
+ };
+
+ if let Some(sugg) = sugg {
+ report_lint(
+ cx,
+ full_span,
+ "indexing into a slice multiple times with an `assert` that does not cover the highest index",
+ indexes,
+ |diag| {
+ diag.span_suggestion(
+ *assert_span,
+ "provide the highest index that is indexed with",
+ sugg,
+ Applicability::MachineApplicable,
+ );
+ },
+ );
+ }
+ },
+ IndexEntry::IndexWithoutAssert {
+ indexes,
+ highest_index,
+ slice,
+ } if indexes.len() > 1 => {
+ // if there was no `assert!` but more than one index, suggest
+ // adding an `assert!` that covers the highest index
+ report_lint(
+ cx,
+ full_span,
+ "indexing into a slice multiple times without an `assert`",
+ indexes,
+ |diag| {
+ diag.help(format!(
+ "consider asserting the length before indexing: `assert!({}.len() > {highest_index});`",
+ snippet(cx, slice.span, "..")
+ ));
+ },
+ );
+ },
+ _ => {},
+ }
+ }
+ }
+}
+
+impl LateLintPass<'_> for MissingAssertsForIndexing {
+ fn check_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {
+ let mut map = UnhashMap::default();
+
+ for_each_expr(block, |expr| {
+ check_index(cx, expr, &mut map);
+ check_assert(cx, expr, &mut map);
+ ControlFlow::<!, ()>::Continue(())
+ });
+
+ report_indexes(cx, &map);
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 3b7eccad7..f598a65d2 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -7,7 +7,6 @@ use rustc_hir as hir;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -124,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
FnKind::Method(_, sig, ..) => {
if trait_ref_of_method(cx, def_id).is_some()
|| already_const(sig.header)
- || method_accepts_droppable(cx, sig.decl.inputs)
+ || method_accepts_droppable(cx, def_id)
{
return;
}
@@ -165,12 +164,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
/// Returns true if any of the method parameters is a type that implements `Drop`. The method
/// can't be made const then, because `drop` can't be const-evaluated.
-fn method_accepts_droppable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool {
+fn method_accepts_droppable(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
+ let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+
// If any of the params are droppable, return true
- param_tys.iter().any(|hir_ty| {
- let ty_ty = hir_ty_to_ty(cx.tcx, hir_ty);
- has_drop(cx, ty_ty)
- })
+ sig.inputs().iter().any(|&ty| has_drop(cx, ty))
}
// We don't have to lint on something that's already `const`
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
new file mode 100644
index 000000000..d55c77a92
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -0,0 +1,410 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::snippet_with_context;
+use clippy_utils::ty::is_copy;
+use clippy_utils::{expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy, ExprUseNode};
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::{Body, Expr, ExprKind, Mutability, Path, QPath};
+use rustc_index::bit_set::BitSet;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::mir::{Rvalue, StatementKind};
+use rustc_middle::ty::{
+ self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, List, ParamTy, ProjectionPredicate, Ty,
+};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::symbol::sym;
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
+use rustc_trait_selection::traits::{Obligation, ObligationCause};
+use std::collections::VecDeque;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for borrow operations (`&`) that used as a generic argument to a
+ /// function when the borrowed value could be used.
+ ///
+ /// ### Why is this bad?
+ /// Suggests that the receiver of the expression borrows
+ /// the expression.
+ ///
+ /// ### Known problems
+ /// The lint cannot tell when the implementation of a trait
+ /// for `&T` and `T` do different things. Removing a borrow
+ /// in such a case can change the semantics of the code.
+ ///
+ /// ### Example
+ /// ```rust
+ /// fn f(_: impl AsRef<str>) {}
+ ///
+ /// let x = "foo";
+ /// f(&x);
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// fn f(_: impl AsRef<str>) {}
+ ///
+ /// let x = "foo";
+ /// f(x);
+ /// ```
+ #[clippy::version = "pre 1.29.0"]
+ pub NEEDLESS_BORROWS_FOR_GENERIC_ARGS,
+ style,
+ "taking a reference that is going to be automatically dereferenced"
+}
+
+pub struct NeedlessBorrowsForGenericArgs<'tcx> {
+ /// Stack of (body owner, `PossibleBorrowerMap`) pairs. Used by
+ /// `needless_borrow_impl_arg_position` to determine when a borrowed expression can instead
+ /// be moved.
+ possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+
+ // `IntoIterator` for arrays requires Rust 1.53.
+ msrv: Msrv,
+}
+impl_lint_pass!(NeedlessBorrowsForGenericArgs<'_> => [NEEDLESS_BORROWS_FOR_GENERIC_ARGS]);
+
+impl NeedlessBorrowsForGenericArgs<'_> {
+ #[must_use]
+ pub fn new(msrv: Msrv) -> Self {
+ Self {
+ possible_borrowers: Vec::new(),
+ msrv,
+ }
+ }
+}
+
+impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+ if matches!(expr.kind, ExprKind::AddrOf(..))
+ && !expr.span.from_expansion()
+ && let Some(use_cx) = expr_use_ctxt(cx, expr)
+ && !use_cx.is_ty_unified
+ && let Some(DefinedTy::Mir(ty)) = use_cx.node.defined_ty(cx)
+ && let ty::Param(ty) = *ty.value.skip_binder().kind()
+ && let Some((hir_id, fn_id, i)) = match use_cx.node {
+ ExprUseNode::MethodArg(_, _, 0) => None,
+ ExprUseNode::MethodArg(hir_id, None, i) => {
+ cx.typeck_results().type_dependent_def_id(hir_id).map(|id| (hir_id, id, i))
+ },
+ ExprUseNode::FnArg(&Expr { kind: ExprKind::Path(ref p), hir_id, .. }, i)
+ if !path_has_args(p) => match cx.typeck_results().qpath_res(p, hir_id) {
+ Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => {
+ Some((hir_id, id, i))
+ },
+ _ => None,
+ },
+ _ => None,
+ } && let count = needless_borrow_count(
+ cx,
+ &mut self.possible_borrowers,
+ fn_id,
+ cx.typeck_results().node_args(hir_id),
+ i,
+ ty,
+ expr,
+ &self.msrv,
+ ) && count != 0
+ {
+ span_lint_and_then(
+ cx,
+ NEEDLESS_BORROWS_FOR_GENERIC_ARGS,
+ expr.span,
+ "the borrowed expression implements the required traits",
+ |diag| {
+ let mut app = Applicability::MachineApplicable;
+ let snip_span = peel_n_hir_expr_refs(expr, count).0.span;
+ let snip = snippet_with_context(cx, snip_span, expr.span.ctxt(), "..", &mut app).0;
+ diag.span_suggestion(expr.span, "change this to", snip.into_owned(), app);
+ }
+ );
+ }
+ }
+
+ fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
+ if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
+ local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
+ }) {
+ self.possible_borrowers.pop();
+ }
+ }
+
+ extract_msrv_attr!(LateContext);
+}
+
+fn path_has_args(p: &QPath<'_>) -> bool {
+ match *p {
+ QPath::Resolved(_, Path { segments: [.., s], .. }) | QPath::TypeRelative(_, s) => s.args.is_some(),
+ _ => false,
+ }
+}
+
+/// Checks for the number of borrow expressions which can be removed from the given expression
+/// where the expression is used as an argument to a function expecting a generic type.
+///
+/// The following constraints will be checked:
+/// * The borrowed expression meets all the generic type's constraints.
+/// * The generic type appears only once in the functions signature.
+/// * The borrowed value will not be moved if it is used later in the function.
+#[expect(clippy::too_many_arguments)]
+fn needless_borrow_count<'tcx>(
+ cx: &LateContext<'tcx>,
+ possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+ fn_id: DefId,
+ callee_args: &'tcx List<GenericArg<'tcx>>,
+ arg_index: usize,
+ param_ty: ParamTy,
+ mut expr: &Expr<'tcx>,
+ msrv: &Msrv,
+) -> usize {
+ let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
+ let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
+
+ let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
+ let predicates = cx.tcx.param_env(fn_id).caller_bounds();
+ let projection_predicates = predicates
+ .iter()
+ .filter_map(|predicate| {
+ if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
+ Some(projection_predicate)
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>();
+
+ let mut trait_with_ref_mut_self_method = false;
+
+ // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.
+ if predicates
+ .iter()
+ .filter_map(|predicate| {
+ if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+ && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
+ {
+ Some(trait_predicate.trait_ref.def_id)
+ } else {
+ None
+ }
+ })
+ .inspect(|trait_def_id| {
+ trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);
+ })
+ .all(|trait_def_id| {
+ Some(trait_def_id) == destruct_trait_def_id
+ || Some(trait_def_id) == sized_trait_def_id
+ || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
+ })
+ {
+ return 0;
+ }
+
+ // See:
+ // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
+ // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
+ if projection_predicates
+ .iter()
+ .any(|projection_predicate| is_mixed_projection_predicate(cx, fn_id, projection_predicate))
+ {
+ return 0;
+ }
+
+ // `args_with_referent_ty` can be constructed outside of `check_referent` because the same
+ // elements are modified each time `check_referent` is called.
+ let mut args_with_referent_ty = callee_args.to_vec();
+
+ let mut check_reference_and_referent = |reference, referent| {
+ let referent_ty = cx.typeck_results().expr_ty(referent);
+
+ if !is_copy(cx, referent_ty)
+ && (referent_ty.has_significant_drop(cx.tcx, cx.param_env)
+ || !referent_used_exactly_once(cx, possible_borrowers, reference))
+ {
+ return false;
+ }
+
+ // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+ if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
+ return false;
+ }
+
+ if !replace_types(
+ cx,
+ param_ty,
+ referent_ty,
+ fn_sig,
+ arg_index,
+ &projection_predicates,
+ &mut args_with_referent_ty,
+ ) {
+ return false;
+ }
+
+ predicates.iter().all(|predicate| {
+ if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+ && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
+ && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
+ && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack()
+ && ty.is_array()
+ && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
+ {
+ return false;
+ }
+
+ let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
+ let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
+ let infcx = cx.tcx.infer_ctxt().build();
+ infcx.predicate_must_hold_modulo_regions(&obligation)
+ })
+ };
+
+ let mut count = 0;
+ while let ExprKind::AddrOf(_, _, referent) = expr.kind {
+ if !check_reference_and_referent(expr, referent) {
+ break;
+ }
+ expr = referent;
+ count += 1;
+ }
+ count
+}
+
+fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
+ cx.tcx
+ .associated_items(trait_def_id)
+ .in_definition_order()
+ .any(|assoc_item| {
+ if assoc_item.fn_has_self_parameter {
+ let self_ty = cx
+ .tcx
+ .fn_sig(assoc_item.def_id)
+ .instantiate_identity()
+ .skip_binder()
+ .inputs()[0];
+ matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
+ } else {
+ false
+ }
+ })
+}
+
+fn is_mixed_projection_predicate<'tcx>(
+ cx: &LateContext<'tcx>,
+ callee_def_id: DefId,
+ projection_predicate: &ProjectionPredicate<'tcx>,
+) -> bool {
+ let generics = cx.tcx.generics_of(callee_def_id);
+ // The predicate requires the projected type to equal a type parameter from the parent context.
+ if let Some(term_ty) = projection_predicate.term.ty()
+ && let ty::Param(term_param_ty) = term_ty.kind()
+ && (term_param_ty.index as usize) < generics.parent_count
+ {
+ // The inner-most self type is a type parameter from the current function.
+ let mut projection_ty = projection_predicate.projection_ty;
+ loop {
+ match projection_ty.self_ty().kind() {
+ ty::Alias(ty::Projection, inner_projection_ty) => {
+ projection_ty = *inner_projection_ty;
+ }
+ ty::Param(param_ty) => {
+ return (param_ty.index as usize) >= generics.parent_count;
+ }
+ _ => {
+ return false;
+ }
+ }
+ }
+ } else {
+ false
+ }
+}
+
+fn referent_used_exactly_once<'tcx>(
+ cx: &LateContext<'tcx>,
+ possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+ reference: &Expr<'tcx>,
+) -> bool {
+ if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)
+ && let Some(local) = expr_local(cx.tcx, reference)
+ && let [location] = *local_assignments(mir, local).as_slice()
+ && let block_data = &mir.basic_blocks[location.block]
+ && let Some(statement) = block_data.statements.get(location.statement_index)
+ && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
+ && !place.is_indirect_first_projection()
+ {
+ let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
+ if possible_borrowers
+ .last()
+ .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id)
+ {
+ possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));
+ }
+ let possible_borrower = &mut possible_borrowers.last_mut().unwrap().1;
+ // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
+ // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
+ // itself. See the comment in that method for an explanation as to why.
+ possible_borrower.bounded_borrowers(&[local], &[local, place.local], place.local, location)
+ && used_exactly_once(mir, place.local).unwrap_or(false)
+ } else {
+ false
+ }
+}
+
+// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
+// projected type that is a type parameter. Returns `false` if replacing the types would have an
+// effect on the function signature beyond substituting `new_ty` for `param_ty`.
+// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
+fn replace_types<'tcx>(
+ cx: &LateContext<'tcx>,
+ param_ty: ParamTy,
+ new_ty: Ty<'tcx>,
+ fn_sig: FnSig<'tcx>,
+ arg_index: usize,
+ projection_predicates: &[ProjectionPredicate<'tcx>],
+ args: &mut [ty::GenericArg<'tcx>],
+) -> bool {
+ let mut replaced = BitSet::new_empty(args.len());
+
+ let mut deque = VecDeque::with_capacity(args.len());
+ deque.push_back((param_ty, new_ty));
+
+ while let Some((param_ty, new_ty)) = deque.pop_front() {
+ // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
+ if !fn_sig
+ .inputs_and_output
+ .iter()
+ .enumerate()
+ .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))
+ {
+ return false;
+ }
+
+ args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
+
+ // The `replaced.insert(...)` check provides some protection against infinite loops.
+ if replaced.insert(param_ty.index) {
+ for projection_predicate in projection_predicates {
+ if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
+ && let Some(term_ty) = projection_predicate.term.ty()
+ && let ty::Param(term_param_ty) = term_ty.kind()
+ {
+ let projection = cx.tcx.mk_ty_from_kind(ty::Alias(
+ ty::Projection,
+ projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty),
+ ));
+
+ if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
+ && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
+ {
+ deque.push_back((*term_param_ty, projected_ty));
+ }
+ }
+ }
+ }
+ }
+
+ true
+}
diff --git a/src/tools/clippy/clippy_lints/src/needless_else.rs b/src/tools/clippy/clippy_lints/src/needless_else.rs
index 03bab86c6..0c1fe881f 100644
--- a/src/tools/clippy/clippy_lints/src/needless_else.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_else.rs
@@ -27,7 +27,7 @@ declare_clippy_lint! {
/// println!("Check successful!");
/// }
/// ```
- #[clippy::version = "1.71.0"]
+ #[clippy::version = "1.72.0"]
pub NEEDLESS_ELSE,
style,
"empty else branch"
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 7f0a5964a..3ad9ae030 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -1,6 +1,7 @@
use super::needless_pass_by_value::requires_exact_signature;
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::snippet;
+use clippy_utils::visitors::for_each_expr_with_closures;
use clippy_utils::{get_parent_node, inherits_cfg, is_from_proc_macro, is_self};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::Applicability;
@@ -9,7 +10,7 @@ use rustc_hir::{
Body, Closure, Expr, ExprKind, FnDecl, HirId, HirIdMap, HirIdSet, Impl, ItemKind, Mutability, Node, PatKind, QPath,
};
use rustc_hir_typeck::expr_use_visitor as euv;
-use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::map::associated_body;
use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -21,6 +22,8 @@ use rustc_span::symbol::kw;
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
+use core::ops::ControlFlow;
+
declare_clippy_lint! {
/// ### What it does
/// Check if a `&mut` function argument is actually used mutably.
@@ -95,6 +98,30 @@ fn should_skip<'tcx>(
is_from_proc_macro(cx, &input)
}
+fn check_closures<'tcx>(
+ ctx: &mut MutablyUsedVariablesCtxt<'tcx>,
+ cx: &LateContext<'tcx>,
+ infcx: &InferCtxt<'tcx>,
+ checked_closures: &mut FxHashSet<LocalDefId>,
+ closures: FxHashSet<LocalDefId>,
+) {
+ let hir = cx.tcx.hir();
+ for closure in closures {
+ if !checked_closures.insert(closure) {
+ continue;
+ }
+ ctx.prev_bind = None;
+ ctx.prev_move_to_closure.clear();
+ if let Some(body) = hir
+ .find_by_def_id(closure)
+ .and_then(associated_body)
+ .map(|(_, body_id)| hir.body(body_id))
+ {
+ euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body);
+ }
+ }
+}
+
impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
fn check_fn(
&mut self,
@@ -161,25 +188,22 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
if is_async {
let mut checked_closures = FxHashSet::default();
+
+ // We retrieve all the closures declared in the async function because they will
+ // not be found by `euv::Delegate`.
+ let mut closures: FxHashSet<LocalDefId> = FxHashSet::default();
+ for_each_expr_with_closures(cx, body, |expr| {
+ if let ExprKind::Closure(closure) = expr.kind {
+ closures.insert(closure.def_id);
+ }
+ ControlFlow::<()>::Continue(())
+ });
+ check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures);
+
while !ctx.async_closures.is_empty() {
- let closures = ctx.async_closures.clone();
+ let async_closures = ctx.async_closures.clone();
ctx.async_closures.clear();
- let hir = cx.tcx.hir();
- for closure in closures {
- if !checked_closures.insert(closure) {
- continue;
- }
- ctx.prev_bind = None;
- ctx.prev_move_to_closure.clear();
- if let Some(body) = hir
- .find_by_def_id(closure)
- .and_then(associated_body)
- .map(|(_, body_id)| hir.body(body_id))
- {
- euv::ExprUseVisitor::new(&mut ctx, &infcx, closure, cx.param_env, cx.typeck_results())
- .consume_body(body);
- }
- }
+ check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures);
}
}
ctx
@@ -244,6 +268,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
struct MutablyUsedVariablesCtxt<'tcx> {
mutably_used_vars: HirIdSet,
prev_bind: Option<HirId>,
+ /// In async functions, the inner AST is composed of multiple layers until we reach the code
+ /// defined by the user. Because of that, some variables are marked as mutably borrowed even
+ /// though they're not. This field lists the `HirId` that should not be considered as mutable
+ /// use of a variable.
prev_move_to_closure: HirIdSet,
aliases: HirIdMap<HirId>,
async_closures: FxHashSet<LocalDefId>,
@@ -308,7 +336,12 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId, borrow: ty::BorrowKind) {
self.prev_bind = None;
if let euv::Place {
- base: euv::PlaceBase::Local(vid),
+ base:
+ euv::PlaceBase::Local(vid)
+ | euv::PlaceBase::Upvar(UpvarId {
+ var_path: UpvarPath { hir_id: vid },
+ ..
+ }),
base_ty,
..
} = &cmt.place
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index cf7cd671d..f7f9dccfb 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -130,6 +130,11 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
}
let generics_sugg = snippet(cx, generics.span, "");
+ let where_clause_sugg = if generics.has_where_clause_predicates {
+ format!("\n{}\n", snippet(cx, generics.where_clause_span, ""))
+ } else {
+ String::new()
+ };
let self_ty_fmt = self_ty.to_string();
let self_type_snip = snippet(cx, impl_self_ty.span, &self_ty_fmt);
span_lint_hir_and_then(
@@ -145,8 +150,12 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
cx,
item.span,
"try adding this",
- &create_new_without_default_suggest_msg(&self_type_snip, &generics_sugg),
- Applicability::MaybeIncorrect,
+ &create_new_without_default_suggest_msg(
+ &self_type_snip,
+ &generics_sugg,
+ &where_clause_sugg
+ ),
+ Applicability::MachineApplicable,
);
},
);
@@ -159,10 +168,14 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
}
}
-fn create_new_without_default_suggest_msg(self_type_snip: &str, generics_sugg: &str) -> String {
+fn create_new_without_default_suggest_msg(
+ self_type_snip: &str,
+ generics_sugg: &str,
+ where_clause_sugg: &str,
+) -> String {
#[rustfmt::skip]
format!(
-"impl{generics_sugg} Default for {self_type_snip} {{
+"impl{generics_sugg} Default for {self_type_snip}{where_clause_sugg} {{
fn default() -> Self {{
Self::new()
}}
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 5f2a324b0..aee184252 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -5,10 +5,8 @@ use clippy_utils::{get_parent_node, is_lint_allowed, peel_blocks};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{
- is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, FnRetTy, ItemKind, Node, PatKind, Stmt, StmtKind,
- UnsafeSource,
+ is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, ItemKind, Node, PatKind, Stmt, StmtKind, UnsafeSource,
};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
@@ -99,14 +97,13 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
|diag| {
for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
if let Node::Item(item) = parent.1
- && let ItemKind::Fn(sig, ..) = item.kind
- && let FnRetTy::Return(ret_ty) = sig.decl.output
+ && let ItemKind::Fn(..) = item.kind
&& let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
&& let [.., final_stmt] = block.stmts
&& final_stmt.hir_id == stmt.hir_id
{
let expr_ty = cx.typeck_results().expr_ty(expr);
- let mut ret_ty = hir_ty_to_ty(cx.tcx, ret_ty);
+ let mut ret_ty = cx.tcx.fn_sig(item.owner_id).instantiate_identity().output().skip_binder();
// Remove `impl Future<Output = T>` to get `T`
if cx.tcx.ty_is_opaque_future(ret_ty) &&
@@ -115,7 +112,7 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
ret_ty = true_ret_ty;
}
- if ret_ty == expr_ty {
+ if !ret_ty.is_unit() && ret_ty == expr_ty {
diag.span_suggestion(
stmt.span.shrink_to_lo(),
"did you mean to return it?",
diff --git a/src/tools/clippy/clippy_lints/src/incorrect_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
index 3c59b839a..20b4b4f03 100644
--- a/src/tools/clippy/clippy_lints/src/incorrect_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -4,7 +4,7 @@ use clippy_utils::ty::implements_trait;
use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, match_def_path, path_res, std_or_core};
use rustc_errors::Applicability;
use rustc_hir::def_id::LocalDefId;
-use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, ItemKind, LangItem, Node, UnOp};
+use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::EarlyBinder;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -13,11 +13,12 @@ use rustc_span::symbol::kw;
declare_clippy_lint! {
/// ### What it does
- /// Checks for manual implementations of `Clone` when `Copy` is already implemented.
+ /// Checks for non-canonical implementations of `Clone` when `Copy` is already implemented.
///
/// ### Why is this bad?
- /// If both `Clone` and `Copy` are implemented, they must agree. This is done by dereferencing
- /// `self` in `Clone`'s implementation. Anything else is incorrect.
+ /// If both `Clone` and `Copy` are implemented, they must agree. This can done by dereferencing
+ /// `self` in `Clone`'s implementation, which will avoid any possibility of the implementations
+ /// becoming out of sync.
///
/// ### Example
/// ```rust,ignore
@@ -46,14 +47,13 @@ declare_clippy_lint! {
/// impl Copy for A {}
/// ```
#[clippy::version = "1.72.0"]
- pub INCORRECT_CLONE_IMPL_ON_COPY_TYPE,
- correctness,
- "manual implementation of `Clone` on a `Copy` type"
+ pub NON_CANONICAL_CLONE_IMPL,
+ suspicious,
+ "non-canonical implementation of `Clone` on a `Copy` type"
}
declare_clippy_lint! {
/// ### What it does
- /// Checks for manual implementations of both `PartialOrd` and `Ord` when only `Ord` is
- /// necessary.
+ /// Checks for non-canonical implementations of `PartialOrd` when `Ord` is already implemented.
///
/// ### Why is this bad?
/// If both `PartialOrd` and `Ord` are implemented, they must agree. This is commonly done by
@@ -61,11 +61,8 @@ declare_clippy_lint! {
/// introduce an error upon refactoring.
///
/// ### Known issues
- /// Code that calls the `.into()` method instead will be flagged as incorrect, despite `.into()`
- /// wrapping it in `Some`.
- ///
- /// ### Limitations
- /// Will not lint if `Self` and `Rhs` do not have the same type.
+ /// Code that calls the `.into()` method instead will be flagged, despite `.into()` wrapping it
+ /// in `Some`.
///
/// ### Example
/// ```rust
@@ -107,13 +104,13 @@ declare_clippy_lint! {
/// }
/// ```
#[clippy::version = "1.72.0"]
- pub INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE,
- correctness,
- "manual implementation of `PartialOrd` when `Ord` is already implemented"
+ pub NON_CANONICAL_PARTIAL_ORD_IMPL,
+ suspicious,
+ "non-canonical implementation of `PartialOrd` on an `Ord` type"
}
-declare_lint_pass!(IncorrectImpls => [INCORRECT_CLONE_IMPL_ON_COPY_TYPE, INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE]);
+declare_lint_pass!(NonCanonicalImpls => [NON_CANONICAL_CLONE_IMPL, NON_CANONICAL_PARTIAL_ORD_IMPL]);
-impl LateLintPass<'_> for IncorrectImpls {
+impl LateLintPass<'_> for NonCanonicalImpls {
#[expect(clippy::too_many_lines)]
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
let Some(Node::Item(item)) = get_parent_node(cx.tcx, impl_item.hir_id()) else {
@@ -125,9 +122,6 @@ impl LateLintPass<'_> for IncorrectImpls {
if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) {
return;
}
- let ItemKind::Impl(_) = item.kind else {
- return;
- };
let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else {
return;
};
@@ -154,9 +148,9 @@ impl LateLintPass<'_> for IncorrectImpls {
{} else {
span_lint_and_sugg(
cx,
- INCORRECT_CLONE_IMPL_ON_COPY_TYPE,
+ NON_CANONICAL_CLONE_IMPL,
block.span,
- "incorrect implementation of `clone` on a `Copy` type",
+ "non-canonical implementation of `clone` on a `Copy` type",
"change this to",
"{ *self }".to_owned(),
Applicability::MaybeIncorrect,
@@ -169,9 +163,9 @@ impl LateLintPass<'_> for IncorrectImpls {
if impl_item.ident.name == sym::clone_from {
span_lint_and_sugg(
cx,
- INCORRECT_CLONE_IMPL_ON_COPY_TYPE,
+ NON_CANONICAL_CLONE_IMPL,
impl_item.span,
- "incorrect implementation of `clone_from` on a `Copy` type",
+ "unnecessary implementation of `clone_from` on a `Copy` type",
"remove it",
String::new(),
Applicability::MaybeIncorrect,
@@ -183,17 +177,8 @@ impl LateLintPass<'_> for IncorrectImpls {
if cx.tcx.is_diagnostic_item(sym::PartialOrd, trait_impl.def_id)
&& impl_item.ident.name == sym::partial_cmp
- && let Some(ord_def_id) = cx
- .tcx
- .diagnostic_items(trait_impl.def_id.krate)
- .name_to_id
- .get(&sym::Ord)
- && implements_trait(
- cx,
- trait_impl.self_ty(),
- *ord_def_id,
- &[],
- )
+ && let Some(ord_def_id) = cx.tcx.get_diagnostic_item(sym::Ord)
+ && implements_trait(cx, trait_impl.self_ty(), ord_def_id, &[])
{
// If the `cmp` call likely needs to be fully qualified in the suggestion
// (like `std::cmp::Ord::cmp`). It's unfortunate we must put this here but we can't
@@ -222,9 +207,9 @@ impl LateLintPass<'_> for IncorrectImpls {
span_lint_and_then(
cx,
- INCORRECT_PARTIAL_ORD_IMPL_ON_ORD_TYPE,
+ NON_CANONICAL_PARTIAL_ORD_IMPL,
item.span,
- "incorrect implementation of `partial_cmp` on an `Ord` type",
+ "non-canonical implementation of `partial_cmp` on an `Ord` type",
|diag| {
let [_, other] = body.params else {
return;
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 243192385..2b4e3260c 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -13,7 +13,6 @@ use rustc_hir::def_id::DefId;
use rustc_hir::{
BodyId, Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, Lint};
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
use rustc_middle::ty::adjustment::Adjust;
@@ -204,7 +203,7 @@ fn is_value_unfrozen_raw<'tcx>(
// similar to 2., but with the a frozen variant) (e.g. borrowing
// `borrow_interior_mutable_const::enums::AssocConsts::TO_BE_FROZEN_VARIANT`).
// I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none).
- err == ErrorHandled::TooGeneric
+ matches!(err, ErrorHandled::TooGeneric(..))
},
|val| val.map_or(true, |val| inner(cx, val, ty)),
)
@@ -244,8 +243,8 @@ pub fn const_eval_resolve<'tcx>(
};
tcx.const_eval_global_id_for_typeck(param_env, cid, span)
},
- Ok(None) => Err(ErrorHandled::TooGeneric),
- Err(err) => Err(ErrorHandled::Reported(err.into())),
+ Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP))),
+ Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(rustc_span::DUMMY_SP))),
}
}
@@ -297,8 +296,8 @@ declare_lint_pass!(NonCopyConst => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTER
impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) {
- if let ItemKind::Const(hir_ty, _generics, body_id) = it.kind {
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ if let ItemKind::Const(.., body_id) = it.kind {
+ let ty = cx.tcx.type_of(it.owner_id).instantiate_identity();
if !ignored_macro(cx, it) && is_unfrozen(cx, ty) && is_value_unfrozen_poly(cx, body_id, ty) {
lint(cx, Source::Item { item: it.span });
}
@@ -306,8 +305,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) {
- if let TraitItemKind::Const(hir_ty, body_id_opt) = &trait_item.kind {
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ if let TraitItemKind::Const(_, body_id_opt) = &trait_item.kind {
+ let ty = cx.tcx.type_of(trait_item.owner_id).instantiate_identity();
// Normalize assoc types because ones originated from generic params
// bounded other traits could have their bound.
@@ -333,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
- if let ImplItemKind::Const(hir_ty, body_id) = &impl_item.kind {
+ if let ImplItemKind::Const(_, body_id) = &impl_item.kind {
let item_def_id = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
let item = cx.tcx.hir().expect_item(item_def_id);
@@ -366,7 +365,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
// we should use here as a frozen variant is a potential to be frozen
// similar to unknown layouts.
// e.g. `layout_of(...).is_err() || has_frozen_variant(...);`
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
if is_unfrozen(cx, normalized);
if is_value_unfrozen_poly(cx, *body_id, normalized);
@@ -381,7 +380,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
}
},
ItemKind::Impl(Impl { of_trait: None, .. }) => {
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
// Normalize assoc types originated from generic params.
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index f9108145c..a10aa65e5 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -1,24 +1,25 @@
use super::ARITHMETIC_SIDE_EFFECTS;
use clippy_utils::consts::{constant, constant_simple, Constant};
use clippy_utils::diagnostics::span_lint;
+use clippy_utils::ty::type_diagnostic_name;
use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty;
use rustc_session::impl_lint_pass;
use rustc_span::source_map::{Span, Spanned};
+use rustc_span::symbol::sym;
use rustc_span::Symbol;
use {rustc_ast as ast, rustc_hir as hir};
-const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[
- ["f32", "f32"],
- ["f64", "f64"],
- ["std::num::Saturating", "*"],
- ["std::num::Wrapping", "*"],
- ["std::string::String", "str"],
-];
+const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[["f32", "f32"], ["f64", "f64"], ["std::string::String", "str"]];
const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"];
-const INTEGER_METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"];
+const INTEGER_METHODS: &[Symbol] = &[
+ sym::saturating_div,
+ sym::wrapping_div,
+ sym::wrapping_rem,
+ sym::wrapping_rem_euclid,
+];
#[derive(Debug)]
pub struct ArithmeticSideEffects {
@@ -53,7 +54,7 @@ impl ArithmeticSideEffects {
allowed_unary,
const_span: None,
expr_span: None,
- integer_methods: INTEGER_METHODS.iter().map(|el| Symbol::intern(el)).collect(),
+ integer_methods: INTEGER_METHODS.iter().copied().collect(),
}
}
@@ -86,6 +87,45 @@ impl ArithmeticSideEffects {
self.allowed_unary.contains(ty_string_elem)
}
+ /// Verifies built-in types that have specific allowed operations
+ fn has_specific_allowed_type_and_operation(
+ cx: &LateContext<'_>,
+ lhs_ty: Ty<'_>,
+ op: &Spanned<hir::BinOpKind>,
+ rhs_ty: Ty<'_>,
+ ) -> bool {
+ let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
+ let is_non_zero_u = |symbol: Option<Symbol>| {
+ matches!(
+ symbol,
+ Some(
+ sym::NonZeroU128
+ | sym::NonZeroU16
+ | sym::NonZeroU32
+ | sym::NonZeroU64
+ | sym::NonZeroU8
+ | sym::NonZeroUsize
+ )
+ )
+ };
+ let is_sat_or_wrap = |ty: Ty<'_>| {
+ let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating);
+ let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping);
+ is_sat || is_wrap
+ };
+
+ // If the RHS is NonZeroU*, then division or module by zero will never occur
+ if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem {
+ return true;
+ }
+ // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module
+ if is_sat_or_wrap(lhs_ty) {
+ return !is_div_or_rem;
+ }
+
+ false
+ }
+
// For example, 8i32 or &i64::MAX.
fn is_integral(ty: Ty<'_>) -> bool {
ty.peel_refs().is_integral()
@@ -147,6 +187,9 @@ impl ArithmeticSideEffects {
if self.has_allowed_binary(lhs_ty, rhs_ty) {
return;
}
+ if Self::has_specific_allowed_type_and_operation(cx, lhs_ty, op, rhs_ty) {
+ return;
+ }
let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) {
if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op.node {
// At least for integers, shifts are already handled by the CTFE
@@ -272,7 +315,7 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id());
let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id);
- if let hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) = body_owner_kind {
+ if let hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) = body_owner_kind {
let body_span = cx.tcx.hir().span_with_body(body_owner);
if let Some(span) = self.const_span && span.contains(body_span) {
return;
diff --git a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
index f3e0c58a7..bce6bdcaf 100644
--- a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
@@ -17,7 +17,7 @@ pub(crate) fn check<'tcx>(
left: &'tcx Expr<'_>,
right: &'tcx Expr<'_>,
) {
- if (op == BinOpKind::Eq || op == BinOpKind::Ne) && (is_float(cx, left) || is_float(cx, right)) {
+ if (op == BinOpKind::Eq || op == BinOpKind::Ne) && is_float(cx, left) {
let left_is_local = match constant_with_source(cx, cx.typeck_results(), left) {
Some((c, s)) if !is_allowed(&c) => s.is_local(),
Some(_) => return,
diff --git a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
index 102845cee..80389cbf8 100644
--- a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
@@ -72,7 +72,7 @@ impl Context {
let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id());
match cx.tcx.hir().body_owner_kind(body_owner_def_id) {
- hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const => {
+ hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const { .. } => {
let body_span = cx.tcx.hir().span_with_body(body_owner);
if let Some(span) = self.const_span {
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 8009b00b4..7dabdcd58 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -16,7 +16,6 @@ use rustc_hir::{
ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind,
TyKind, Unsafety,
};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_lint::{LateContext, LateLintPass};
@@ -172,13 +171,8 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
for arg in check_fn_args(
cx,
- cx.tcx
- .fn_sig(item.owner_id)
- .instantiate_identity()
- .skip_binder()
- .inputs(),
+ cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder(),
sig.decl.inputs,
- &sig.decl.output,
&[],
)
.filter(|arg| arg.mutability() == Mutability::Not)
@@ -237,7 +231,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
let decl = sig.decl;
let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder();
- let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params)
+ let lint_args: Vec<_> = check_fn_args(cx, sig, decl.inputs, body.params)
.filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)
.collect();
let results = check_ptr_arg_usage(cx, body, &lint_args);
@@ -278,7 +272,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// (fn_path, arg_indices) - `arg_indices` are the `arg` positions where null would cause U.B.
- const INVALID_NULL_PTR_USAGE_TABLE: [(&[&str], &[usize]); 16] = [
+ const INVALID_NULL_PTR_USAGE_TABLE: [(&[&str], &[usize]); 13] = [
(&paths::SLICE_FROM_RAW_PARTS, &[0]),
(&paths::SLICE_FROM_RAW_PARTS_MUT, &[0]),
(&paths::PTR_COPY, &[0, 1]),
@@ -291,20 +285,33 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
(&paths::PTR_SLICE_FROM_RAW_PARTS_MUT, &[0]),
(&paths::PTR_SWAP, &[0, 1]),
(&paths::PTR_SWAP_NONOVERLAPPING, &[0, 1]),
- (&paths::PTR_WRITE, &[0]),
- (&paths::PTR_WRITE_UNALIGNED, &[0]),
- (&paths::PTR_WRITE_VOLATILE, &[0]),
(&paths::PTR_WRITE_BYTES, &[0]),
];
+ let invalid_null_ptr_usage_table_diag_items: [(Option<DefId>, &[usize]); 3] = [
+ (cx.tcx.get_diagnostic_item(sym::ptr_write), &[0]),
+ (cx.tcx.get_diagnostic_item(sym::ptr_write_unaligned), &[0]),
+ (cx.tcx.get_diagnostic_item(sym::ptr_write_volatile), &[0]),
+ ];
if_chain! {
if let ExprKind::Call(fun, args) = expr.kind;
if let ExprKind::Path(ref qpath) = fun.kind;
if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id();
let fun_def_path = cx.get_def_path(fun_def_id).into_iter().map(Symbol::to_ident_string).collect::<Vec<_>>();
- if let Some(&(_, arg_indices)) = INVALID_NULL_PTR_USAGE_TABLE
+ if let Some(arg_indices) = INVALID_NULL_PTR_USAGE_TABLE
.iter()
- .find(|&&(fn_path, _)| fn_path == fun_def_path);
+ .find_map(|&(fn_path, indices)| if fn_path == fun_def_path { Some(indices) } else { None })
+ .or_else(|| {
+ invalid_null_ptr_usage_table_diag_items
+ .iter()
+ .find_map(|&(def_id, indices)| {
+ if def_id == Some(fun_def_id) {
+ Some(indices)
+ } else {
+ None
+ }
+ })
+ });
then {
for &arg_idx in arg_indices {
if let Some(arg) = args.get(arg_idx).filter(|arg| is_null_path(cx, arg)) {
@@ -430,12 +437,13 @@ impl<'tcx> DerefTy<'tcx> {
#[expect(clippy::too_many_lines)]
fn check_fn_args<'cx, 'tcx: 'cx>(
cx: &'cx LateContext<'tcx>,
- tys: &'tcx [Ty<'tcx>],
+ fn_sig: ty::FnSig<'tcx>,
hir_tys: &'tcx [hir::Ty<'tcx>],
- ret_ty: &'tcx FnRetTy<'tcx>,
params: &'tcx [Param<'tcx>],
) -> impl Iterator<Item = PtrArg<'tcx>> + 'cx {
- tys.iter()
+ fn_sig
+ .inputs()
+ .iter()
.zip(hir_tys.iter())
.enumerate()
.filter_map(move |(i, (ty, hir_ty))| {
@@ -481,9 +489,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
})
{
if !lifetime.is_anonymous()
- && let FnRetTy::Return(ret_ty) = ret_ty
- && let ret_ty = hir_ty_to_ty(cx.tcx, ret_ty)
- && ret_ty
+ && fn_sig.output()
.walk()
.filter_map(|arg| {
arg.as_region().and_then(|lifetime| {
diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs
index ccabb577c..8a7e48746 100644
--- a/src/tools/clippy/clippy_lints/src/raw_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs
@@ -1,7 +1,7 @@
use std::iter::once;
use std::ops::ControlFlow;
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet;
use rustc_ast::ast::{Expr, ExprKind};
use rustc_ast::token::LitKind;
@@ -9,6 +9,7 @@ use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{BytePos, Pos, Span};
declare_clippy_lint! {
/// ### What it does
@@ -49,7 +50,7 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.72.0"]
pub NEEDLESS_RAW_STRING_HASHES,
- style,
+ pedantic,
"suggests reducing the number of hashes around a raw string literal"
}
impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]);
@@ -76,17 +77,37 @@ impl EarlyLintPass for RawStrings {
}
if !str.contains(['\\', '"']) {
- span_lint_and_sugg(
+ span_lint_and_then(
cx,
NEEDLESS_RAW_STRINGS,
expr.span,
"unnecessary raw string literal",
- "try",
- format!("{}\"{}\"", prefix.replace('r', ""), lit.symbol),
- Applicability::MachineApplicable,
- );
+ |diag| {
+ let (start, end) = hash_spans(expr.span, prefix, 0, max);
- return;
+ // BytePos: skip over the `b` in `br`, we checked the prefix appears in the source text
+ let r_pos = expr.span.lo() + BytePos::from_usize(prefix.len() - 1);
+ let start = start.with_lo(r_pos);
+
+ if end.is_empty() {
+ diag.span_suggestion(
+ start,
+ "use a string literal instead",
+ format!("\"{str}\""),
+ Applicability::MachineApplicable,
+ );
+ } else {
+ diag.multipart_suggestion(
+ "try",
+ vec![(start, String::new()), (end, String::new())],
+ Applicability::MachineApplicable,
+ );
+ }
+ },
+ );
+ if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
+ return;
+ }
}
let req = {
@@ -96,13 +117,6 @@ impl EarlyLintPass for RawStrings {
let num = str.as_bytes().iter().chain(once(&0)).try_fold(0u8, |acc, &b| {
match b {
b'"' if !following_quote => (following_quote, req) = (true, 1),
- // I'm a bit surprised the compiler didn't optimize this out, there's no
- // branch but it still ends up doing an unnecessary comparison, it's:
- // - cmp r9b,1h
- // - sbb cl,-1h
- // which will add 1 if it's true. With this change, it becomes:
- // - add cl,r9b
- // isn't that so much nicer?
b'#' => req += u8::from(following_quote),
_ => {
if following_quote {
@@ -126,18 +140,58 @@ impl EarlyLintPass for RawStrings {
};
if req < max {
- let hashes = "#".repeat(req as usize);
-
- span_lint_and_sugg(
+ span_lint_and_then(
cx,
NEEDLESS_RAW_STRING_HASHES,
expr.span,
"unnecessary hashes around raw string literal",
- "try",
- format!(r#"{prefix}{hashes}"{}"{hashes}"#, lit.symbol),
- Applicability::MachineApplicable,
+ |diag| {
+ let (start, end) = hash_spans(expr.span, prefix, req, max);
+
+ let message = match max - req {
+ _ if req == 0 => "remove all the hashes around the literal".to_string(),
+ 1 => "remove one hash from both sides of the literal".to_string(),
+ n => format!("remove {n} hashes from both sides of the literal"),
+ };
+
+ diag.multipart_suggestion(
+ message,
+ vec![(start, String::new()), (end, String::new())],
+ Applicability::MachineApplicable,
+ );
+ },
);
}
}
}
}
+
+/// Returns spans pointing at the unneeded hashes, e.g. for a `req` of `1` and `max` of `3`:
+///
+/// ```ignore
+/// r###".."###
+/// ^^ ^^
+/// ```
+fn hash_spans(literal_span: Span, prefix: &str, req: u8, max: u8) -> (Span, Span) {
+ let literal_span = literal_span.data();
+
+ // BytePos: we checked prefix appears literally in the source text
+ let hash_start = literal_span.lo + BytePos::from_usize(prefix.len());
+ let hash_end = literal_span.hi;
+
+ // BytePos: req/max are counts of the ASCII character #
+ let start = Span::new(
+ hash_start + BytePos(req.into()),
+ hash_start + BytePos(max.into()),
+ literal_span.ctxt,
+ None,
+ );
+ let end = Span::new(
+ hash_end - BytePos(req.into()),
+ hash_end - BytePos(max.into()),
+ literal_span.ctxt,
+ None,
+ );
+
+ (start, end)
+}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index fc49b58e0..f42836611 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -10,6 +10,7 @@ use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@@ -84,7 +85,7 @@ fn find_innermost_closure<'tcx>(
cx: &LateContext<'tcx>,
mut expr: &'tcx hir::Expr<'tcx>,
mut steps: usize,
-) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, hir::IsAsync)> {
+) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, ty::Asyncness)> {
let mut data = None;
while let hir::ExprKind::Closure(closure) = expr.kind
@@ -98,9 +99,9 @@ fn find_innermost_closure<'tcx>(
{
expr = body.value;
data = Some((body.value, closure.fn_decl, if is_async_closure(body) {
- hir::IsAsync::Async
+ ty::Asyncness::Yes
} else {
- hir::IsAsync::NotAsync
+ ty::Asyncness::No
}));
steps -= 1;
}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
index 3e963d798..1d4fdb43a 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
@@ -31,7 +31,7 @@ declare_clippy_lint! {
/// ```rust
/// let foo = String::new();
/// ```
- #[clippy::version = "1.70.0"]
+ #[clippy::version = "1.72.0"]
pub REDUNDANT_TYPE_ANNOTATIONS,
restriction,
"warns about needless / redundant type annotations."
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index fc1fabcc0..613f1ecc6 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -15,6 +15,8 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::eval_order_dependence", "clippy::mixed_read_write_in_expression"),
("clippy::identity_conversion", "clippy::useless_conversion"),
("clippy::if_let_some_result", "clippy::match_result_ok"),
+ ("clippy::incorrect_clone_impl_on_copy_type", "clippy::non_canonical_clone_impl"),
+ ("clippy::incorrect_partial_ord_impl_on_ord_type", "clippy::non_canonical_partial_ord_impl"),
("clippy::integer_arithmetic", "clippy::arithmetic_side_effects"),
("clippy::logic_bug", "clippy::overly_complex_bool_expr"),
("clippy::new_without_default_derive", "clippy::new_without_default"),
@@ -38,12 +40,12 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::drop_bounds", "drop_bounds"),
("clippy::drop_copy", "dropping_copy_types"),
("clippy::drop_ref", "dropping_references"),
+ ("clippy::fn_null_check", "useless_ptr_null_checks"),
("clippy::for_loop_over_option", "for_loops_over_fallibles"),
("clippy::for_loop_over_result", "for_loops_over_fallibles"),
("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
("clippy::forget_copy", "forgetting_copy_types"),
("clippy::forget_ref", "forgetting_references"),
- ("clippy::fn_null_check", "useless_ptr_null_checks"),
("clippy::into_iter_on_array", "array_into_iter"),
("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
("clippy::invalid_ref", "invalid_value"),
diff --git a/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs b/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
new file mode 100644
index 000000000..0c8c904e3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
@@ -0,0 +1,134 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
+use clippy_utils::source::snippet;
+use clippy_utils::{is_from_proc_macro, path_to_local_id};
+use rustc_errors::Applicability;
+use rustc_hir::def::Res;
+use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Local, PatKind, QPath, Stmt, StmtKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::Span;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Informs the user about a more concise way to create a vector with a known capacity.
+ ///
+ /// ### Why is this bad?
+ /// The `Vec::with_capacity` constructor is less complex.
+ ///
+ /// ### Example
+ /// ```rust
+ /// let mut v: Vec<usize> = vec![];
+ /// v.reserve(10);
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// let mut v: Vec<usize> = Vec::with_capacity(10);
+ /// ```
+ #[clippy::version = "1.73.0"]
+ pub RESERVE_AFTER_INITIALIZATION,
+ complexity,
+ "`reserve` called immediatly after `Vec` creation"
+}
+impl_lint_pass!(ReserveAfterInitialization => [RESERVE_AFTER_INITIALIZATION]);
+
+#[derive(Default)]
+pub struct ReserveAfterInitialization {
+ searcher: Option<VecReserveSearcher>,
+}
+
+struct VecReserveSearcher {
+ local_id: HirId,
+ err_span: Span,
+ init_part: String,
+ space_hint: String,
+}
+impl VecReserveSearcher {
+ fn display_err(&self, cx: &LateContext<'_>) {
+ if self.space_hint.is_empty() {
+ return;
+ }
+
+ let s = format!("{}Vec::with_capacity({});", self.init_part, self.space_hint);
+
+ span_lint_and_sugg(
+ cx,
+ RESERVE_AFTER_INITIALIZATION,
+ self.err_span,
+ "call to `reserve` immediately after creation",
+ "consider using `Vec::with_capacity(/* Space hint */)`",
+ s,
+ Applicability::HasPlaceholders,
+ );
+ }
+}
+
+impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
+ fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {
+ self.searcher = None;
+ }
+
+ fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+ if let Some(init_expr) = local.init
+ && let PatKind::Binding(BindingAnnotation::MUT, id, _, None) = local.pat.kind
+ && !in_external_macro(cx.sess(), local.span)
+ && let Some(init) = get_vec_init_kind(cx, init_expr)
+ && !matches!(init, VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_))
+ {
+ self.searcher = Some(VecReserveSearcher {
+ local_id: id,
+ err_span: local.span,
+ init_part: snippet(cx, local.span.shrink_to_lo()
+ .to(init_expr.span.source_callsite().shrink_to_lo()), "..")
+ .into_owned(),
+ space_hint: String::new()
+ });
+ }
+ }
+
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+ if self.searcher.is_none()
+ && let ExprKind::Assign(left, right, _) = expr.kind
+ && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
+ && let Res::Local(id) = path.res
+ && !in_external_macro(cx.sess(), expr.span)
+ && let Some(init) = get_vec_init_kind(cx, right)
+ && !matches!(init, VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_))
+ {
+ self.searcher = Some(VecReserveSearcher {
+ local_id: id,
+ err_span: expr.span,
+ init_part: snippet(cx, left.span.shrink_to_lo()
+ .to(right.span.source_callsite().shrink_to_lo()), "..")
+ .into_owned(), // see `assign_expression` test
+ space_hint: String::new()
+ });
+ }
+ }
+
+ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
+ if let Some(searcher) = self.searcher.take() {
+ if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind
+ && let ExprKind::MethodCall(name, self_arg, [space_hint], _) = expr.kind
+ && path_to_local_id(self_arg, searcher.local_id)
+ && name.ident.as_str() == "reserve"
+ && !is_from_proc_macro(cx, expr)
+ {
+ self.searcher = Some(VecReserveSearcher {
+ err_span: searcher.err_span.to(stmt.span),
+ space_hint: snippet(cx, space_hint.span, "..").into_owned(),
+ .. searcher
+ });
+ } else {
+ searcher.display_err(cx);
+ }
+ }
+ }
+
+ fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {
+ if let Some(searcher) = self.searcher.take() {
+ searcher.display_err(cx);
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
index c9ab622ad..9db18c297 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -1,4 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::macros::root_macro_call;
use clippy_utils::sugg::Sugg;
use clippy_utils::{
get_enclosing_block, is_expr_path_def_path, is_integer_literal, is_path_diagnostic_item, path_to_local,
@@ -148,6 +149,15 @@ impl SlowVectorInit {
/// - `Some(InitializedSize::Uninitialized)` for `Vec::new()`
/// - `None` for other, unrelated kinds of expressions
fn as_vec_initializer<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<InitializedSize<'tcx>> {
+ // Generally don't warn if the vec initializer comes from an expansion, except for the vec! macro.
+ // This lets us still warn on `vec![]`, while ignoring other kinds of macros that may output an
+ // empty vec
+ if expr.span.from_expansion()
+ && root_macro_call(expr.span).map(|m| m.def_id) != cx.tcx.get_diagnostic_item(sym::vec_macro)
+ {
+ return None;
+ }
+
if let ExprKind::Call(func, [len_expr]) = expr.kind
&& is_expr_path_def_path(cx, func, &paths::VEC_WITH_CAPACITY)
{
@@ -205,7 +215,7 @@ impl SlowVectorInit {
span_lint_and_then(cx, SLOW_VECTOR_INITIALIZATION, slow_fill.span, msg, |diag| {
diag.span_suggestion(
- vec_alloc.allocation_expr.span,
+ vec_alloc.allocation_expr.span.source_callsite(),
"consider replacing this with",
format!("vec![0; {len_expr}]"),
Applicability::Unspecified,
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index f23916527..5f54a10d1 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -1,4 +1,5 @@
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_hir::{HirId, Path, PathSegment};
@@ -99,17 +100,17 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
&& let Some(first_segment) = get_first_segment(path)
&& is_stable(cx, def_id)
{
- let (lint, msg, help) = match first_segment.ident.name {
+ let (lint, used_mod, replace_with) = match first_segment.ident.name {
sym::std => match cx.tcx.crate_name(def_id.krate) {
sym::core => (
STD_INSTEAD_OF_CORE,
- "used import from `std` instead of `core`",
- "consider importing the item from `core`",
+ "std",
+ "core",
),
sym::alloc => (
STD_INSTEAD_OF_ALLOC,
- "used import from `std` instead of `alloc`",
- "consider importing the item from `alloc`",
+ "std",
+ "alloc",
),
_ => {
self.prev_span = path.span;
@@ -120,8 +121,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
if cx.tcx.crate_name(def_id.krate) == sym::core {
(
ALLOC_INSTEAD_OF_CORE,
- "used import from `alloc` instead of `core`",
- "consider importing the item from `core`",
+ "alloc",
+ "core",
)
} else {
self.prev_span = path.span;
@@ -131,7 +132,14 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
_ => return,
};
if path.span != self.prev_span {
- span_lint_and_help(cx, lint, path.span, msg, None, help);
+ span_lint_and_sugg(
+ cx,
+ lint,
+ first_segment.ident.span,
+ &format!("used import from `{used_mod}` instead of `{replace_with}`"),
+ &format!("consider importing the item from `{replace_with}`"),
+ replace_with.to_string(),
+ Applicability::MachineApplicable);
self.prev_span = path.span;
}
}
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
index 23d6e2a84..d10f10ef8 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
@@ -586,7 +586,7 @@ fn ident_difference_expr_with_base_location(
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
| (While(_, _, _), While(_, _, _))
| (If(_, _, _), If(_, _, _))
- | (Let(_, _, _), Let(_, _, _))
+ | (Let(_, _, _, _), Let(_, _, _, _))
| (Type(_, _), Type(_, _))
| (Cast(_, _), Cast(_, _))
| (Lit(_), Lit(_))
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
index 4944381da..b26365e34 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
@@ -28,35 +28,43 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t
return false;
}
- match arg.kind {
+ let casts_peeled = peel_casts(arg);
+ match casts_peeled.kind {
// Catching:
// transmute over constants that resolve to `null`.
- ExprKind::Path(ref _qpath) if matches!(constant(cx, cx.typeck_results(), arg), Some(Constant::RawPtr(0))) => {
+ ExprKind::Path(ref _qpath)
+ if matches!(
+ constant(cx, cx.typeck_results(), casts_peeled),
+ Some(Constant::RawPtr(0))
+ ) =>
+ {
lint_expr(cx, expr);
true
},
-
- // Catching:
- // `std::mem::transmute(0 as *const i32)`
- ExprKind::Cast(inner_expr, _cast_ty) if is_integer_literal(inner_expr, 0) => {
- lint_expr(cx, expr);
- true
- },
-
// Catching:
// `std::mem::transmute(std::ptr::null::<i32>())`
ExprKind::Call(func1, []) if is_path_diagnostic_item(cx, func1, sym::ptr_null) => {
lint_expr(cx, expr);
true
},
-
_ => {
// FIXME:
// Also catch transmutations of variables which are known nulls.
// To do this, MIR const propagation seems to be the better tool.
// Whenever MIR const prop routines are more developed, this will
// become available. As of this writing (25/03/19) it is not yet.
+ if is_integer_literal(casts_peeled, 0) {
+ lint_expr(cx, expr);
+ return true;
+ }
false
},
}
}
+
+fn peel_casts<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
+ match &expr.kind {
+ ExprKind::Cast(inner_expr, _) => peel_casts(inner_expr),
+ _ => expr,
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
index 78ad52d8a..c12519d72 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -189,8 +189,8 @@ fn all_bindings_are_for_conv<'tcx>(
tys.len() == elements.len() && tys.iter().chain(final_tys.iter().copied()).all_equal()
},
(ToType::Tuple, ty::Array(ty, len)) => {
- len.eval_target_usize(cx.tcx, cx.param_env) as usize == elements.len()
- && final_tys.iter().chain(once(ty)).all_equal()
+ let Some(len) = len.try_eval_target_usize(cx.tcx, cx.param_env) else { return false };
+ len as usize == elements.len() && final_tys.iter().chain(once(ty)).all_equal()
},
_ => false,
}
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 79f9d45d5..71a4b3fba 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -315,7 +315,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
fn check_fn(
&mut self,
cx: &LateContext<'_>,
- _: FnKind<'_>,
+ fn_kind: FnKind<'_>,
decl: &FnDecl<'_>,
_: &Body<'_>,
_: Span,
@@ -340,6 +340,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
CheckTyContext {
is_in_trait_impl,
is_exported,
+ in_body: matches!(fn_kind, FnKind::Closure),
..CheckTyContext::default()
},
);
@@ -427,7 +428,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
cx,
ty,
CheckTyContext {
- is_local: true,
+ in_body: true,
..CheckTyContext::default()
},
);
@@ -481,7 +482,7 @@ impl Types {
}
match hir_ty.kind {
- TyKind::Path(ref qpath) if !context.is_local => {
+ TyKind::Path(ref qpath) if !context.in_body => {
let hir_id = hir_ty.hir_id;
let res = cx.qpath_res(qpath, hir_id);
if let Some(def_id) = res.opt_def_id() {
@@ -581,8 +582,8 @@ impl Types {
#[derive(Clone, Copy, Default)]
struct CheckTyContext {
is_in_trait_impl: bool,
- /// `true` for types on local variables.
- is_local: bool,
+ /// `true` for types on local variables and in closure signatures.
+ in_body: bool,
/// `true` for types that are part of the public API.
is_exported: bool,
is_nested_call: bool,
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index f2ef60201..6193fdeb4 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -12,7 +12,7 @@ use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{BytePos, Pos, Span, SyntaxContext};
+use rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext};
declare_clippy_lint! {
/// ### What it does
@@ -341,44 +341,21 @@ fn block_parents_have_safety_comment(
id: hir::HirId,
) -> bool {
if let Some(node) = get_parent_node(cx.tcx, id) {
- return match node {
- Node::Expr(expr) => {
- if let Some(
- Node::Local(hir::Local { span, .. })
- | Node::Item(hir::Item {
- kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
- span,
- ..
- }),
- ) = get_parent_node(cx.tcx, expr.hir_id)
- {
- let hir_id = match get_parent_node(cx.tcx, expr.hir_id) {
- Some(Node::Local(hir::Local { hir_id, .. })) => *hir_id,
- Some(Node::Item(hir::Item { owner_id, .. })) => {
- cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id)
- },
- _ => unreachable!(),
- };
-
- // if unsafe block is part of a let/const/static statement,
- // and accept_comment_above_statement is set to true
- // we accept the safety comment in the line the precedes this statement.
- accept_comment_above_statement
- && span_with_attrs_in_body_has_safety_comment(
- cx,
- *span,
- hir_id,
- accept_comment_above_attributes,
- )
- } else {
- !is_branchy(expr)
- && span_with_attrs_in_body_has_safety_comment(
- cx,
- expr.span,
- expr.hir_id,
- accept_comment_above_attributes,
- )
- }
+ let (span, hir_id) = match node {
+ Node::Expr(expr) => match get_parent_node(cx.tcx, expr.hir_id) {
+ Some(Node::Local(hir::Local { span, hir_id, .. })) => (*span, *hir_id),
+ Some(Node::Item(hir::Item {
+ kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
+ span,
+ owner_id,
+ ..
+ })) => (*span, cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id)),
+ _ => {
+ if is_branchy(expr) {
+ return false;
+ }
+ (expr.span, expr.hir_id)
+ },
},
Node::Stmt(hir::Stmt {
kind:
@@ -387,28 +364,27 @@ fn block_parents_have_safety_comment(
| hir::StmtKind::Semi(hir::Expr { span, hir_id, .. }),
..
})
- | Node::Local(hir::Local { span, hir_id, .. }) => {
- span_with_attrs_in_body_has_safety_comment(cx, *span, *hir_id, accept_comment_above_attributes)
- },
+ | Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id),
Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
span,
owner_id,
..
- }) => span_with_attrs_in_body_has_safety_comment(
- cx,
- *span,
- cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id),
- accept_comment_above_attributes,
- ),
- _ => false,
+ }) => (*span, cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id)),
+ _ => return false,
};
+ // if unsafe block is part of a let/const/static statement,
+ // and accept_comment_above_statement is set to true
+ // we accept the safety comment in the line the precedes this statement.
+ accept_comment_above_statement
+ && span_with_attrs_has_safety_comment(cx, span, hir_id, accept_comment_above_attributes)
+ } else {
+ false
}
- false
}
/// Extends `span` to also include its attributes, then checks if that span has a safety comment.
-fn span_with_attrs_in_body_has_safety_comment(
+fn span_with_attrs_has_safety_comment(
cx: &LateContext<'_>,
span: Span,
hir_id: HirId,
@@ -420,7 +396,7 @@ fn span_with_attrs_in_body_has_safety_comment(
span
};
- span_in_body_has_safety_comment(cx, span)
+ span_has_safety_comment(cx, span)
}
/// Checks if an expression is "branchy", e.g. loop, match/if/etc.
@@ -444,7 +420,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
matches!(
span_from_macro_expansion_has_safety_comment(cx, span),
HasSafetyComment::Yes(_)
- ) || span_in_body_has_safety_comment(cx, span)
+ ) || span_has_safety_comment(cx, span)
}
fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span {
@@ -507,20 +483,18 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
&& Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
&& let Some(src) = unsafe_line.sf.src.as_deref()
{
- return unsafe_line.sf.lines(|lines| {
- if comment_start_line.line >= unsafe_line.line {
- HasSafetyComment::No
- } else {
- match text_has_safety_comment(
- src,
- &lines[comment_start_line.line + 1..=unsafe_line.line],
- unsafe_line.sf.start_pos.to_usize(),
- ) {
- Some(b) => HasSafetyComment::Yes(b),
- None => HasSafetyComment::No,
- }
+ return if comment_start_line.line >= unsafe_line.line {
+ HasSafetyComment::No
+ } else {
+ match text_has_safety_comment(
+ src,
+ &unsafe_line.sf.lines()[comment_start_line.line + 1..=unsafe_line.line],
+ unsafe_line.sf.start_pos,
+ ) {
+ Some(b) => HasSafetyComment::Yes(b),
+ None => HasSafetyComment::No,
}
- });
+ };
}
}
HasSafetyComment::Maybe
@@ -551,20 +525,18 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H
&& Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
&& let Some(src) = unsafe_line.sf.src.as_deref()
{
- return unsafe_line.sf.lines(|lines| {
- if comment_start_line.line >= unsafe_line.line {
- HasSafetyComment::No
- } else {
- match text_has_safety_comment(
- src,
- &lines[comment_start_line.line + 1..=unsafe_line.line],
- unsafe_line.sf.start_pos.to_usize(),
- ) {
- Some(b) => HasSafetyComment::Yes(b),
- None => HasSafetyComment::No,
- }
+ return if comment_start_line.line >= unsafe_line.line {
+ HasSafetyComment::No
+ } else {
+ match text_has_safety_comment(
+ src,
+ &unsafe_line.sf.lines()[comment_start_line.line + 1..=unsafe_line.line],
+ unsafe_line.sf.start_pos,
+ ) {
+ Some(b) => HasSafetyComment::Yes(b),
+ None => HasSafetyComment::No,
}
- });
+ };
}
}
HasSafetyComment::Maybe
@@ -614,20 +586,18 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
&& Lrc::ptr_eq(&unsafe_line.sf, &macro_line.sf)
&& let Some(src) = unsafe_line.sf.src.as_deref()
{
- unsafe_line.sf.lines(|lines| {
- if macro_line.line < unsafe_line.line {
- match text_has_safety_comment(
- src,
- &lines[macro_line.line + 1..=unsafe_line.line],
- unsafe_line.sf.start_pos.to_usize(),
- ) {
- Some(b) => HasSafetyComment::Yes(b),
- None => HasSafetyComment::No,
- }
- } else {
- HasSafetyComment::No
+ if macro_line.line < unsafe_line.line {
+ match text_has_safety_comment(
+ src,
+ &unsafe_line.sf.lines()[macro_line.line + 1..=unsafe_line.line],
+ unsafe_line.sf.start_pos,
+ ) {
+ Some(b) => HasSafetyComment::Yes(b),
+ None => HasSafetyComment::No,
}
- })
+ } else {
+ HasSafetyComment::No
+ }
} else {
// Problem getting source text. Pretend a comment was found.
HasSafetyComment::Maybe
@@ -639,29 +609,36 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
let body = cx.enclosing_body?;
let map = cx.tcx.hir();
let mut span = map.body(body).value.span;
+ let mut maybe_global_var = false;
for (_, node) in map.parent_iter(body.hir_id) {
match node {
Node::Expr(e) => span = e.span,
- Node::Block(_)
- | Node::Arm(_)
- | Node::Stmt(_)
- | Node::Local(_)
- | Node::Item(hir::Item {
+ Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (),
+ Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
..
- }) => (),
+ }) => maybe_global_var = true,
+ Node::Item(hir::Item {
+ kind: hir::ItemKind::Mod(_),
+ span: item_span,
+ ..
+ }) => {
+ span = *item_span;
+ break;
+ },
+ Node::Crate(mod_) if maybe_global_var => {
+ span = mod_.spans.inner_span;
+ },
_ => break,
}
}
Some(span)
}
-fn span_in_body_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
+fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
let source_map = cx.sess().source_map();
let ctxt = span.ctxt();
- if ctxt == SyntaxContext::root()
- && let Some(search_span) = get_body_search_span(cx)
- {
+ if ctxt.is_root() && let Some(search_span) = get_body_search_span(cx) {
if let Ok(unsafe_line) = source_map.lookup_line(span.lo())
&& let Some(body_span) = walk_span_to_context(search_span, SyntaxContext::root())
&& let Ok(body_line) = source_map.lookup_line(body_span.lo())
@@ -671,13 +648,11 @@ fn span_in_body_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
// Get the text from the start of function body to the unsafe block.
// fn foo() { some_stuff; unsafe { stuff }; other_stuff; }
// ^-------------^
- unsafe_line.sf.lines(|lines| {
- body_line.line < unsafe_line.line && text_has_safety_comment(
- src,
- &lines[body_line.line + 1..=unsafe_line.line],
- unsafe_line.sf.start_pos.to_usize(),
- ).is_some()
- })
+ body_line.line < unsafe_line.line && text_has_safety_comment(
+ src,
+ &unsafe_line.sf.lines()[body_line.line + 1..=unsafe_line.line],
+ unsafe_line.sf.start_pos,
+ ).is_some()
} else {
// Problem getting source text. Pretend a comment was found.
true
@@ -688,13 +663,13 @@ fn span_in_body_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
}
/// Checks if the given text has a safety comment for the immediately proceeding line.
-fn text_has_safety_comment(src: &str, line_starts: &[BytePos], offset: usize) -> Option<BytePos> {
+fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos: BytePos) -> Option<BytePos> {
let mut lines = line_starts
.array_windows::<2>()
.rev()
.map_while(|[start, end]| {
- let start = start.to_usize() - offset;
- let end = end.to_usize() - offset;
+ let start = start.to_usize();
+ let end = end.to_usize();
let text = src.get(start..end)?;
let trimmed = text.trim_start();
Some((start + (text.len() - trimmed.len()), trimmed))
@@ -709,9 +684,7 @@ fn text_has_safety_comment(src: &str, line_starts: &[BytePos], offset: usize) ->
let (mut line, mut line_start) = (line, line_start);
loop {
if line.to_ascii_uppercase().contains("SAFETY:") {
- return Some(BytePos(
- u32::try_from(line_start).unwrap() + u32::try_from(offset).unwrap(),
- ));
+ return Some(start_pos + BytePos(u32::try_from(line_start).unwrap()));
}
match lines.next() {
Some((s, x)) if x.starts_with("//") => (line, line_start) = (x, s),
@@ -724,15 +697,13 @@ fn text_has_safety_comment(src: &str, line_starts: &[BytePos], offset: usize) ->
let (mut line_start, mut line) = (line_start, line);
loop {
if line.starts_with("/*") {
- let src = &src[line_start..line_starts.last().unwrap().to_usize() - offset];
+ let src = &src[line_start..line_starts.last().unwrap().to_usize()];
let mut tokens = tokenize(src);
return (src[..tokens.next().unwrap().len as usize]
.to_ascii_uppercase()
.contains("SAFETY:")
&& tokens.all(|t| t.kind == TokenKind::Whitespace))
- .then_some(BytePos(
- u32::try_from(line_start).unwrap() + u32::try_from(offset).unwrap(),
- ));
+ .then_some(start_pos + BytePos(u32::try_from(line_start).unwrap()));
}
match lines.next() {
Some(x) => (line_start, line) = x,
diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
index dd829ded0..de4b8738e 100644
--- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
@@ -26,7 +26,7 @@ declare_clippy_lint! {
///
/// ### Example
/// ```rust
- /// let mut twins = vec!((1, 1), (2, 2));
+ /// let mut twins = vec![(1, 1), (2, 2)];
/// twins.sort_by_key(|x| { x.1; });
/// ```
#[clippy::version = "1.47.0"]
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index 704d7abd7..e7915953d 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -7,7 +7,7 @@ use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Local, MatchSource, Node, PatKind, QPath, TyKind};
use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_middle::lint::{in_external_macro, is_from_async_await};
use rustc_middle::ty;
use super::LET_UNIT_VALUE;
@@ -16,6 +16,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
if let Some(init) = local.init
&& !local.pat.span.from_expansion()
&& !in_external_macro(cx.sess(), local.span)
+ && !is_from_async_await(local.span)
&& cx.typeck_results().pat_ty(local.pat).is_unit()
{
if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer))
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
new file mode 100644
index 000000000..5aa057580
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
@@ -0,0 +1,93 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::get_type_diagnostic_name;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Suggest removing the use of a may (or map_err) method when an Option or Result is being construted.
+ ///
+ /// ### Why is this bad?
+ /// It introduces unnecessary complexity. In this case the function can be used directly and
+ /// construct the Option or Result from the output.
+ ///
+ /// ### Example
+ /// ```rust
+ /// Some(4).map(i32::swap_bytes);
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// Some(i32::swap_bytes(4));
+ /// ```
+ #[clippy::version = "1.73.0"]
+ pub UNNECESSARY_MAP_ON_CONSTRUCTOR,
+ complexity,
+ "using `map`/`map_err` on `Option` or `Result` constructors"
+}
+declare_lint_pass!(UnnecessaryMapOnConstructor => [UNNECESSARY_MAP_ON_CONSTRUCTOR]);
+
+impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+ if expr.span.from_expansion() {
+ return;
+ }
+ if let hir::ExprKind::MethodCall(path, recv, args, ..) = expr.kind
+ && let Some(sym::Option | sym::Result) = get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(recv)){
+ let (constructor_path, constructor_item) =
+ if let hir::ExprKind::Call(constructor, constructor_args) = recv.kind
+ && let hir::ExprKind::Path(constructor_path) = constructor.kind
+ && let Some(arg) = constructor_args.get(0)
+ {
+ if constructor.span.from_expansion() || arg.span.from_expansion() {
+ return;
+ }
+ (constructor_path, arg)
+ } else {
+ return;
+ };
+ let constructor_symbol = match constructor_path {
+ hir::QPath::Resolved(_, path) => {
+ if let Some(path_segment) = path.segments.last() {
+ path_segment.ident.name
+ } else {
+ return;
+ }
+ },
+ hir::QPath::TypeRelative(_, path) => path.ident.name,
+ hir::QPath::LangItem(_, _, _) => return,
+ };
+ match constructor_symbol {
+ sym::Some | sym::Ok if path.ident.name == rustc_span::sym::map => (),
+ sym::Err if path.ident.name == sym!(map_err) => (),
+ _ => return,
+ }
+
+ if let Some(map_arg) = args.get(0)
+ && let hir::ExprKind::Path(fun) = map_arg.kind
+ {
+ if map_arg.span.from_expansion() {
+ return;
+ }
+ let mut applicability = Applicability::MachineApplicable;
+ let fun_snippet = snippet_with_applicability(cx, fun.span(), "_", &mut applicability);
+ let constructor_snippet =
+ snippet_with_applicability(cx, constructor_path.span(), "_", &mut applicability);
+ let constructor_arg_snippet =
+ snippet_with_applicability(cx, constructor_item.span, "_", &mut applicability);
+ span_lint_and_sugg(
+ cx,
+ UNNECESSARY_MAP_ON_CONSTRUCTOR,
+ expr.span,
+ &format!("unnecessary {} on constructor {constructor_snippet}(_)", path.ident.name),
+ "try",
+ format!("{constructor_snippet}({fun_snippet}({constructor_arg_snippet}))"),
+ applicability,
+ );
+ }
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 9cf595772..766a54814 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -68,7 +68,7 @@ impl EarlyLintPass for UnnestedOrPatterns {
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
if self.msrv.meets(msrvs::OR_PATTERNS) {
- if let ast::ExprKind::Let(pat, _, _) = &e.kind {
+ if let ast::ExprKind::Let(pat, _, _, _) = &e.kind {
lint_unnested_or_patterns(cx, pat);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index c99b0290c..9a0d83d83 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -1,15 +1,18 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::usage::is_potentially_mutated;
+use clippy_utils::usage::is_potentially_local_place;
use clippy_utils::{higher, path_to_local};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
-use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, PathSegment, UnOp};
+use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegment, UnOp};
+use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId};
+use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::Ty;
+use rustc_middle::mir::FakeReadCause;
+use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::def_id::LocalDefId;
use rustc_span::source_map::Span;
@@ -192,6 +195,55 @@ fn collect_unwrap_info<'tcx>(
Vec::new()
}
+/// A HIR visitor delegate that checks if a local variable of type `Option<_>` is mutated,
+/// *except* for if `Option::as_mut` is called.
+/// The reason for why we allow that one specifically is that `.as_mut()` cannot change
+/// the option to `None`, and that is important because this lint relies on the fact that
+/// `is_some` + `unwrap` is equivalent to `if let Some(..) = ..`, which it would not be if
+/// the option is changed to None between `is_some` and `unwrap`.
+/// (And also `.as_mut()` is a somewhat common method that is still worth linting on.)
+struct MutationVisitor<'tcx> {
+ is_mutated: bool,
+ local_id: HirId,
+ tcx: TyCtxt<'tcx>,
+}
+
+/// Checks if the parent of the expression pointed at by the given `HirId` is a call to
+/// `Option::as_mut`.
+///
+/// Used by the mutation visitor to specifically allow `.as_mut()` calls.
+/// In particular, the `HirId` that the visitor receives is the id of the local expression
+/// (i.e. the `x` in `x.as_mut()`), and that is the reason for why we care about its parent
+/// expression: that will be where the actual method call is.
+fn is_option_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool {
+ if let Node::Expr(mutating_expr) = tcx.hir().get_parent(expr_id)
+ && let ExprKind::MethodCall(path, ..) = mutating_expr.kind
+ {
+ path.ident.name.as_str() == "as_mut"
+ } else {
+ false
+ }
+}
+
+impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx> {
+ fn borrow(&mut self, cat: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) {
+ if let ty::BorrowKind::MutBorrow = bk
+ && is_potentially_local_place(self.local_id, &cat.place)
+ && !is_option_as_mut_use(self.tcx, diag_expr_id)
+ {
+ self.is_mutated = true;
+ }
+ }
+
+ fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {
+ self.is_mutated = true;
+ }
+
+ fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
+
+ fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
+}
+
impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> {
fn visit_branch(
&mut self,
@@ -202,10 +254,26 @@ impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> {
) {
let prev_len = self.unwrappables.len();
for unwrap_info in collect_unwrap_info(self.cx, if_expr, cond, branch, else_branch, true) {
- if is_potentially_mutated(unwrap_info.local_id, cond, self.cx)
- || is_potentially_mutated(unwrap_info.local_id, branch, self.cx)
- {
- // if the variable is mutated, we don't know whether it can be unwrapped:
+ let mut delegate = MutationVisitor {
+ tcx: self.cx.tcx,
+ is_mutated: false,
+ local_id: unwrap_info.local_id,
+ };
+
+ let infcx = self.cx.tcx.infer_ctxt().build();
+ let mut vis = ExprUseVisitor::new(
+ &mut delegate,
+ &infcx,
+ cond.hir_id.owner.def_id,
+ self.cx.param_env,
+ self.cx.typeck_results(),
+ );
+ vis.walk_expr(cond);
+ vis.walk_expr(branch);
+
+ if delegate.is_mutated {
+ // if the variable is mutated, we don't know whether it can be unwrapped.
+ // it might have been changed to `None` in between `is_some` + `unwrap`.
continue;
}
self.unwrappables.push(unwrap_info);
@@ -215,6 +283,27 @@ impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> {
}
}
+enum AsRefKind {
+ AsRef,
+ AsMut,
+}
+
+/// Checks if the expression is a method call to `as_{ref,mut}` and returns the receiver of it.
+/// If it isn't, the expression itself is returned.
+fn consume_option_as_ref<'tcx>(expr: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, Option<AsRefKind>) {
+ if let ExprKind::MethodCall(path, recv, ..) = expr.kind {
+ if path.ident.name == sym::as_ref {
+ (recv, Some(AsRefKind::AsRef))
+ } else if path.ident.name.as_str() == "as_mut" {
+ (recv, Some(AsRefKind::AsMut))
+ } else {
+ (expr, None)
+ }
+ } else {
+ (expr, None)
+ }
+}
+
impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies;
@@ -233,6 +322,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
// find `unwrap[_err]()` calls:
if_chain! {
if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind;
+ let (self_arg, as_ref_kind) = consume_option_as_ref(self_arg);
if let Some(id) = path_to_local(self_arg);
if [sym::unwrap, sym::expect, sym!(unwrap_err)].contains(&method_name.ident.name);
let call_to_unwrap = [sym::unwrap, sym::expect].contains(&method_name.ident.name);
@@ -268,7 +358,12 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
unwrappable.check.span.with_lo(unwrappable.if_expr.span.lo()),
"try",
format!(
- "if let {suggested_pattern} = {unwrappable_variable_name}",
+ "if let {suggested_pattern} = {borrow_prefix}{unwrappable_variable_name}",
+ borrow_prefix = match as_ref_kind {
+ Some(AsRefKind::AsRef) => "&",
+ Some(AsRefKind::AsMut) => "&mut ",
+ None => "",
+ },
),
// We don't track how the unwrapped value is used inside the
// block or suggest deleting the unwrap, so we can't offer a
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 5ac4f0aa4..f32e7edad 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -8,10 +8,14 @@ use rustc_errors::Applicability;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, MatchSource, Node, PatKind};
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::traits::Obligation;
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
+use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{sym, Span};
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
declare_clippy_lint! {
/// ### What it does
@@ -61,22 +65,69 @@ impl MethodOrFunction {
}
}
-/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did`
-fn into_iter_bound(cx: &LateContext<'_>, fn_did: DefId, into_iter_did: DefId, param_index: u32) -> Option<Span> {
- cx.tcx
- .predicates_of(fn_did)
- .predicates
- .iter()
- .find_map(|&(ref pred, span)| {
- if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder()
- && tr.def_id() == into_iter_did
- && tr.self_ty().is_param(param_index)
- {
- Some(span)
- } else {
- None
+/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did`,
+/// iff all of the bounds also hold for the type of the `.into_iter()` receiver.
+/// ```ignore
+/// pub fn foo<I>(i: I)
+/// where I: IntoIterator<Item=i32> + ExactSizeIterator
+/// ^^^^^^^^^^^^^^^^^ this extra bound stops us from suggesting to remove `.into_iter()` ...
+/// {
+/// assert_eq!(i.len(), 3);
+/// }
+///
+/// pub fn bar() {
+/// foo([1, 2, 3].into_iter());
+/// ^^^^^^^^^^^^ ... here, because `[i32; 3]` is not `ExactSizeIterator`
+/// }
+/// ```
+fn into_iter_bound<'tcx>(
+ cx: &LateContext<'tcx>,
+ fn_did: DefId,
+ into_iter_did: DefId,
+ into_iter_receiver: Ty<'tcx>,
+ param_index: u32,
+ node_args: GenericArgsRef<'tcx>,
+) -> Option<Span> {
+ let param_env = cx.tcx.param_env(fn_did);
+ let mut into_iter_span = None;
+
+ for (pred, span) in cx.tcx.explicit_predicates_of(fn_did).predicates {
+ if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder() {
+ if tr.self_ty().is_param(param_index) {
+ if tr.def_id() == into_iter_did {
+ into_iter_span = Some(*span);
+ } else {
+ let tr = cx.tcx.erase_regions(tr);
+ if tr.has_escaping_bound_vars() {
+ return None;
+ }
+
+ // Substitute generics in the predicate and replace the IntoIterator type parameter with the
+ // `.into_iter()` receiver to see if the bound also holds for that type.
+ let args = cx.tcx.mk_args_from_iter(node_args.iter().enumerate().map(|(i, arg)| {
+ if i == param_index as usize {
+ GenericArg::from(into_iter_receiver)
+ } else {
+ arg
+ }
+ }));
+
+ let predicate = EarlyBinder::bind(tr).instantiate(cx.tcx, args);
+ let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), param_env, predicate);
+ if !cx
+ .tcx
+ .infer_ctxt()
+ .build()
+ .predicate_must_hold_modulo_regions(&obligation)
+ {
+ return None;
+ }
+ }
}
- })
+ }
+ }
+
+ into_iter_span
}
/// Extracts the receiver of a `.into_iter()` method call.
@@ -160,22 +211,41 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
// `fn_sig` does not ICE. (see #11065)
&& cx.tcx.opt_def_kind(did).is_some_and(DefKind::is_fn_like) =>
{
- Some((did, args, MethodOrFunction::Function))
+ Some((
+ did,
+ args,
+ cx.typeck_results().node_args(recv.hir_id),
+ MethodOrFunction::Function
+ ))
}
ExprKind::MethodCall(.., args, _) => {
cx.typeck_results().type_dependent_def_id(parent.hir_id)
- .map(|did| (did, args, MethodOrFunction::Method))
+ .map(|did| {
+ return (
+ did,
+ args,
+ cx.typeck_results().node_args(parent.hir_id),
+ MethodOrFunction::Method
+ );
+ })
}
_ => None,
};
- if let Some((parent_fn_did, args, kind)) = parent_fn
+ if let Some((parent_fn_did, args, node_args, kind)) = parent_fn
&& let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
&& let sig = cx.tcx.fn_sig(parent_fn_did).skip_binder().skip_binder()
&& let Some(arg_pos) = args.iter().position(|x| x.hir_id == e.hir_id)
&& let Some(&into_iter_param) = sig.inputs().get(kind.param_pos(arg_pos))
&& let ty::Param(param) = into_iter_param.kind()
- && let Some(span) = into_iter_bound(cx, parent_fn_did, into_iter_did, param.index)
+ && let Some(span) = into_iter_bound(
+ cx,
+ parent_fn_did,
+ into_iter_did,
+ cx.typeck_results().expr_ty(into_iter_recv),
+ param.index,
+ node_args
+ )
&& self.expn_depth == 0
{
// Get the "innermost" `.into_iter()` call, e.g. given this expression:
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 58ae0656d..75c3c7a95 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -542,11 +542,11 @@ define_Conf! {
/// Lint: UNDOCUMENTED_UNSAFE_BLOCKS.
///
/// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
- (accept_comment_above_statement: bool = false),
+ (accept_comment_above_statement: bool = true),
/// Lint: UNDOCUMENTED_UNSAFE_BLOCKS.
///
/// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
- (accept_comment_above_attributes: bool = false),
+ (accept_comment_above_attributes: bool = true),
/// Lint: UNNECESSARY_RAW_STRING_HASHES.
///
/// Whether to allow `r#""#` when `r""` can be used
@@ -561,6 +561,31 @@ define_Conf! {
/// Which crates to allow absolute paths from
(absolute_paths_allowed_crates: rustc_data_structures::fx::FxHashSet<String> =
rustc_data_structures::fx::FxHashSet::default()),
+ /// Lint: PATH_ENDS_WITH_EXT.
+ ///
+ /// Additional dotfiles (files or directories starting with a dot) to allow
+ (allowed_dotfiles: rustc_data_structures::fx::FxHashSet<String> =
+ rustc_data_structures::fx::FxHashSet::default()),
+ /// Lint: EXPLICIT_ITER_LOOP
+ ///
+ /// Whether to recommend using implicit into iter for reborrowed values.
+ ///
+ /// #### Example
+ /// ```
+ /// let mut vec = vec![1, 2, 3];
+ /// let rmvec = &mut vec;
+ /// for _ in rmvec.iter() {}
+ /// for _ in rmvec.iter_mut() {}
+ /// ```
+ ///
+ /// Use instead:
+ /// ```
+ /// let mut vec = vec![1, 2, 3];
+ /// let rmvec = &mut vec;
+ /// for _ in &*rmvec {}
+ /// for _ in &mut *rmvec {}
+ /// ```
+ (enforce_iter_loop_reborrow: bool = false),
}
/// Search for the configuration file.
diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
index 6d3493523..94a9a7c24 100644
--- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
@@ -1,12 +1,15 @@
-use clippy_utils::macros::collect_ast_format_args;
+use clippy_utils::macros::AST_FORMAT_ARGS;
use clippy_utils::source::snippet_opt;
use itertools::Itertools;
-use rustc_ast::{Expr, ExprKind, FormatArgs};
+use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
+use rustc_data_structures::fx::FxHashMap;
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{EarlyContext, EarlyLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::hygiene;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{hygiene, Span};
use std::iter::once;
+use std::mem;
+use std::rc::Rc;
declare_clippy_lint! {
/// ### What it does
@@ -17,7 +20,12 @@ declare_clippy_lint! {
"collects `format_args` AST nodes for use in later lints"
}
-declare_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]);
+#[derive(Default)]
+pub struct FormatArgsCollector {
+ format_args: FxHashMap<Span, Rc<FormatArgs>>,
+}
+
+impl_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]);
impl EarlyLintPass for FormatArgsCollector {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
@@ -26,9 +34,17 @@ impl EarlyLintPass for FormatArgsCollector {
return;
}
- collect_ast_format_args(expr.span, args);
+ self.format_args
+ .insert(expr.span.with_parent(None), Rc::new((**args).clone()));
}
}
+
+ fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &Crate) {
+ AST_FORMAT_ARGS.with(|ast_format_args| {
+ let result = ast_format_args.set(mem::take(&mut self.format_args));
+ debug_assert!(result.is_ok());
+ });
+ }
}
/// Detects if the format string or an argument has its span set by a proc macro to something inside
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
index da8654d93..82f9d4e41 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
@@ -10,7 +10,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::interpret::ConstValue;
+use rustc_middle::mir::ConstValue;
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::Symbol;
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 4ed985f54..250772238 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -5,10 +5,9 @@ use if_chain::if_chain;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::Item;
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::{self, FloatTy};
+use rustc_middle::ty::FloatTy;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::Symbol;
@@ -34,25 +33,20 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
let mod_name = &cx.tcx.item_name(local_def_id.to_def_id());
if_chain! {
if mod_name.as_str() == "paths";
- if let hir::ItemKind::Const(ty, _, body_id) = item.kind;
- let ty = hir_ty_to_ty(cx.tcx, ty);
- if let ty::Array(el_ty, _) = &ty.kind();
- if let ty::Ref(_, el_ty, _) = &el_ty.kind();
- if el_ty.is_str();
+ if let hir::ItemKind::Const(.., body_id) = item.kind;
let body = cx.tcx.hir().body(body_id);
let typeck_results = cx.tcx.typeck_body(body_id);
if let Some(Constant::Vec(path)) = constant_simple(cx, typeck_results, body.value);
- let path: Vec<&str> = path
+ if let Some(path) = path
.iter()
.map(|x| {
if let Constant::Str(s) = x {
- s.as_str()
+ Some(s.as_str())
} else {
- // We checked the type of the constant above
- unreachable!()
+ None
}
})
- .collect();
+ .collect::<Option<Vec<&str>>>();
if !check_path(cx, &path[..]);
then {
span_lint(cx, INVALID_PATHS, item.span, "invalid path");
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index 87380f14f..bbb5ade8b 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -28,8 +28,8 @@ declare_clippy_lint! {
/// know the name of the lint.
///
/// ### Known problems
- /// Only checks for lints associated using the
- /// `declare_lint_pass!`, `impl_lint_pass!`, and `lint_array!` macros.
+ /// Only checks for lints associated using the `declare_lint_pass!` and
+ /// `impl_lint_pass!` macros.
///
/// ### Example
/// ```rust,ignore
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index f49c3fadb..c38a3e81b 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -31,7 +31,7 @@ use serde::{Serialize, Serializer};
use std::collections::{BTreeSet, BinaryHeap};
use std::fmt;
use std::fmt::Write as _;
-use std::fs::{self, OpenOptions};
+use std::fs::{self, File};
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::process::Command;
@@ -229,25 +229,10 @@ impl Drop for MetadataCollector {
collect_renames(&mut lints);
// Outputting json
- if Path::new(JSON_OUTPUT_FILE).exists() {
- fs::remove_file(JSON_OUTPUT_FILE).unwrap();
- }
- let mut file = OpenOptions::new()
- .write(true)
- .create(true)
- .open(JSON_OUTPUT_FILE)
- .unwrap();
- writeln!(file, "{}", serde_json::to_string_pretty(&lints).unwrap()).unwrap();
+ fs::write(JSON_OUTPUT_FILE, serde_json::to_string_pretty(&lints).unwrap()).unwrap();
// Outputting markdown
- if Path::new(MARKDOWN_OUTPUT_FILE).exists() {
- fs::remove_file(MARKDOWN_OUTPUT_FILE).unwrap();
- }
- let mut file = OpenOptions::new()
- .write(true)
- .create(true)
- .open(MARKDOWN_OUTPUT_FILE)
- .unwrap();
+ let mut file = File::create(MARKDOWN_OUTPUT_FILE).unwrap();
writeln!(
file,
"<!--
@@ -261,17 +246,15 @@ Please use that command to update the file and do not edit it by hand.
.unwrap();
// Write configuration links to CHANGELOG.md
- let mut changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap();
- let mut changelog_file = OpenOptions::new().read(true).write(true).open(CHANGELOG_PATH).unwrap();
-
- if let Some(position) = changelog.find("<!-- begin autogenerated links to configuration documentation -->") {
- // I know this is kinda wasteful, we just don't have regex on `clippy_lints` so... this is the best
- // we can do AFAIK.
- changelog = changelog[..position].to_string();
- }
+ let changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap();
+ let mut changelog_file = File::create(CHANGELOG_PATH).unwrap();
+ let position = changelog
+ .find("<!-- begin autogenerated links to configuration documentation -->")
+ .unwrap();
writeln!(
changelog_file,
- "{changelog}<!-- begin autogenerated links to configuration documentation -->\n{}\n<!-- end autogenerated links to configuration documentation -->",
+ "{}<!-- begin autogenerated links to configuration documentation -->\n{}\n<!-- end autogenerated links to configuration documentation -->",
+ &changelog[..position],
self.configs_to_markdown(ClippyConfiguration::to_markdown_link)
)
.unwrap();
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
index bf835f89c..86b77a77f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
@@ -5,9 +5,8 @@ use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::{self, GenericArgKind};
+use rustc_middle::ty::{self, EarlyBinder, GenericArgKind};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@@ -25,16 +24,14 @@ impl LateLintPass<'_> for MsrvAttrImpl {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
if_chain! {
if let hir::ItemKind::Impl(hir::Impl {
- of_trait: Some(lint_pass_trait_ref),
- self_ty,
+ of_trait: Some(_),
items,
..
}) = &item.kind;
- if let Some(lint_pass_trait_def_id) = lint_pass_trait_ref.trait_def_id();
- let is_late_pass = match_def_path(cx, lint_pass_trait_def_id, &paths::LATE_LINT_PASS);
- if is_late_pass || match_def_path(cx, lint_pass_trait_def_id, &paths::EARLY_LINT_PASS);
- let self_ty = hir_ty_to_ty(cx.tcx, self_ty);
- if let ty::Adt(self_ty_def, _) = self_ty.kind();
+ if let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::instantiate_identity);
+ let is_late_pass = match_def_path(cx, trait_ref.def_id, &paths::LATE_LINT_PASS);
+ if is_late_pass || match_def_path(cx, trait_ref.def_id, &paths::EARLY_LINT_PASS);
+ if let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind();
if self_ty_def.is_struct();
if self_ty_def.all_fields().any(|f| {
cx.tcx
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index f66f33fee..a3acb8f17 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -10,7 +10,8 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::interpret::{Allocation, ConstValue, GlobalAlloc};
+use rustc_middle::mir::interpret::{Allocation, GlobalAlloc};
+use rustc_middle::mir::ConstValue;
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::Symbol;
@@ -232,7 +233,8 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
cx.tcx.type_of(def_id).instantiate_identity(),
),
Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? {
- ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => {
+ ConstValue::Indirect { alloc_id, offset } if offset.bytes() == 0 => {
+ let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory();
read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).instantiate_identity())
},
_ => None,
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index a9957b18a..da083fb14 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -304,7 +304,7 @@ impl<'tcx> LateLintPass<'tcx> for Write {
_ => return,
}
- find_format_args(cx, expr, macro_call.expn, |format_args| {
+ if let Some(format_args) = find_format_args(cx, expr, macro_call.expn) {
// ignore `writeln!(w)` and `write!(v, some_macro!())`
if format_args.span.from_expansion() {
return;
@@ -312,15 +312,15 @@ impl<'tcx> LateLintPass<'tcx> for Write {
match diag_name {
sym::print_macro | sym::eprint_macro | sym::write_macro => {
- check_newline(cx, format_args, &macro_call, name);
+ check_newline(cx, &format_args, &macro_call, name);
},
sym::println_macro | sym::eprintln_macro | sym::writeln_macro => {
- check_empty_string(cx, format_args, &macro_call, name);
+ check_empty_string(cx, &format_args, &macro_call, name);
},
_ => {},
}
- check_literal(cx, format_args, name);
+ check_literal(cx, &format_args, name);
if !self.in_debug_impl {
for piece in &format_args.template {
@@ -334,7 +334,7 @@ impl<'tcx> LateLintPass<'tcx> for Write {
}
}
}
- });
+ }
}
}
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 3926b954e..1596bb773 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
-version = "0.1.73"
+version = "0.1.74"
edition = "2021"
publish = false
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 140cfa219..a78ff0202 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -166,7 +166,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r),
(Lit(l), Lit(r)) => l == r,
(Cast(l, lt), Cast(r, rt)) | (Type(l, lt), Type(r, rt)) => eq_expr(l, r) && eq_ty(lt, rt),
- (Let(lp, le, _), Let(rp, re, _)) => eq_pat(lp, rp) && eq_expr(le, re),
+ (Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re),
(If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re),
(While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt),
(ForLoop(lp, li, lt, ll), ForLoop(rp, ri, rt, rl)) => {
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 6d57af325..d596eed4b 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -21,7 +21,7 @@ use std::iter;
/// A `LitKind`-like enum to fold constant `Expr`s into.
#[derive(Debug, Clone)]
pub enum Constant<'tcx> {
- Adt(rustc_middle::mir::ConstantKind<'tcx>),
+ Adt(rustc_middle::mir::Const<'tcx>),
/// A `String` (e.g., "abc").
Str(String),
/// A binary string (e.g., `b"abc"`).
@@ -482,7 +482,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
.tcx
.const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None)
.ok()
- .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?;
+ .map(|val| rustc_middle::mir::Const::from_value(val, ty))?;
let result = miri_to_const(self.lcx, result)?;
self.source = ConstantSource::Constant;
Some(result)
@@ -655,10 +655,10 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
}
}
-pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'tcx>) -> Option<Constant<'tcx>> {
- use rustc_middle::mir::interpret::ConstValue;
+pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> Option<Constant<'tcx>> {
+ use rustc_middle::mir::ConstValue;
match result {
- mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() {
+ mir::Const::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() {
ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)),
ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)),
ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))),
@@ -671,47 +671,42 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'t
ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))),
_ => None,
},
- mir::ConstantKind::Val(ConstValue::Slice { data, start, end }, _) => match result.ty().kind() {
- ty::Ref(_, tam, _) => match tam.kind() {
- ty::Str => String::from_utf8(
- data.inner()
- .inspect_with_uninit_and_ptr_outside_interpreter(start..end)
- .to_owned(),
- )
- .ok()
- .map(Constant::Str),
- _ => None,
- },
- _ => None,
+ mir::Const::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) =>
+ {
+ let data = cv.try_get_slice_bytes_for_diagnostics(lcx.tcx)?;
+ String::from_utf8(data.to_owned()).ok().map(Constant::Str)
},
- mir::ConstantKind::Val(ConstValue::ByRef { alloc, offset: _ }, _) => match result.ty().kind() {
- ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)),
- ty::Array(sub_type, len) => match sub_type.kind() {
- ty::Float(FloatTy::F32) => match len.try_to_target_usize(lcx.tcx) {
- Some(len) => alloc
- .inner()
- .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap()))
- .to_owned()
- .array_chunks::<4>()
- .map(|&chunk| Some(Constant::F32(f32::from_le_bytes(chunk))))
- .collect::<Option<Vec<Constant<'tcx>>>>()
- .map(Constant::Vec),
- _ => None,
- },
- ty::Float(FloatTy::F64) => match len.try_to_target_usize(lcx.tcx) {
- Some(len) => alloc
- .inner()
- .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap()))
- .to_owned()
- .array_chunks::<8>()
- .map(|&chunk| Some(Constant::F64(f64::from_le_bytes(chunk))))
- .collect::<Option<Vec<Constant<'tcx>>>>()
- .map(Constant::Vec),
+ mir::Const::Val(ConstValue::Indirect { alloc_id, offset: _ }, _) => {
+ let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory();
+ match result.ty().kind() {
+ ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)),
+ ty::Array(sub_type, len) => match sub_type.kind() {
+ ty::Float(FloatTy::F32) => match len.try_to_target_usize(lcx.tcx) {
+ Some(len) => alloc
+ .inner()
+ .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap()))
+ .to_owned()
+ .array_chunks::<4>()
+ .map(|&chunk| Some(Constant::F32(f32::from_le_bytes(chunk))))
+ .collect::<Option<Vec<Constant<'tcx>>>>()
+ .map(Constant::Vec),
+ _ => None,
+ },
+ ty::Float(FloatTy::F64) => match len.try_to_target_usize(lcx.tcx) {
+ Some(len) => alloc
+ .inner()
+ .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap()))
+ .to_owned()
+ .array_chunks::<8>()
+ .map(|&chunk| Some(Constant::F64(f64::from_le_bytes(chunk))))
+ .collect::<Option<Vec<Constant<'tcx>>>>()
+ .map(Constant::Vec),
+ _ => None,
+ },
_ => None,
},
_ => None,
- },
- _ => None,
+ }
},
_ => None,
}
@@ -720,17 +715,17 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'t
fn field_of_struct<'tcx>(
adt_def: ty::AdtDef<'tcx>,
lcx: &LateContext<'tcx>,
- result: mir::ConstantKind<'tcx>,
+ result: mir::Const<'tcx>,
field: &Ident,
-) -> Option<mir::ConstantKind<'tcx>> {
- if let mir::ConstantKind::Val(result, ty) = result
- && let Some(dc) = rustc_const_eval::const_eval::try_destructure_mir_constant_for_diagnostics(lcx.tcx, result, ty)
+) -> Option<mir::Const<'tcx>> {
+ if let mir::Const::Val(result, ty) = result
+ && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics(result, ty)
&& let Some(dc_variant) = dc.variant
&& let Some(variant) = adt_def.variants().get(dc_variant)
&& let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name)
&& let Some(&(val, ty)) = dc.fields.get(field_idx)
{
- Some(mir::ConstantKind::Val(val, ty))
+ Some(mir::Const::Val(val, ty))
}
else {
None
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index fdc35cd4d..52214e733 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -5,6 +5,7 @@ use crate::tokenize_with_text;
use rustc_ast::ast::InlineAsmTemplatePiece;
use rustc_data_structures::fx::FxHasher;
use rustc_hir::def::Res;
+use rustc_hir::MatchSource::TryDesugar;
use rustc_hir::{
ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
GenericArgs, Guard, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
@@ -311,7 +312,7 @@ impl HirEqInterExpr<'_, '_, '_> {
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
},
(&ExprKind::Match(le, la, ref ls), &ExprKind::Match(re, ra, ref rs)) => {
- ls == rs
+ (ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_)))))
&& self.eq_expr(le, re)
&& over(la, ra, |l, r| {
self.eq_pat(l.pat, r.pat)
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 6c4cec595..13da79fba 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -5,6 +5,7 @@
#![feature(lint_reasons)]
#![feature(never_type)]
#![feature(rustc_private)]
+#![feature(assert_matches)]
#![recursion_limit = "512"]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::must_use_candidate)]
@@ -89,14 +90,14 @@ use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
use rustc_hir::{
self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr,
- ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item,
+ ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item,
ItemKind, LangItem, Local, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy,
QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
};
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{LateContext, Level, Lint, LintContext};
use rustc_middle::hir::place::PlaceBase;
-use rustc_middle::mir::ConstantKind;
+use rustc_middle::mir::Const;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::binding::BindingMode;
use rustc_middle::ty::fast_reject::SimplifiedType;
@@ -110,6 +111,7 @@ use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::{sym, Span};
use rustc_target::abi::Integer;
+use visitors::Visitable;
use crate::consts::{constant, miri_to_const, Constant};
use crate::higher::Range;
@@ -286,7 +288,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
/// Checks if the given `QPath` belongs to a type alias.
pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
match *qpath {
- QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, ..)),
+ QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)),
QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) },
_ => false,
}
@@ -1286,7 +1288,7 @@ pub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext<
}
/// Returns `true` if `expr` contains a return expression
-pub fn contains_return(expr: &hir::Expr<'_>) -> bool {
+pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool {
for_each_expr(expr, |e| {
if matches!(e.kind, hir::ExprKind::Ret(..)) {
ControlFlow::Break(())
@@ -1508,7 +1510,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
&& let bnd_ty = subst.type_at(0)
&& let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx)
&& let const_val = cx.tcx.valtree_to_const_val((bnd_ty, min_val.to_valtree()))
- && let min_const_kind = ConstantKind::from_value(const_val, bnd_ty)
+ && let min_const_kind = Const::from_value(const_val, bnd_ty)
&& let Some(min_const) = miri_to_const(cx, min_const_kind)
&& let Some(start_const) = constant(cx, cx.typeck_results(), start)
{
@@ -1524,7 +1526,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
&& let bnd_ty = subst.type_at(0)
&& let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx)
&& let const_val = cx.tcx.valtree_to_const_val((bnd_ty, max_val.to_valtree()))
- && let max_const_kind = ConstantKind::from_value(const_val, bnd_ty)
+ && let max_const_kind = Const::from_value(const_val, bnd_ty)
&& let Some(max_const) = miri_to_const(cx, max_const_kind)
&& let Some(end_const) = constant(cx, cx.typeck_results(), end)
{
@@ -1783,6 +1785,33 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc
None
}
+/// Returns `true` if the lint is `#[allow]`ed or `#[expect]`ed at any of the `ids`, fulfilling all
+/// of the expectations in `ids`
+///
+/// This should only be used when the lint would otherwise be emitted, for a way to check if a lint
+/// is allowed early to skip work see [`is_lint_allowed`]
+///
+/// To emit at a lint at a different context than the one current see
+/// [`span_lint_hir`](diagnostics::span_lint_hir) or
+/// [`span_lint_hir_and_then`](diagnostics::span_lint_hir_and_then)
+pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl IntoIterator<Item = HirId>) -> bool {
+ let mut suppress_lint = false;
+
+ for id in ids {
+ let (level, _) = cx.tcx.lint_level_at_node(lint, id);
+ if let Some(expectation) = level.get_expectation_id() {
+ cx.fulfill_expectation(expectation);
+ }
+
+ match level {
+ Level::Allow | Level::Expect(_) => suppress_lint = true,
+ Level::Warn | Level::ForceWarn(_) | Level::Deny | Level::Forbid => {},
+ }
+ }
+
+ suppress_lint
+}
+
/// Returns `true` if the lint is allowed in the current context. This is useful for
/// skipping long running code when it's unnecessary
///
@@ -1956,8 +1985,8 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
/// Checks if the given function kind is an async function.
pub fn is_async_fn(kind: FnKind<'_>) -> bool {
match kind {
- FnKind::ItemFn(_, _, header) => header.asyncness == IsAsync::Async,
- FnKind::Method(_, sig) => sig.header.asyncness == IsAsync::Async,
+ FnKind::ItemFn(_, _, header) => header.asyncness.is_async(),
+ FnKind::Method(_, sig) => sig.header.asyncness.is_async(),
FnKind::Closure => false,
}
}
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 173f9841d..82508bcdb 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -10,8 +10,9 @@ use rustc_lint::LateContext;
use rustc_span::def_id::DefId;
use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol};
-use std::cell::RefCell;
+use std::cell::OnceCell;
use std::ops::ControlFlow;
+use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
@@ -374,28 +375,21 @@ thread_local! {
/// A thread local is used because [`FormatArgs`] is `!Send` and `!Sync`, we are making an
/// assumption that the early pass that populates the map and the later late passes will all be
/// running on the same thread.
- static AST_FORMAT_ARGS: RefCell<FxHashMap<Span, FormatArgs>> = {
+ #[doc(hidden)]
+ pub static AST_FORMAT_ARGS: OnceCell<FxHashMap<Span, Rc<FormatArgs>>> = {
static CALLED: AtomicBool = AtomicBool::new(false);
debug_assert!(
!CALLED.swap(true, Ordering::SeqCst),
"incorrect assumption: `AST_FORMAT_ARGS` should only be accessed by a single thread",
);
- RefCell::default()
+ OnceCell::new()
};
}
-/// Record [`rustc_ast::FormatArgs`] for use in late lint passes, this should only be called by
-/// `FormatArgsCollector`
-pub fn collect_ast_format_args(span: Span, format_args: &FormatArgs) {
- AST_FORMAT_ARGS.with(|ast_format_args| {
- ast_format_args.borrow_mut().insert(span, format_args.clone());
- });
-}
-
-/// Calls `callback` with an AST [`FormatArgs`] node if a `format_args` expansion is found as a
-/// descendant of `expn_id`
-pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId, callback: impl FnOnce(&FormatArgs)) {
+/// Returns an AST [`FormatArgs`] node if a `format_args` expansion is found as a descendant of
+/// `expn_id`
+pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId) -> Option<Rc<FormatArgs>> {
let format_args_expr = for_each_expr(start, |expr| {
let ctxt = expr.span.ctxt();
if ctxt.outer_expn().is_descendant_of(expn_id) {
@@ -410,13 +404,14 @@ pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId,
} else {
ControlFlow::Continue(Descend::No)
}
- });
+ })?;
- if let Some(expr) = format_args_expr {
- AST_FORMAT_ARGS.with(|ast_format_args| {
- ast_format_args.borrow().get(&expr.span).map(callback);
- });
- }
+ AST_FORMAT_ARGS.with(|ast_format_args| {
+ ast_format_args
+ .get()?
+ .get(&format_args_expr.span.with_parent(None))
+ .map(Rc::clone)
+ })
}
/// Attempt to find the [`rustc_hir::Expr`] that corresponds to the [`FormatArgument`]'s value, if
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 131f3c0aa..9dbb4c68d 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -1,7 +1,8 @@
use rustc_hir::{Expr, HirId};
+use rustc_index::bit_set::BitSet;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{
- traversal, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
+ traversal, BasicBlock, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
};
use rustc_middle::ty::TyCtxt;
@@ -29,20 +30,26 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) -
locals.len()
];
- traversal::ReversePostorder::new(mir, location.block).try_fold(init, |usage, (tbb, tdata)| {
- // Give up on loops
- if tdata.terminator().successors().any(|s| s == location.block) {
- return None;
- }
+ traversal::Postorder::new(&mir.basic_blocks, location.block)
+ .collect::<Vec<_>>()
+ .into_iter()
+ .rev()
+ .try_fold(init, |usage, tbb| {
+ let tdata = &mir.basic_blocks[tbb];
- let mut v = V {
- locals,
- location,
- results: usage,
- };
- v.visit_basic_block_data(tbb, tdata);
- Some(v.results)
- })
+ // Give up on loops
+ if tdata.terminator().successors().any(|s| s == location.block) {
+ return None;
+ }
+
+ let mut v = V {
+ locals,
+ location,
+ results: usage,
+ };
+ v.visit_basic_block_data(tbb, tdata);
+ Some(v.results)
+ })
}
struct V<'a> {
@@ -79,8 +86,32 @@ impl<'a, 'tcx> Visitor<'tcx> for V<'a> {
}
}
+/// Checks if the block is part of a cycle
+pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {
+ let mut seen = BitSet::new_empty(body.basic_blocks.len());
+ let mut to_visit = Vec::with_capacity(body.basic_blocks.len() / 2);
+
+ seen.insert(block);
+ let mut next = block;
+ loop {
+ for succ in body.basic_blocks[next].terminator().successors() {
+ if seen.insert(succ) {
+ to_visit.push(succ);
+ } else if succ == block {
+ return true;
+ }
+ }
+
+ if let Some(x) = to_visit.pop() {
+ next = x;
+ } else {
+ return false;
+ }
+ }
+}
+
/// Convenience wrapper around `visit_local_usage`.
-pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> {
+pub fn used_exactly_once(mir: &Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> {
visit_local_usage(
&[local],
mir,
@@ -91,11 +122,14 @@ pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle:
)
.map(|mut vec| {
let LocalUsage { local_use_locs, .. } = vec.remove(0);
- local_use_locs
+ let mut locations = local_use_locs
.into_iter()
- .filter(|location| !is_local_assignment(mir, local, *location))
- .count()
- == 1
+ .filter(|&location| !is_local_assignment(mir, local, location));
+ if let Some(location) = locations.next() {
+ locations.next().is_none() && !block_in_cycle(mir, location.block)
+ } else {
+ false
+ }
})
}
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 3637476c4..0faff05eb 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -20,7 +20,7 @@ macro_rules! msrv_aliases {
// names may refer to stabilized feature flags or library items
msrv_aliases! {
1,71,0 { TUPLE_ARRAY_CONVERSIONS }
- 1,70,0 { OPTION_IS_SOME_AND }
+ 1,70,0 { OPTION_IS_SOME_AND, BINARY_HEAP_RETAIN }
1,68,0 { PATH_MAIN_SEPARATOR_STR }
1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE }
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 914ea85ac..2fb24b5c7 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -15,6 +15,7 @@ pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [
];
#[cfg(feature = "internal")]
pub const DIAGNOSTIC_BUILDER: [&str; 3] = ["rustc_errors", "diagnostic_builder", "DiagnosticBuilder"];
+pub const BINARYHEAP_ITER: [&str; 5] = ["alloc", "collections", "binary_heap", "BinaryHeap", "iter"];
pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];
pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
pub const BTREESET_ITER: [&str; 6] = ["alloc", "collections", "btree", "set", "BTreeSet", "iter"];
@@ -48,6 +49,7 @@ pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"];
pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"];
pub const ITER_EMPTY: [&str; 5] = ["core", "iter", "sources", "empty", "Empty"];
+pub const ITER_ONCE: [&str; 5] = ["core", "iter", "sources", "once", "Once"];
pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
#[cfg(feature = "internal")]
pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
@@ -86,10 +88,7 @@ pub const PTR_REPLACE: [&str; 3] = ["core", "ptr", "replace"];
pub const PTR_SWAP: [&str; 3] = ["core", "ptr", "swap"];
pub const PTR_UNALIGNED_VOLATILE_LOAD: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_load"];
pub const PTR_UNALIGNED_VOLATILE_STORE: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_store"];
-pub const PTR_WRITE: [&str; 3] = ["core", "ptr", "write"];
pub const PTR_WRITE_BYTES: [&str; 3] = ["core", "intrinsics", "write_bytes"];
-pub const PTR_WRITE_UNALIGNED: [&str; 3] = ["core", "ptr", "write_unaligned"];
-pub const PTR_WRITE_VOLATILE: [&str; 3] = ["core", "ptr", "write_volatile"];
pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"];
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"];
@@ -165,3 +164,4 @@ pub const DEBUG_STRUCT: [&str; 4] = ["core", "fmt", "builders", "DebugStruct"];
pub const ORD_CMP: [&str; 4] = ["core", "cmp", "Ord", "cmp"];
#[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so
pub const BOOL_THEN: [&str; 4] = ["core", "bool", "<impl bool>", "then"];
+pub const ARRAY_INTO_ITER: [&str; 4] = ["core", "array", "iter", "IntoIter"];
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 139e31bc5..55f9cb27a 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -272,6 +272,7 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
| ProjectionElem::Downcast(..)
| ProjectionElem::Subslice { .. }
| ProjectionElem::Deref
+ | ProjectionElem::Subtype(_)
| ProjectionElem::Index(_) => {},
}
}
@@ -291,8 +292,8 @@ fn check_terminator<'tcx>(
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::Goto { .. }
| TerminatorKind::Return
- | TerminatorKind::Resume
- | TerminatorKind::Terminate
+ | TerminatorKind::UnwindResume
+ | TerminatorKind::UnwindTerminate(_)
| TerminatorKind::Unreachable => Ok(()),
TerminatorKind::Drop { place, .. } => {
if !is_ty_const_destruct(tcx, place.ty(&body.local_decls, tcx).ty, body) {
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index dc4ee7256..31cb42109 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -8,7 +8,7 @@ use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
use rustc_lint::{LateContext, LintContext};
use rustc_session::Session;
use rustc_span::source_map::{original_sp, SourceMap};
-use rustc_span::{hygiene, BytePos, Pos, SourceFile, Span, SpanData, SyntaxContext, DUMMY_SP};
+use rustc_span::{hygiene, BytePos, SourceFileAndLine, Pos, SourceFile, Span, SpanData, SyntaxContext, DUMMY_SP};
use std::borrow::Cow;
use std::ops::Range;
@@ -117,9 +117,9 @@ fn first_char_in_first_line<T: LintContext>(cx: &T, span: Span) -> Option<BytePo
/// ```
fn line_span<T: LintContext>(cx: &T, span: Span) -> Span {
let span = original_sp(span, DUMMY_SP);
- let source_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();
- let line_no = source_map_and_line.line;
- let line_start = source_map_and_line.sf.lines(|lines| lines[line_no]);
+ let SourceFileAndLine { sf, line } = cx.sess().source_map().lookup_line(span.lo()).unwrap();
+ let line_start = sf.lines()[line];
+ let line_start = sf.absolute_position(line_start);
span.with_lo(line_start)
}
@@ -362,7 +362,7 @@ pub fn snippet_block_with_context<'a>(
}
/// Same as `snippet_with_applicability`, but first walks the span up to the given context. This
-/// will result in the macro call, rather then the expansion, if the span is from a child context.
+/// will result in the macro call, rather than the expansion, if the span is from a child context.
/// If the span is not from a child context, it will be used directly instead.
///
/// e.g. Given the expression `&vec![]`, getting a snippet from the span for `vec![]` as a HIR node
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index ee5a49a20..ae8ee371f 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -88,7 +88,7 @@ impl<'a> Sugg<'a> {
}
/// Same as `hir`, but first walks the span up to the given context. This will result in the
- /// macro call, rather then the expansion, if the span is from a child context. If the span is
+ /// macro call, rather than the expansion, if the span is from a child context. If the span is
/// not from a child context, it will be used directly instead.
///
/// e.g. Given the expression `&vec![]`, getting a snippet from the span for `vec![]` as a HIR
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index a05f682aa..604dc7691 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -13,7 +13,8 @@ use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
-use rustc_middle::mir::interpret::{ConstValue, Scalar};
+use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::ConstValue;
use rustc_middle::traits::EvaluationResult;
use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::{
@@ -27,6 +28,7 @@ use rustc_target::abi::{Size, VariantIdx};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use rustc_trait_selection::traits::{Obligation, ObligationCause};
+use std::assert_matches::debug_assert_matches;
use std::iter;
use crate::{match_def_path, path_res, paths};
@@ -259,7 +261,11 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
})),
);
- debug_assert_eq!(tcx.def_kind(trait_id), DefKind::Trait);
+ debug_assert_matches!(
+ tcx.def_kind(trait_id),
+ DefKind::Trait | DefKind::TraitAlias,
+ "`DefId` must belong to a trait or trait alias"
+ );
#[cfg(debug_assertions)]
assert_generic_args_match(tcx, trait_id, trait_ref.args);
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index 06fd95290..750646723 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -150,7 +150,7 @@ fn generic_args_certainty(cx: &LateContext<'_>, args: &GenericArgs<'_>) -> Certa
}
/// Tries to tell whether a `QPath` resolves to something certain, e.g., whether all of its path
-/// segments generic arguments are are instantiated.
+/// segments generic arguments are instantiated.
///
/// `qpath` could refer to either a type or a value. The heuristic never needs the `DefId` of a
/// value. So `DefId`s are retained only when `resolves_to_type` is true.
@@ -207,8 +207,8 @@ fn path_segment_certainty(
// Checking `res_generics_def_id(..)` before calling `generics_of` avoids an ICE.
if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
let generics = cx.tcx.generics_of(def_id);
- let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && generics.params.is_empty()
- {
+ let count = generics.params.len() - usize::from(generics.host_effect_index.is_some());
+ let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0 {
Certainty::Certain(None)
} else {
Certainty::Uncertain
@@ -219,7 +219,7 @@ fn path_segment_certainty(
// See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value.
let certainty = lhs.join_clearing_def_ids(rhs);
if resolves_to_type {
- if let DefKind::TyAlias { .. } = cx.tcx.def_kind(def_id) {
+ if let DefKind::TyAlias = cx.tcx.def_kind(def_id) {
adt_def_id(cx.tcx.type_of(def_id).instantiate_identity())
.map_or(certainty, |def_id| certainty.with_def_id(def_id))
} else {
@@ -299,10 +299,11 @@ fn type_is_inferrable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> b
// Check that all type parameters appear in the functions input types.
(0..(generics.parent_count + generics.params.len()) as u32).all(|index| {
- fn_sig
- .inputs()
- .iter()
- .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
+ Some(index as usize) == generics.host_effect_index
+ || fn_sig
+ .inputs()
+ .iter()
+ .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
})
}
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index 39ef76348..ec131c7f6 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -4,7 +4,7 @@ use core::ops::ControlFlow;
use hir::def::Res;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self as hir, Expr, ExprKind, HirId, HirIdSet};
-use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
+use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, Place, PlaceBase, PlaceWithHirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter;
@@ -37,6 +37,17 @@ pub fn is_potentially_mutated<'tcx>(variable: HirId, expr: &'tcx Expr<'_>, cx: &
mutated_variables(expr, cx).map_or(true, |mutated| mutated.contains(&variable))
}
+pub fn is_potentially_local_place(local_id: HirId, place: &Place<'_>) -> bool {
+ match place.base {
+ PlaceBase::Local(id) => id == local_id,
+ PlaceBase::Upvar(_) => {
+ // Conservatively assume yes.
+ true
+ },
+ _ => false,
+ }
+}
+
struct MutVarsDelegate {
used_mutably: HirIdSet,
skip: bool,
diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml
index 3633ed31d..1470da61f 100644
--- a/src/tools/clippy/declare_clippy_lint/Cargo.toml
+++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "declare_clippy_lint"
-version = "0.1.73"
+version = "0.1.74"
edition = "2021"
publish = false
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 8b3f819f0..5ce22b65f 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly-2023-08-10"
+channel = "nightly-2023-09-25"
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index e46f8bf6f..f340cf593 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -1,16 +1,13 @@
-#![feature(test)] // compiletest_rs requires this attribute
#![feature(lazy_cell)]
#![feature(is_sorted)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]
#![allow(unused_extern_crates)]
-use compiletest::{status_emitter, CommandBuilder, OutputConflictHandling};
-use ui_test as compiletest;
-use ui_test::Mode as TestMode;
+use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, Mode, OutputConflictHandling};
use std::collections::BTreeMap;
-use std::env::{self, remove_var, set_var, var_os};
+use std::env::{self, set_var, var_os};
use std::ffi::{OsStr, OsString};
use std::fs;
use std::path::{Path, PathBuf};
@@ -21,7 +18,6 @@ use test_utils::IS_RUSTC_TEST_SUITE;
// in the depinfo file (otherwise cargo thinks they are unused)
extern crate clippy_lints;
extern crate clippy_utils;
-extern crate derive_new;
extern crate futures;
extern crate if_chain;
extern crate itertools;
@@ -30,11 +26,12 @@ extern crate quote;
extern crate syn;
extern crate tokio;
+mod test_utils;
+
/// All crates used in UI tests are listed here
static TEST_DEPENDENCIES: &[&str] = &[
"clippy_lints",
"clippy_utils",
- "derive_new",
"futures",
"if_chain",
"itertools",
@@ -105,32 +102,35 @@ static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| {
.collect()
});
-mod test_utils;
-
// whether to run internal tests or not
const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
-fn base_config(test_dir: &str) -> compiletest::Config {
- let mut config = compiletest::Config {
- mode: TestMode::Yolo,
- stderr_filters: vec![],
- stdout_filters: vec![],
- output_conflict_handling: if var_os("RUSTC_BLESS").is_some_and(|v| v != "0")
- || env::args().any(|arg| arg == "--bless")
- {
- OutputConflictHandling::Bless
- } else {
- OutputConflictHandling::Error("cargo uibless".into())
+fn canonicalize(path: impl AsRef<Path>) -> PathBuf {
+ let path = path.as_ref();
+ fs::create_dir_all(path).unwrap();
+ fs::canonicalize(path).unwrap_or_else(|err| panic!("{} cannot be canonicalized: {err}", path.display()))
+}
+
+fn base_config(test_dir: &str) -> (Config, Args) {
+ let mut args = Args::test().unwrap();
+ args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
+
+ let mut config = Config {
+ mode: Mode::Yolo {
+ rustfix: ui_test::RustfixMode::Everything,
},
+ stderr_filters: vec![(Match::PathBackslash, b"/")],
+ stdout_filters: vec![],
+ filter_files: env::var("TESTNAME")
+ .map(|filters| filters.split(',').map(str::to_string).collect())
+ .unwrap_or_default(),
target: None,
- out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap_or("target".into())).join("ui_test"),
- ..compiletest::Config::rustc(Path::new("tests").join(test_dir))
+ out_dir: canonicalize(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into())).join("ui_test"),
+ ..Config::rustc(Path::new("tests").join(test_dir))
};
-
- if let Some(_path) = option_env!("RUSTC_LIB_PATH") {
- //let path = PathBuf::from(path);
- //config.run_lib_path = path.clone();
- //config.compile_lib_path = path;
+ config.with_args(&args, /* bless by default */ false);
+ if let OutputConflictHandling::Error(err) = &mut config.output_conflict_handling {
+ *err = "cargo uibless".into();
}
let current_exe_path = env::current_exe().unwrap();
let deps_path = current_exe_path.parent().unwrap();
@@ -155,52 +155,34 @@ fn base_config(test_dir: &str) -> compiletest::Config {
config.program.args.push(dep.into());
}
- // Normalize away slashes in windows paths.
- config.stderr_filter(r"\\", "/");
-
- //config.build_base = profile_path.join("test").join(test_dir);
config.program.program = profile_path.join(if cfg!(windows) {
"clippy-driver.exe"
} else {
"clippy-driver"
});
- config
-}
-
-fn test_filter() -> Box<dyn Sync + Fn(&Path) -> bool> {
- if let Ok(filters) = env::var("TESTNAME") {
- let filters: Vec<_> = filters.split(',').map(ToString::to_string).collect();
- Box::new(move |path| filters.iter().any(|f| path.to_string_lossy().contains(f)))
- } else {
- Box::new(|_| true)
- }
+ (config, args)
}
fn run_ui() {
- let config = base_config("ui");
- //config.rustfix_coverage = true;
- // use tests/clippy.toml
- let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
- let _threads = VarGuard::set(
- "RUST_TEST_THREADS",
- // if RUST_TEST_THREADS is set, adhere to it, otherwise override it
- env::var("RUST_TEST_THREADS").unwrap_or_else(|_| {
- std::thread::available_parallelism()
- .map_or(1, std::num::NonZeroUsize::get)
- .to_string()
- }),
- );
+ let (mut config, args) = base_config("ui");
+ config
+ .program
+ .envs
+ .push(("CLIPPY_CONF_DIR".into(), Some(canonicalize("tests").into())));
- let test_filter = test_filter();
+ let quiet = args.quiet;
- compiletest::run_tests_generic(
- config,
- move |path| compiletest::default_file_filter(path) && test_filter(path),
- compiletest::default_per_file_config,
- status_emitter::Text,
+ ui_test::run_tests_generic(
+ vec![config],
+ ui_test::default_file_filter,
+ ui_test::default_per_file_config,
+ if quiet {
+ status_emitter::Text::quiet()
+ } else {
+ status_emitter::Text::verbose()
+ },
)
.unwrap();
- check_rustfix_coverage();
}
fn run_internal_tests() {
@@ -208,51 +190,59 @@ fn run_internal_tests() {
if !RUN_INTERNAL_TESTS {
return;
}
- let mut config = base_config("ui-internal");
+ let (mut config, args) = base_config("ui-internal");
if let OutputConflictHandling::Error(err) = &mut config.output_conflict_handling {
*err = "cargo uitest --features internal -- -- --bless".into();
}
- let test_filter = test_filter();
+ let quiet = args.quiet;
- compiletest::run_tests_generic(
- config,
- move |path| compiletest::default_file_filter(path) && test_filter(path),
- compiletest::default_per_file_config,
- status_emitter::Text,
+ ui_test::run_tests_generic(
+ vec![config],
+ ui_test::default_file_filter,
+ ui_test::default_per_file_config,
+ if quiet {
+ status_emitter::Text::quiet()
+ } else {
+ status_emitter::Text::verbose()
+ },
)
.unwrap();
}
fn run_ui_toml() {
- let mut config = base_config("ui-toml");
-
- config.stderr_filter(
- &regex::escape(
- &fs::canonicalize("tests")
- .unwrap()
- .parent()
- .unwrap()
- .display()
- .to_string()
- .replace('\\', "/"),
+ let (mut config, args) = base_config("ui-toml");
+
+ config.stderr_filters = vec![
+ (
+ Match::Exact(
+ canonicalize("tests")
+ .parent()
+ .unwrap()
+ .to_string_lossy()
+ .as_bytes()
+ .to_vec(),
+ ),
+ b"$DIR",
),
- "$$DIR",
- );
+ (Match::Exact(b"\\".to_vec()), b"/"),
+ ];
- let test_filter = test_filter();
+ let quiet = args.quiet;
ui_test::run_tests_generic(
- config,
- |path| compiletest::default_file_filter(path) && test_filter(path),
- |config, path| {
- let mut config = config.clone();
+ vec![config],
+ ui_test::default_file_filter,
+ |config, path, _file_contents| {
config
.program
.envs
.push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
- Some(config)
},
- status_emitter::Text,
+ if quiet {
+ status_emitter::Text::quiet()
+ } else {
+ status_emitter::Text::verbose()
+ },
)
.unwrap();
}
@@ -262,7 +252,7 @@ fn run_ui_cargo() {
return;
}
- let mut config = base_config("ui-cargo");
+ let (mut config, args) = base_config("ui-cargo");
config.program.input_file_flag = CommandBuilder::cargo().input_file_flag;
config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag;
config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()];
@@ -280,30 +270,47 @@ fn run_ui_cargo() {
});
config.edition = None;
- config.stderr_filter(
- &regex::escape(
- &fs::canonicalize("tests")
- .unwrap()
- .parent()
- .unwrap()
- .display()
- .to_string()
- .replace('\\', "/"),
+ config.stderr_filters = vec![
+ (
+ Match::Exact(
+ canonicalize("tests")
+ .parent()
+ .unwrap()
+ .to_string_lossy()
+ .as_bytes()
+ .to_vec(),
+ ),
+ b"$DIR",
),
- "$$DIR",
- );
+ (Match::Exact(b"\\".to_vec()), b"/"),
+ ];
- let test_filter = test_filter();
+ let quiet = args.quiet;
+
+ let ignored_32bit = |path: &Path| {
+ // FIXME: for some reason the modules are linted in a different order for this test
+ cfg!(target_pointer_width = "32") && path.ends_with("tests/ui-cargo/module_style/fail_mod/Cargo.toml")
+ };
ui_test::run_tests_generic(
- config,
- |path| test_filter(path) && path.ends_with("Cargo.toml"),
- |config, path| {
- let mut config = config.clone();
- config.out_dir = PathBuf::from("target/ui_test_cargo/").join(path.parent().unwrap());
- Some(config)
+ vec![config],
+ |path, config| {
+ path.ends_with("Cargo.toml") && ui_test::default_any_file_filter(path, config) && !ignored_32bit(path)
+ },
+ |config, path, _file_contents| {
+ config.out_dir = canonicalize(
+ std::env::current_dir()
+ .unwrap()
+ .join("target")
+ .join("ui_test_cargo/")
+ .join(path.parent().unwrap()),
+ );
+ },
+ if quiet {
+ status_emitter::Text::quiet()
+ } else {
+ status_emitter::Text::verbose()
},
- status_emitter::Text,
)
.unwrap();
}
@@ -328,7 +335,6 @@ fn main() {
"cargo" => run_ui_cargo as fn(),
"toml" => run_ui_toml as fn(),
"internal" => run_internal_tests as fn(),
- "rustfix-coverage-known-exceptions-accuracy" => rustfix_coverage_known_exceptions_accuracy as fn(),
"ui-cargo-toml-metadata" => ui_cargo_toml_metadata as fn(),
_ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"),
@@ -349,95 +355,20 @@ fn main() {
f();
sum += start.elapsed().as_millis();
}
- println!("average {} time: {} millis.", speedtest.to_uppercase(), sum / 1000);
+ println!(
+ "average {} time: {} millis.",
+ speedtest.to_uppercase(),
+ sum / u128::from(iterations)
+ );
} else {
run_ui();
run_ui_toml();
run_ui_cargo();
run_internal_tests();
- rustfix_coverage_known_exceptions_accuracy();
ui_cargo_toml_metadata();
}
}
-const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
- "assign_ops2.rs",
- "borrow_deref_ref_unfixable.rs",
- "cast_size_32bit.rs",
- "char_lit_as_u8.rs",
- "cmp_owned/without_suggestion.rs",
- "dbg_macro.rs",
- "deref_addrof_double_trigger.rs",
- "doc/unbalanced_ticks.rs",
- "eprint_with_newline.rs",
- "explicit_counter_loop.rs",
- "iter_skip_next_unfixable.rs",
- "let_and_return.rs",
- "literals.rs",
- "map_flatten.rs",
- "map_unwrap_or.rs",
- "match_bool.rs",
- "mem_replace_macro.rs",
- "needless_arbitrary_self_type_unfixable.rs",
- "needless_borrow_pat.rs",
- "needless_for_each_unfixable.rs",
- "nonminimal_bool.rs",
- "print_literal.rs",
- "redundant_static_lifetimes_multiple.rs",
- "ref_binding_to_reference.rs",
- "repl_uninit.rs",
- "result_map_unit_fn_unfixable.rs",
- "search_is_some.rs",
- "single_component_path_imports_nested_first.rs",
- "string_add.rs",
- "suspicious_to_owned.rs",
- "toplevel_ref_arg_non_rustfix.rs",
- "unit_arg.rs",
- "unnecessary_clone.rs",
- "unnecessary_lazy_eval_unfixable.rs",
- "write_literal.rs",
- "write_literal_2.rs",
-];
-
-fn check_rustfix_coverage() {
- let missing_coverage_path = Path::new("debug/test/ui/rustfix_missing_coverage.txt");
- let missing_coverage_path = if let Ok(target_dir) = std::env::var("CARGO_TARGET_DIR") {
- PathBuf::from(target_dir).join(missing_coverage_path)
- } else {
- missing_coverage_path.to_path_buf()
- };
-
- if let Ok(missing_coverage_contents) = std::fs::read_to_string(missing_coverage_path) {
- assert!(RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.iter().is_sorted_by_key(Path::new));
-
- for rs_file in missing_coverage_contents.lines() {
- let rs_path = Path::new(rs_file);
- if rs_path.starts_with("tests/ui/crashes") {
- continue;
- }
- assert!(rs_path.starts_with("tests/ui/"), "{rs_file:?}");
- let filename = rs_path.strip_prefix("tests/ui/").unwrap();
- assert!(
- RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS
- .binary_search_by_key(&filename, Path::new)
- .is_ok(),
- "`{rs_file}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \
- Please either add `//@run-rustfix` at the top of the file or add the file to \
- `RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.",
- );
- }
- }
-}
-
-fn rustfix_coverage_known_exceptions_accuracy() {
- for filename in RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS {
- let rs_path = Path::new("tests/ui").join(filename);
- assert!(rs_path.exists(), "`{}` does not exist", rs_path.display());
- let fixed_path = rs_path.with_extension("fixed");
- assert!(!fixed_path.exists(), "`{}` exists", fixed_path.display());
- }
-}
-
fn ui_cargo_toml_metadata() {
let ui_cargo_path = Path::new("tests/ui-cargo");
let cargo_common_metadata_path = ui_cargo_path.join("cargo_common_metadata");
@@ -473,27 +404,3 @@ fn ui_cargo_toml_metadata() {
);
}
}
-
-/// Restores an env var on drop
-#[must_use]
-struct VarGuard {
- key: &'static str,
- value: Option<OsString>,
-}
-
-impl VarGuard {
- fn set(key: &'static str, val: impl AsRef<OsStr>) -> Self {
- let value = var_os(key);
- set_var(key, val);
- Self { key, value }
- }
-}
-
-impl Drop for VarGuard {
- fn drop(&mut self) {
- match self.value.as_deref() {
- None => remove_var(self.key),
- Some(value) => set_var(self.key, value),
- }
- }
-}
diff --git a/src/tools/clippy/tests/headers.rs b/src/tools/clippy/tests/headers.rs
index 1d1e566cb..7eec9a9cd 100644
--- a/src/tools/clippy/tests/headers.rs
+++ b/src/tools/clippy/tests/headers.rs
@@ -16,7 +16,7 @@ fn old_test_headers() {
continue;
}
- let file = fs::read_to_string(entry.path()).unwrap();
+ let file = fs::read_to_string(entry.path()).unwrap_or_else(|err| panic!("{}: {err}", entry.path().display()));
if let Some(header) = old_headers.find(&file) {
println!("Found header `{}` in {}", header.as_str(), entry.path().display());
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr
index e161507b5..4d97d5496 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr
@@ -1,6 +1,7 @@
error: package `cargo_common_metadata_fail` is missing `package.description` metadata
|
= note: `-D clippy::cargo-common-metadata` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cargo_common_metadata)]`
error: package `cargo_common_metadata_fail` is missing `either package.license or package.license_file` metadata
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr
index dbf494cc3..9eb884f08 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr
@@ -1,6 +1,7 @@
error: package `cargo_common_metadata_fail_publish` is missing `package.description` metadata
|
= note: `-D clippy::cargo-common-metadata` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cargo_common_metadata)]`
error: package `cargo_common_metadata_fail_publish` is missing `either package.license or package.license_file` metadata
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr
index ae5967406..f9685a784 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr
@@ -1,6 +1,7 @@
error: package `cargo_common_metadata_fail_publish_true` is missing `package.description` metadata
|
= note: `-D clippy::cargo-common-metadata` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cargo_common_metadata)]`
error: package `cargo_common_metadata_fail_publish_true` is missing `either package.license or package.license_file` metadata
diff --git a/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr
index fde3a1e65..912ea9bb4 100644
--- a/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr
@@ -9,6 +9,7 @@ error: file is loaded as a module multiple times: `src/b.rs`
|
= help: replace all but one `mod` item with `use` items
= note: `-D clippy::duplicate-mod` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::duplicate_mod)]`
error: file is loaded as a module multiple times: `src/c.rs`
--> src/main.rs:9:1
diff --git a/src/tools/clippy/tests/ui-cargo/feature_name/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/feature_name/fail/Cargo.stderr
index da2db45d3..388f49fb2 100644
--- a/src/tools/clippy/tests/ui-cargo/feature_name/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/feature_name/fail/Cargo.stderr
@@ -2,6 +2,7 @@ error: the "no-" prefix in the feature name "no-qaq" is negative
|
= help: consider renaming the feature to "qaq", but make sure the feature adds functionality
= note: `-D clippy::negative-feature-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::negative_feature_names)]`
error: the "no_" prefix in the feature name "no_qaq" is negative
|
@@ -19,6 +20,7 @@ error: the "-support" suffix in the feature name "qvq-support" is redundant
|
= help: consider renaming the feature to "qvq"
= note: `-D clippy::redundant-feature-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_feature_names)]`
error: the "_support" suffix in the feature name "qvq_support" is redundant
|
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/Cargo.stderr
index c2907f319..902330e17 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/Cargo.stderr
@@ -6,6 +6,7 @@ error: `mod.rs` files are required, found `src/bad/inner.rs`
|
= help: move `src/bad/inner.rs` to `src/bad/inner/mod.rs`
= note: `-D clippy::self-named-module-files` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::self_named_module_files)]`
error: `mod.rs` files are required, found `src/bad/inner/stuff.rs`
--> src/bad/inner/stuff.rs:1:1
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr
index fcf1a3c5e..d776feb7f 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr
@@ -6,5 +6,6 @@ error: `mod.rs` files are required, found `src/bad.rs`
|
= help: move `src/bad.rs` to `src/bad/mod.rs`
= note: `-D clippy::self-named-module-files` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::self_named_module_files)]`
error: could not compile `fail-mod-remap` (bin "fail-mod-remap") due to previous error
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr
index f61642ca2..22558bc4c 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr
@@ -6,5 +6,6 @@ error: `mod.rs` files are not allowed, found `src/bad/mod.rs`
|
= help: move `src/bad/mod.rs` to `src/bad.rs`
= note: `-D clippy::mod-module-files` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mod_module_files)]`
error: could not compile `fail-no-mod` (bin "fail-no-mod") due to previous error
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr
index 5bcce9204..4beedc108 100644
--- a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr
@@ -1,5 +1,6 @@
error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9
|
= note: `-D clippy::multiple-crate-versions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::multiple_crate_versions)]`
error: could not compile `multiple_crate_versions` (bin "multiple_crate_versions") due to previous error
diff --git a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr
index b1578c9f3..65a19bb07 100644
--- a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr
@@ -1,5 +1,6 @@
error: wildcard dependency for `regex`
|
= note: `-D clippy::wildcard-dependencies` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wildcard_dependencies)]`
error: could not compile `wildcard_dependencies` (bin "wildcard_dependencies") due to previous error
diff --git a/src/tools/clippy/tests/ui-internal/check_formulation.stderr b/src/tools/clippy/tests/ui-internal/check_formulation.stderr
index 10eabca4b..96fa61760 100644
--- a/src/tools/clippy/tests/ui-internal/check_formulation.stderr
+++ b/src/tools/clippy/tests/ui-internal/check_formulation.stderr
@@ -6,6 +6,7 @@ LL | /// Check for lint formulations that are correct
|
= help: try using `Checks for` instead
= note: `-D clippy::almost-standard-lint-formulation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::almost_standard_lint_formulation)]`
error: non-standard lint formulation
--> $DIR/check_formulation.rs:33:5
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed
index 72c04bf80..918e33345 100644
--- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
index 76f7c3ce9..1baf6142b 100644
--- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
index 0852fe65a..dce2daad6 100644
--- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
@@ -1,5 +1,5 @@
error: this call is collapsible
- --> $DIR/collapsible_span_lint_calls.rs:36:9
+ --> $DIR/collapsible_span_lint_calls.rs:35:9
|
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
LL | | db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);
@@ -7,14 +7,14 @@ LL | | });
| |__________^ help: collapse into: `span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, help_msg, sugg.to_string(), Applicability::MachineApplicable)`
|
note: the lint level is defined here
- --> $DIR/collapsible_span_lint_calls.rs:2:9
+ --> $DIR/collapsible_span_lint_calls.rs:1:9
|
LL | #![deny(clippy::internal)]
| ^^^^^^^^^^^^^^^^
= note: `#[deny(clippy::collapsible_span_lint_calls)]` implied by `#[deny(clippy::internal)]`
error: this call is collapsible
- --> $DIR/collapsible_span_lint_calls.rs:39:9
+ --> $DIR/collapsible_span_lint_calls.rs:38:9
|
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
LL | | db.span_help(expr.span, help_msg);
@@ -22,7 +22,7 @@ LL | | });
| |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg)`
error: this call is collapsible
- --> $DIR/collapsible_span_lint_calls.rs:42:9
+ --> $DIR/collapsible_span_lint_calls.rs:41:9
|
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
LL | | db.help(help_msg);
@@ -30,7 +30,7 @@ LL | | });
| |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg)`
error: this call is collapsible
- --> $DIR/collapsible_span_lint_calls.rs:45:9
+ --> $DIR/collapsible_span_lint_calls.rs:44:9
|
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
LL | | db.span_note(expr.span, note_msg);
@@ -38,7 +38,7 @@ LL | | });
| |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg)`
error: this call is collapsible
- --> $DIR/collapsible_span_lint_calls.rs:48:9
+ --> $DIR/collapsible_span_lint_calls.rs:47:9
|
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
LL | | db.note(note_msg);
diff --git a/src/tools/clippy/tests/ui-internal/if_chain_style.stderr b/src/tools/clippy/tests/ui-internal/if_chain_style.stderr
index b12df2786..ea0495532 100644
--- a/src/tools/clippy/tests/ui-internal/if_chain_style.stderr
+++ b/src/tools/clippy/tests/ui-internal/if_chain_style.stderr
@@ -16,6 +16,7 @@ help: this `let` statement can also be in the `if_chain!`
LL | let x = "";
| ^^^^^^^^^^^
= note: `-D clippy::if-chain-style` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::if_chain_style)]`
error: `if a && b;` should be `if a; if b;`
--> $DIR/if_chain_style.rs:24:12
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
index a1a10c079..98591e15b 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
index 32dbfe5dc..92e92d4fb 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
index 4e99636e6..b8d9721ee 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
@@ -1,30 +1,30 @@
error: interning a defined symbol
- --> $DIR/interning_defined_symbol.rs:18:13
+ --> $DIR/interning_defined_symbol.rs:17:13
|
LL | let _ = Symbol::intern("f32");
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::f32`
|
note: the lint level is defined here
- --> $DIR/interning_defined_symbol.rs:2:9
+ --> $DIR/interning_defined_symbol.rs:1:9
|
LL | #![deny(clippy::internal)]
| ^^^^^^^^^^^^^^^^
= note: `#[deny(clippy::interning_defined_symbol)]` implied by `#[deny(clippy::internal)]`
error: interning a defined symbol
- --> $DIR/interning_defined_symbol.rs:21:13
+ --> $DIR/interning_defined_symbol.rs:20:13
|
LL | let _ = sym!(f32);
| ^^^^^^^^^ help: try: `rustc_span::sym::f32`
error: interning a defined symbol
- --> $DIR/interning_defined_symbol.rs:24:13
+ --> $DIR/interning_defined_symbol.rs:23:13
|
LL | let _ = Symbol::intern("proc-macro");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::proc_dash_macro`
error: interning a defined symbol
- --> $DIR/interning_defined_symbol.rs:27:13
+ --> $DIR/interning_defined_symbol.rs:26:13
|
LL | let _ = Symbol::intern("self");
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::symbol::kw::SelfLower`
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
index ac0752774..928596d08 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
index 56f778621..50b28648c 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr
index ddc06f0be..e97f6aea7 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.stderr
@@ -1,11 +1,11 @@
error: `extract_msrv_attr!` macro missing from `LateLintPass` implementation
- --> $DIR/invalid_msrv_attr_impl.rs:30:1
+ --> $DIR/invalid_msrv_attr_impl.rs:28:1
|
LL | impl LateLintPass<'_> for Pass {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/invalid_msrv_attr_impl.rs:3:9
+ --> $DIR/invalid_msrv_attr_impl.rs:1:9
|
LL | #![deny(clippy::internal)]
| ^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL + extract_msrv_attr!(LateContext);
|
error: `extract_msrv_attr!` macro missing from `EarlyLintPass` implementation
- --> $DIR/invalid_msrv_attr_impl.rs:34:1
+ --> $DIR/invalid_msrv_attr_impl.rs:32:1
|
LL | impl EarlyLintPass for Pass {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-internal/invalid_paths.stderr b/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
index 0e8508869..988d32d52 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
+++ b/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
@@ -5,6 +5,7 @@ LL | pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::invalid-paths` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::invalid_paths)]`
error: invalid path
--> $DIR/invalid_paths.rs:18:5
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
index d8a08bc99..cef16cf6c 100644
--- a/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.rs b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
index f7af0e9d8..fb453be66 100644
--- a/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.stderr b/src/tools/clippy/tests/ui-internal/outer_expn_data.stderr
index afef69678..e41ace472 100644
--- a/src/tools/clippy/tests/ui-internal/outer_expn_data.stderr
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.stderr
@@ -1,11 +1,11 @@
error: usage of `outer_expn().expn_data()`
- --> $DIR/outer_expn_data.rs:25:34
+ --> $DIR/outer_expn_data.rs:23:34
|
LL | let _ = expr.span.ctxt().outer_expn().expn_data();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `outer_expn_data()`
|
note: the lint level is defined here
- --> $DIR/outer_expn_data.rs:3:9
+ --> $DIR/outer_expn_data.rs:1:9
|
LL | #![deny(clippy::internal)]
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
index fce24412f..3908411da 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:paths.rs
#![deny(clippy::internal)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
index b10bc9e46..632e26215 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:paths.rs
#![deny(clippy::internal)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
index 3ca29f099..dd963d24c 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
@@ -1,72 +1,72 @@
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:37:13
+ --> $DIR/unnecessary_def_path.rs:36:13
|
LL | let _ = match_type(cx, ty, &OPTION);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
|
note: the lint level is defined here
- --> $DIR/unnecessary_def_path.rs:3:9
+ --> $DIR/unnecessary_def_path.rs:2:9
|
LL | #![deny(clippy::internal)]
| ^^^^^^^^^^^^^^^^
= note: `#[deny(clippy::unnecessary_def_path)]` implied by `#[deny(clippy::internal)]`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:38:13
+ --> $DIR/unnecessary_def_path.rs:37:13
|
LL | let _ = match_type(cx, ty, RESULT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:39:13
+ --> $DIR/unnecessary_def_path.rs:38:13
|
LL | let _ = match_type(cx, ty, &["core", "result", "Result"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:43:13
+ --> $DIR/unnecessary_def_path.rs:42:13
|
LL | let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Rc)`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:45:13
+ --> $DIR/unnecessary_def_path.rs:44:13
|
LL | let _ = match_type(cx, ty, &paths::OPTION);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:46:13
+ --> $DIR/unnecessary_def_path.rs:45:13
|
LL | let _ = match_type(cx, ty, paths::RESULT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
error: use of a def path to a `LangItem`
- --> $DIR/unnecessary_def_path.rs:48:13
+ --> $DIR/unnecessary_def_path.rs:47:13
|
LL | let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_lang_item(cx, ty, LangItem::OwnedBox)`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:49:13
+ --> $DIR/unnecessary_def_path.rs:48:13
|
LL | let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit)`
error: use of a def path to a `LangItem`
- --> $DIR/unnecessary_def_path.rs:51:13
+ --> $DIR/unnecessary_def_path.rs:50:13
|
LL | let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did)`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:52:13
+ --> $DIR/unnecessary_def_path.rs:51:13
|
LL | let _ = match_def_path(cx, did, &["core", "option", "Option"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.is_diagnostic_item(sym::Option, did)`
error: use of a def path to a `LangItem`
- --> $DIR/unnecessary_def_path.rs:53:13
+ --> $DIR/unnecessary_def_path.rs:52:13
|
LL | let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
@@ -74,25 +74,25 @@ LL | let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
= help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:55:13
+ --> $DIR/unnecessary_def_path.rs:54:13
|
LL | let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_trait_method(cx, expr, sym::AsRef)`
error: use of a def path to a diagnostic item
- --> $DIR/unnecessary_def_path.rs:57:13
+ --> $DIR/unnecessary_def_path.rs:56:13
|
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_path_diagnostic_item(cx, expr, sym::Option)`
error: use of a def path to a `LangItem`
- --> $DIR/unnecessary_def_path.rs:58:13
+ --> $DIR/unnecessary_def_path.rs:57:13
|
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id))`
error: use of a def path to a `LangItem`
- --> $DIR/unnecessary_def_path.rs:59:13
+ --> $DIR/unnecessary_def_path.rs:58:13
|
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome)`
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr
index 3ca45404e..58b1fd92b 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr
@@ -6,6 +6,7 @@ LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
|
= help: convert all references to use `sym::Deref`
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_def_path)]`
error: hardcoded path to a language item
--> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
index b802de1cb..eb79fdbc4 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(rustc_private)]
#![deny(clippy::internal)]
#![allow(
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
index c1bead5bd..bbea13af9 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(rustc_private)]
#![deny(clippy::internal)]
#![allow(
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
index a1f507f33..8e2aa5953 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
@@ -1,36 +1,36 @@
error: unnecessary `Symbol` to string conversion
- --> $DIR/unnecessary_symbol_str.rs:16:5
+ --> $DIR/unnecessary_symbol_str.rs:15:5
|
LL | Symbol::intern("foo").as_str() == "clippy";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::sym::clippy`
|
note: the lint level is defined here
- --> $DIR/unnecessary_symbol_str.rs:3:9
+ --> $DIR/unnecessary_symbol_str.rs:2:9
|
LL | #![deny(clippy::internal)]
| ^^^^^^^^^^^^^^^^
= note: `#[deny(clippy::unnecessary_symbol_str)]` implied by `#[deny(clippy::internal)]`
error: unnecessary `Symbol` to string conversion
- --> $DIR/unnecessary_symbol_str.rs:17:5
+ --> $DIR/unnecessary_symbol_str.rs:16:5
|
LL | Symbol::intern("foo").to_string() == "self";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower`
error: unnecessary `Symbol` to string conversion
- --> $DIR/unnecessary_symbol_str.rs:18:5
+ --> $DIR/unnecessary_symbol_str.rs:17:5
|
LL | Symbol::intern("foo").to_ident_string() != "Self";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper`
error: unnecessary `Symbol` to string conversion
- --> $DIR/unnecessary_symbol_str.rs:19:5
+ --> $DIR/unnecessary_symbol_str.rs:18:5
|
LL | &*Ident::empty().as_str() == "clippy";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::empty().name == rustc_span::sym::clippy`
error: unnecessary `Symbol` to string conversion
- --> $DIR/unnecessary_symbol_str.rs:20:5
+ --> $DIR/unnecessary_symbol_str.rs:19:5
|
LL | "clippy" == Ident::empty().to_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::empty().name`
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
index a8900da4e..99f08d947 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
@@ -5,6 +5,7 @@ LL | std::f32::MAX;
| ^^^^^^^^^^^^^
|
= note: `-D clippy::absolute-paths` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]`
error: consider bringing this path into scope with the `use` keyword
--> $DIR/absolute_paths.rs:41:5
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr
index 41b70644b..017ba4cc2 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr
@@ -5,6 +5,7 @@ LL | std::f32::MAX;
| ^^^^^^^^^^^^^
|
= note: `-D clippy::absolute-paths` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]`
error: consider bringing this path into scope with the `use` keyword
--> $DIR/absolute_paths.rs:41:5
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
index d4c250a8f..0e6a54452 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
@@ -1,4 +1,4 @@
-//@aux-build:../../ui/auxiliary/proc_macros.rs:proc-macro
+//@aux-build:../../ui/auxiliary/proc_macros.rs
//@aux-build:helper.rs
//@revisions: allow_crates disallow_crates
//@[allow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates
diff --git a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed
index c90856845..c04543da9 100644
--- a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed
+++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::uninlined_format_args)]
#![allow(clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs
index 661350c5c..813830d80 100644
--- a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs
+++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::uninlined_format_args)]
#![allow(clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr
index eb1180e60..b754f67ed 100644
--- a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr
+++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr
@@ -1,10 +1,11 @@
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:10:5
+ --> $DIR/uninlined_format_args.rs:9:5
|
LL | println!("val='{}'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`
help: change this to
|
LL - println!("val='{}'", local_i32);
@@ -12,7 +13,7 @@ LL + println!("val='{local_i32}'");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:11:5
+ --> $DIR/uninlined_format_args.rs:10:5
|
LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,12 +25,13 @@ LL + println!("Hello {} is {local_f64:.local_i32$}", "x");
|
error: literal with an empty format string
- --> $DIR/uninlined_format_args.rs:11:35
+ --> $DIR/uninlined_format_args.rs:10:35
|
LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64);
| ^^^
|
= note: `-D clippy::print-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_literal)]`
help: try
|
LL - println!("Hello {} is {:.*}", "x", local_i32, local_f64);
@@ -37,7 +39,7 @@ LL + println!("Hello x is {:.*}", local_i32, local_f64);
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:12:5
+ --> $DIR/uninlined_format_args.rs:11:5
|
LL | println!("Hello {} is {:.*}", local_i32, 5, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +51,7 @@ LL + println!("Hello {local_i32} is {local_f64:.*}", 5);
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:13:5
+ --> $DIR/uninlined_format_args.rs:12:5
|
LL | println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +63,7 @@ LL + println!("Hello {local_i32} is {local_f64:.*}", 5);
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:14:5
+ --> $DIR/uninlined_format_args.rs:13:5
|
LL | println!("{}, {}", local_i32, local_opt.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr
index 4f98ca192..5e8d26e07 100644
--- a/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr
+++ b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr
@@ -5,6 +5,7 @@ LL | let _ = Baz + Baz;
| ^^^^^^^^^
|
= note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`
error: arithmetic operation that can potentially result in unexpected side-effects
--> $DIR/arithmetic_side_effects_allowed.rs:80:13
diff --git a/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs
index 7f623c7a9..d36159e12 100644
--- a/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs
+++ b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.rs
@@ -1,6 +1,6 @@
#![allow(unused)]
#![warn(clippy::large_const_arrays, clippy::large_stack_arrays)]
-
+//@no-rustfix
const ABOVE: [u8; 11] = [0; 11];
const BELOW: [u8; 10] = [0; 10];
diff --git a/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr
index ac017b209..cf70b3c5c 100644
--- a/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr
+++ b/src/tools/clippy/tests/ui-toml/array_size_threshold/array_size_threshold.stderr
@@ -7,6 +7,7 @@ LL | const ABOVE: [u8; 11] = [0; 11];
| help: make this a static item: `static`
|
= note: `-D clippy::large-const-arrays` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_const_arrays)]`
error: allocating a local array larger than 10 bytes
--> $DIR/array_size_threshold.rs:4:25
@@ -16,6 +17,7 @@ LL | const ABOVE: [u8; 11] = [0; 11];
|
= help: consider allocating on the heap with `vec![0; 11].into_boxed_slice()`
= note: `-D clippy::large-stack-arrays` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_stack_arrays)]`
error: allocating a local array larger than 10 bytes
--> $DIR/array_size_threshold.rs:8:17
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
index fbef5c456..868cf00a8 100644
--- a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
@@ -7,8 +7,10 @@ async fn bad() -> u32 {
}
async fn bad_reason() -> u32 {
- let _x = Ipv4Addr::new(127, 0, 0, 1);
- baz().await
+ let x = Ipv4Addr::new(127, 0, 0, 1);
+ let y = baz().await;
+ let _x = x;
+ y
}
async fn good() -> u32 {
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
index 825aa1487..ddcd1940d 100644
--- a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
@@ -6,15 +6,16 @@ LL | let _x = String::from("hello");
|
= note: strings are bad (from clippy.toml)
= note: `-D clippy::await-holding-invalid-type` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::await_holding_invalid_type)]`
error: `std::net::Ipv4Addr` may not be held across an `await` point per `clippy.toml`
--> $DIR/await_holding_invalid_type.rs:10:9
|
-LL | let _x = Ipv4Addr::new(127, 0, 0, 1);
- | ^^
+LL | let x = Ipv4Addr::new(127, 0, 0, 1);
+ | ^
error: `std::string::String` may not be held across an `await` point per `clippy.toml`
- --> $DIR/await_holding_invalid_type.rs:31:13
+ --> $DIR/await_holding_invalid_type.rs:33:13
|
LL | let _x = String::from("hi!");
| ^^
diff --git a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
index 89d84eb24..a21952c0e 100644
--- a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
@@ -18,6 +18,7 @@ LL | fn cognitive_complexity() {
|
= help: you could split it up into multiple smaller functions
= note: `-D clippy::cognitive-complexity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]`
error: aborting due to previous error; 2 warnings emitted
diff --git a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs
index 21e4fce26..67129e624 100644
--- a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs
+++ b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs
@@ -1,6 +1,6 @@
//@compile-flags: --test
#![warn(clippy::dbg_macro)]
-
+//@no-rustfix
fn foo(n: u32) -> u32 {
if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
}
diff --git a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr
index 859383a71..3a66f701e 100644
--- a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr
+++ b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr
@@ -5,6 +5,7 @@ LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::dbg-macro` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`
help: remove the invocation before committing it to a version control system
|
LL | if let Some(n) = n.checked_sub(4) { n } else { n }
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml
new file mode 100644
index 000000000..74fc5d249
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml
@@ -0,0 +1 @@
+literal-representation-threshold = 0xFFFFFF
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed
new file mode 100644
index 000000000..750f3be84
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed
@@ -0,0 +1,6 @@
+#![warn(clippy::decimal_literal_representation)]
+fn main() {
+ let _ = 8388608;
+ let _ = 0x00FF_FFFF;
+ //~^ ERROR: integer literal has a better hexadecimal representation
+}
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs
new file mode 100644
index 000000000..26b3354d1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs
@@ -0,0 +1,6 @@
+#![warn(clippy::decimal_literal_representation)]
+fn main() {
+ let _ = 8388608;
+ let _ = 16777215;
+ //~^ ERROR: integer literal has a better hexadecimal representation
+}
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr
new file mode 100644
index 000000000..6f817a3fd
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr
@@ -0,0 +1,11 @@
+error: integer literal has a better hexadecimal representation
+ --> $DIR/decimal_literal_representation.rs:4:13
+ |
+LL | let _ = 16777215;
+ | ^^^^^^^^ help: consider: `0x00FF_FFFF`
+ |
+ = note: `-D clippy::decimal-literal-representation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::decimal_literal_representation)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_macros/auxiliary/macros.rs b/src/tools/clippy/tests/ui-toml/disallowed_macros/auxiliary/macros.rs
index fcaeace0e..f4166b227 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_macros/auxiliary/macros.rs
+++ b/src/tools/clippy/tests/ui-toml/disallowed_macros/auxiliary/macros.rs
@@ -30,3 +30,18 @@ macro_rules! item {
const ITEM: usize = 1;
};
}
+
+#[macro_export]
+macro_rules! binop {
+ ($t:tt) => {
+ $t + $t
+ };
+}
+
+#[macro_export]
+macro_rules! attr {
+ ($i:item) => {
+ #[repr(C)]
+ $i
+ };
+}
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_macros/clippy.toml b/src/tools/clippy/tests/ui-toml/disallowed_macros/clippy.toml
index c8fe8be9a..85f1b71eb 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_macros/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/disallowed_macros/clippy.toml
@@ -8,4 +8,6 @@ disallowed-macros = [
"macros::ty",
"macros::pat",
"macros::item",
+ "macros::binop",
+ "macros::attr",
]
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs
index ba919b487..4a3d55e13 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs
+++ b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs
@@ -20,11 +20,14 @@ fn main() {
let macros::pat!() = 1;
let _: macros::ty!() = "";
macros::item!();
+ let _ = macros::binop!(1);
eprintln!("allowed");
}
-struct S;
+macros::attr! {
+ struct S;
+}
impl S {
macros::item!();
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
index aed9feb6f..3c6f59b16 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
+++ b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
@@ -5,6 +5,7 @@ LL | println!("one");
| ^^^^^^^^^^^^^^^
|
= note: `-D clippy::disallowed-macros` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`
error: use of a disallowed macro `std::println`
--> $DIR/disallowed_macros.rs:11:5
@@ -62,23 +63,37 @@ error: use of a disallowed macro `macros::item`
LL | macros::item!();
| ^^^^^^^^^^^^^^^
+error: use of a disallowed macro `macros::binop`
+ --> $DIR/disallowed_macros.rs:23:13
+ |
+LL | let _ = macros::binop!(1);
+ | ^^^^^^^^^^^^^^^^^
+
+error: use of a disallowed macro `macros::attr`
+ --> $DIR/disallowed_macros.rs:28:1
+ |
+LL | / macros::attr! {
+LL | | struct S;
+LL | | }
+ | |_^
+
error: use of a disallowed macro `macros::item`
- --> $DIR/disallowed_macros.rs:30:5
+ --> $DIR/disallowed_macros.rs:33:5
|
LL | macros::item!();
| ^^^^^^^^^^^^^^^
error: use of a disallowed macro `macros::item`
- --> $DIR/disallowed_macros.rs:34:5
+ --> $DIR/disallowed_macros.rs:37:5
|
LL | macros::item!();
| ^^^^^^^^^^^^^^^
error: use of a disallowed macro `macros::item`
- --> $DIR/disallowed_macros.rs:38:5
+ --> $DIR/disallowed_macros.rs:41:5
|
LL | macros::item!();
| ^^^^^^^^^^^^^^^
-error: aborting due to 13 previous errors
+error: aborting due to 15 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr
index 23c3e96a8..51cbe1abf 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.stderr
@@ -5,6 +5,7 @@ LL | let foo = "bar";
| ^^^
|
= note: `-D clippy::disallowed-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`
error: use of a disallowed/placeholder name `ducks`
--> $DIR/disallowed_names.rs:7:9
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr
index d961fa340..d9f25a3ee 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.stderr
@@ -5,6 +5,7 @@ LL | let ducks = ["quack", "quack"];
| ^^^^^
|
= note: `-D clippy::disallowed-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml
new file mode 100644
index 000000000..26cb2d77b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml
@@ -0,0 +1 @@
+allowed-scripts = ["Cyrillic"]
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs
new file mode 100644
index 000000000..9df1ec6fa
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs
@@ -0,0 +1,6 @@
+#![warn(clippy::disallowed_script_idents)]
+fn main() {
+ let счётчик = 10;
+ let カウンタ = 10;
+ //~^ ERROR: identifier `カウンタ` has a Unicode script that is not allowed by configuration
+}
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr
new file mode 100644
index 000000000..31bb5ee35
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr
@@ -0,0 +1,11 @@
+error: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana
+ --> $DIR/disallowed_script_idents.rs:4:9
+ |
+LL | let カウンタ = 10;
+ | ^^^^^^^^
+ |
+ = note: `-D clippy::disallowed-script-idents` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_script_idents)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed
new file mode 100644
index 000000000..f16e138da
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed
@@ -0,0 +1,12 @@
+#![warn(clippy::doc_markdown)]
+
+/// This is a special interface for ClipPy which doesn't require backticks
+fn allowed_name() {}
+
+/// OAuth and LaTeX are inside Clippy's default list.
+fn default_name() {}
+
+/// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.
+fn unknown_name() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr
index 0f767c9b8..92b035058 100644
--- a/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr
+++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr
@@ -5,6 +5,7 @@ LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and sh
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::doc-markdown` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
help: try
|
LL | /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.
diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed
new file mode 100644
index 000000000..af6ec675e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed
@@ -0,0 +1,12 @@
+#![warn(clippy::doc_markdown)]
+
+/// This is a special interface for ClipPy which doesn't require backticks
+fn allowed_name() {}
+
+/// `OAuth` and `LaTeX` are inside Clippy's default list.
+fn default_name() {}
+
+/// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.
+fn unknown_name() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr
index e0613eb86..6567b5f12 100644
--- a/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr
+++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr
@@ -5,6 +5,7 @@ LL | /// OAuth and LaTeX are inside Clippy's default list.
| ^^^^^
|
= note: `-D clippy::doc-markdown` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
help: try
|
LL | /// `OAuth` and LaTeX are inside Clippy's default list.
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml
new file mode 100644
index 000000000..0ad7a9799
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml
@@ -0,0 +1 @@
+enum-variant-name-threshold = 5
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs
new file mode 100644
index 000000000..8f4e178cc
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs
@@ -0,0 +1,16 @@
+enum Foo {
+ AFoo,
+ BFoo,
+ CFoo,
+ DFoo,
+}
+enum Foo2 {
+ //~^ ERROR: all variants have the same postfix
+ AFoo,
+ BFoo,
+ CFoo,
+ DFoo,
+ EFoo,
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr
new file mode 100644
index 000000000..11039b1db
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr
@@ -0,0 +1,18 @@
+error: all variants have the same postfix: `Foo`
+ --> $DIR/enum_variant_names.rs:7:1
+ |
+LL | / enum Foo2 {
+LL | |
+LL | | AFoo,
+LL | | BFoo,
+... |
+LL | | EFoo,
+LL | | }
+ | |_^
+ |
+ = help: remove the postfixes and use full paths to the variants instead of glob imports
+ = note: `-D clippy::enum-variant-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml
new file mode 100644
index 000000000..64a8017fe
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml
@@ -0,0 +1 @@
+enum-variant-size-threshold = 500
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed
new file mode 100644
index 000000000..9ae760ae4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed
@@ -0,0 +1,11 @@
+enum Fine {
+ A(()),
+ B([u8; 500]),
+}
+enum Bad {
+ //~^ ERROR: large size difference between variants
+ A(()),
+ B(Box<[u8; 501]>),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs
new file mode 100644
index 000000000..cf7f432bf
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs
@@ -0,0 +1,11 @@
+enum Fine {
+ A(()),
+ B([u8; 500]),
+}
+enum Bad {
+ //~^ ERROR: large size difference between variants
+ A(()),
+ B([u8; 501]),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
new file mode 100644
index 000000000..4d9bc9d48
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
@@ -0,0 +1,21 @@
+error: large size difference between variants
+ --> $DIR/enum_variant_size.rs:5:1
+ |
+LL | / enum Bad {
+LL | |
+LL | | A(()),
+ | | ----- the second-largest variant contains at least 0 bytes
+LL | | B([u8; 501]),
+ | | ------------ the largest variant contains at least 501 bytes
+LL | | }
+ | |_^ the entire enum is at least 502 bytes
+ |
+ = note: `-D clippy::large-enum-variant` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | B(Box<[u8; 501]>),
+ | ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml
new file mode 100644
index 000000000..f85aade6a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml
@@ -0,0 +1 @@
+enum-variant-name-threshold = 0
diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs
new file mode 100644
index 000000000..6918d7528
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs
@@ -0,0 +1,3 @@
+enum Actions {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/excessive_nesting/auxiliary/proc_macros.rs b/src/tools/clippy/tests/ui-toml/excessive_nesting/auxiliary/proc_macros.rs
deleted file mode 100644
index 60fbaaea3..000000000
--- a/src/tools/clippy/tests/ui-toml/excessive_nesting/auxiliary/proc_macros.rs
+++ /dev/null
@@ -1,469 +0,0 @@
-// NOTE: Copied from `ui/auxiliary/proc_macros.rs`, couldn't get `../` to work for some reason
-
-#![feature(let_chains)]
-#![feature(proc_macro_span)]
-#![allow(clippy::excessive_nesting, dead_code)]
-
-extern crate proc_macro;
-
-use core::mem;
-use proc_macro::token_stream::IntoIter;
-use proc_macro::Delimiter::{self, Brace, Parenthesis};
-use proc_macro::Spacing::{self, Alone, Joint};
-use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree as TT};
-
-type Result<T> = core::result::Result<T, TokenStream>;
-
-/// Make a `compile_error!` pointing to the given span.
-fn make_error(msg: &str, span: Span) -> TokenStream {
- TokenStream::from_iter([
- TT::Ident(Ident::new("compile_error", span)),
- TT::Punct(punct_with_span('!', Alone, span)),
- TT::Group({
- let mut msg = Literal::string(msg);
- msg.set_span(span);
- group_with_span(Parenthesis, TokenStream::from_iter([TT::Literal(msg)]), span)
- }),
- ])
-}
-
-fn expect_tt<T>(tt: Option<TT>, f: impl FnOnce(TT) -> Option<T>, expected: &str, span: Span) -> Result<T> {
- match tt {
- None => Err(make_error(
- &format!("unexpected end of input, expected {expected}"),
- span,
- )),
- Some(tt) => {
- let span = tt.span();
- match f(tt) {
- Some(x) => Ok(x),
- None => Err(make_error(&format!("unexpected token, expected {expected}"), span)),
- }
- },
- }
-}
-
-fn punct_with_span(c: char, spacing: Spacing, span: Span) -> Punct {
- let mut p = Punct::new(c, spacing);
- p.set_span(span);
- p
-}
-
-fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Group {
- let mut g = Group::new(delimiter, stream);
- g.set_span(span);
- g
-}
-
-/// Token used to escape the following token from the macro's span rules.
-const ESCAPE_CHAR: char = '$';
-
-/// Takes a single token followed by a sequence of tokens. Returns the sequence of tokens with their
-/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`.
-#[proc_macro]
-pub fn with_span(input: TokenStream) -> TokenStream {
- let mut iter = input.into_iter();
- let span = iter.next().unwrap().span();
- let mut res = TokenStream::new();
- if let Err(e) = write_with_span(span, iter, &mut res) {
- e
- } else {
- res
- }
-}
-
-/// Takes a sequence of tokens and return the tokens with the span set such that they appear to be
-/// from an external macro. Tokens may be escaped with either `#ident` or `#(tokens)`.
-#[proc_macro]
-pub fn external(input: TokenStream) -> TokenStream {
- let mut res = TokenStream::new();
- if let Err(e) = write_with_span(Span::mixed_site(), input.into_iter(), &mut res) {
- e
- } else {
- res
- }
-}
-
-/// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped
-/// either by `#ident` or `#(tokens)`.
-fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> {
- while let Some(tt) = input.next() {
- match tt {
- TT::Punct(p) if p.as_char() == ESCAPE_CHAR => {
- expect_tt(
- input.next(),
- |tt| match tt {
- tt @ (TT::Ident(_) | TT::Literal(_)) => {
- out.extend([tt]);
- Some(())
- },
- TT::Punct(mut p) if p.as_char() == ESCAPE_CHAR => {
- p.set_span(s);
- out.extend([TT::Punct(p)]);
- Some(())
- },
- TT::Group(g) if g.delimiter() == Parenthesis => {
- out.extend([TT::Group(group_with_span(Delimiter::None, g.stream(), g.span()))]);
- Some(())
- },
- _ => None,
- },
- "an ident, a literal, or parenthesized tokens",
- p.span(),
- )?;
- },
- TT::Group(g) => {
- let mut stream = TokenStream::new();
- write_with_span(s, g.stream().into_iter(), &mut stream)?;
- out.extend([TT::Group(group_with_span(g.delimiter(), stream, s))]);
- },
- mut tt => {
- tt.set_span(s);
- out.extend([tt]);
- },
- }
- }
- Ok(())
-}
-
-/// Within the item this attribute is attached to, an `inline!` macro is available which expands the
-/// contained tokens as though they came from a macro expansion.
-///
-/// Within the `inline!` macro, any token preceded by `$` is passed as though it were an argument
-/// with an automatically chosen fragment specifier. `$ident` will be passed as `ident`, `$1` or
-/// `$"literal"` will be passed as `literal`, `$'lt` will be passed as `lifetime`, and `$(...)` will
-/// pass the contained tokens as a `tt` sequence (the wrapping parenthesis are removed). If another
-/// specifier is required it can be specified within parenthesis like `$(@expr ...)`. This will
-/// expand the remaining tokens as a single argument.
-///
-/// Multiple `inline!` macros may be nested within each other. This will expand as nested macro
-/// calls. However, any arguments will be passed as though they came from the outermost context.
-#[proc_macro_attribute]
-pub fn inline_macros(args: TokenStream, input: TokenStream) -> TokenStream {
- let mut args = args.into_iter();
- let mac_name = match args.next() {
- Some(TT::Ident(name)) => Some(name),
- Some(tt) => {
- return make_error(
- "unexpected argument, expected either an ident or no arguments",
- tt.span(),
- );
- },
- None => None,
- };
- if let Some(tt) = args.next() {
- return make_error(
- "unexpected argument, expected either an ident or no arguments",
- tt.span(),
- );
- };
-
- let mac_name = if let Some(mac_name) = mac_name {
- Ident::new(&format!("__inline_mac_{mac_name}"), Span::call_site())
- } else {
- let mut input = match LookaheadIter::new(input.clone().into_iter()) {
- Some(x) => x,
- None => return input,
- };
- loop {
- match input.next() {
- None => break Ident::new("__inline_mac", Span::call_site()),
- Some(TT::Ident(kind)) => match &*kind.to_string() {
- "impl" => break Ident::new("__inline_mac_impl", Span::call_site()),
- kind @ ("struct" | "enum" | "union" | "fn" | "mod" | "trait" | "type" | "const" | "static") => {
- if let TT::Ident(name) = &input.tt {
- break Ident::new(&format!("__inline_mac_{kind}_{name}"), Span::call_site());
- } else {
- break Ident::new(&format!("__inline_mac_{kind}"), Span::call_site());
- }
- },
- _ => {},
- },
- _ => {},
- }
- }
- };
-
- let mut expander = Expander::default();
- let mut mac = MacWriter::new(mac_name);
- if let Err(e) = expander.expand(input.into_iter(), &mut mac) {
- return e;
- }
- let mut out = TokenStream::new();
- mac.finish(&mut out);
- out.extend(expander.expn);
- out
-}
-
-/// Wraps a `TokenStream` iterator with a single token lookahead.
-struct LookaheadIter {
- tt: TT,
- iter: IntoIter,
-}
-impl LookaheadIter {
- fn new(mut iter: IntoIter) -> Option<Self> {
- iter.next().map(|tt| Self { tt, iter })
- }
-
- /// Get's the lookahead token, replacing it with the next token in the stream.
- /// Note: If there isn't a next token, this will not return the lookahead token.
- fn next(&mut self) -> Option<TT> {
- self.iter.next().map(|tt| mem::replace(&mut self.tt, tt))
- }
-}
-
-/// Builds the macro used to implement all the `inline!` macro calls.
-struct MacWriter {
- name: Ident,
- macros: TokenStream,
- next_idx: usize,
-}
-impl MacWriter {
- fn new(name: Ident) -> Self {
- Self {
- name,
- macros: TokenStream::new(),
- next_idx: 0,
- }
- }
-
- /// Inserts a new `inline!` call.
- fn insert(&mut self, name_span: Span, bang_span: Span, body: Group, expander: &mut Expander) -> Result<()> {
- let idx = self.next_idx;
- self.next_idx += 1;
-
- let mut inner = Expander::for_arm(idx);
- inner.expand(body.stream().into_iter(), self)?;
- let new_arm = inner.arm.unwrap();
-
- self.macros.extend([
- TT::Group(Group::new(Parenthesis, new_arm.args_def)),
- TT::Punct(Punct::new('=', Joint)),
- TT::Punct(Punct::new('>', Alone)),
- TT::Group(Group::new(Parenthesis, inner.expn)),
- TT::Punct(Punct::new(';', Alone)),
- ]);
-
- expander.expn.extend([
- TT::Ident({
- let mut name = self.name.clone();
- name.set_span(name_span);
- name
- }),
- TT::Punct(punct_with_span('!', Alone, bang_span)),
- ]);
- let mut call_body = TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]);
- if let Some(arm) = expander.arm.as_mut() {
- if !new_arm.args.is_empty() {
- arm.add_sub_args(new_arm.args, &mut call_body);
- }
- } else {
- call_body.extend(new_arm.args);
- }
- let mut g = Group::new(body.delimiter(), call_body);
- g.set_span(body.span());
- expander.expn.extend([TT::Group(g)]);
- Ok(())
- }
-
- /// Creates the macro definition.
- fn finish(self, out: &mut TokenStream) {
- if self.next_idx != 0 {
- out.extend([
- TT::Ident(Ident::new("macro_rules", Span::call_site())),
- TT::Punct(Punct::new('!', Alone)),
- TT::Ident(self.name),
- TT::Group(Group::new(Brace, self.macros)),
- ])
- }
- }
-}
-
-struct MacroArm {
- args_def: TokenStream,
- args: Vec<TT>,
-}
-impl MacroArm {
- fn add_single_arg_def(&mut self, kind: &str, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {
- let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site());
- self.args_def.extend([
- TT::Punct(Punct::new('$', Alone)),
- TT::Ident(name.clone()),
- TT::Punct(Punct::new(':', Alone)),
- TT::Ident(Ident::new(kind, Span::call_site())),
- ]);
- name.set_span(arg_span);
- out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]);
- }
-
- fn add_parenthesized_arg_def(&mut self, kind: Ident, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {
- let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site());
- self.args_def.extend([TT::Group(Group::new(
- Parenthesis,
- TokenStream::from_iter([
- TT::Punct(Punct::new('$', Alone)),
- TT::Ident(name.clone()),
- TT::Punct(Punct::new(':', Alone)),
- TT::Ident(kind),
- ]),
- ))]);
- name.set_span(arg_span);
- out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]);
- }
-
- fn add_multi_arg_def(&mut self, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {
- let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site());
- self.args_def.extend([TT::Group(Group::new(
- Parenthesis,
- TokenStream::from_iter([
- TT::Punct(Punct::new('$', Alone)),
- TT::Group(Group::new(
- Parenthesis,
- TokenStream::from_iter([
- TT::Punct(Punct::new('$', Alone)),
- TT::Ident(name.clone()),
- TT::Punct(Punct::new(':', Alone)),
- TT::Ident(Ident::new("tt", Span::call_site())),
- ]),
- )),
- TT::Punct(Punct::new('*', Alone)),
- ]),
- ))]);
- name.set_span(arg_span);
- out.extend([
- TT::Punct(punct_with_span('$', Alone, dollar_span)),
- TT::Group(group_with_span(
- Parenthesis,
- TokenStream::from_iter([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]),
- dollar_span,
- )),
- TT::Punct(punct_with_span('*', Alone, dollar_span)),
- ]);
- }
-
- fn add_arg(&mut self, dollar_span: Span, tt: TT, input: &mut IntoIter, out: &mut TokenStream) -> Result<()> {
- match tt {
- TT::Punct(p) if p.as_char() == ESCAPE_CHAR => out.extend([TT::Punct(p)]),
- TT::Punct(p) if p.as_char() == '\'' && p.spacing() == Joint => {
- let lt_name = expect_tt(
- input.next(),
- |tt| match tt {
- TT::Ident(x) => Some(x),
- _ => None,
- },
- "lifetime name",
- p.span(),
- )?;
- let arg_span = p.span().join(lt_name.span()).unwrap_or(p.span());
- self.add_single_arg_def("lifetime", dollar_span, arg_span, out);
- self.args.extend([TT::Punct(p), TT::Ident(lt_name)]);
- },
- TT::Ident(x) => {
- self.add_single_arg_def("ident", dollar_span, x.span(), out);
- self.args.push(TT::Ident(x));
- },
- TT::Literal(x) => {
- self.add_single_arg_def("literal", dollar_span, x.span(), out);
- self.args.push(TT::Literal(x));
- },
- TT::Group(g) if g.delimiter() == Parenthesis => {
- let mut inner = g.stream().into_iter();
- if let Some(TT::Punct(p)) = inner.next()
- && p.as_char() == '@'
- {
- let kind = expect_tt(
- inner.next(),
- |tt| match tt {
- TT::Ident(kind) => Some(kind),
- _ => None,
- },
- "a macro fragment specifier",
- p.span(),
- )?;
- self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out);
- self.args.push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span())))
- } else {
- self.add_multi_arg_def(dollar_span, g.span(), out);
- self.args.push(TT::Group(g));
- }
- },
- tt => return Err(make_error("unsupported escape", tt.span())),
- };
- Ok(())
- }
-
- fn add_sub_args(&mut self, args: Vec<TT>, out: &mut TokenStream) {
- self.add_multi_arg_def(Span::call_site(), Span::call_site(), out);
- self.args
- .extend([TT::Group(Group::new(Parenthesis, TokenStream::from_iter(args)))]);
- }
-}
-
-#[derive(Default)]
-struct Expander {
- arm: Option<MacroArm>,
- expn: TokenStream,
-}
-impl Expander {
- fn for_arm(idx: usize) -> Self {
- Self {
- arm: Some(MacroArm {
- args_def: TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]),
- args: Vec::new(),
- }),
- expn: TokenStream::new(),
- }
- }
-
- fn write_tt(&mut self, tt: TT, mac: &mut MacWriter) -> Result<()> {
- match tt {
- TT::Group(g) => {
- let outer = mem::take(&mut self.expn);
- self.expand(g.stream().into_iter(), mac)?;
- let inner = mem::replace(&mut self.expn, outer);
- self.expn
- .extend([TT::Group(group_with_span(g.delimiter(), inner, g.span()))]);
- },
- tt => self.expn.extend([tt]),
- }
- Ok(())
- }
-
- fn expand(&mut self, input: IntoIter, mac: &mut MacWriter) -> Result<()> {
- let Some(mut input) = LookaheadIter::new(input) else {
- return Ok(());
- };
- while let Some(tt) = input.next() {
- if let TT::Punct(p) = &tt
- && p.as_char() == ESCAPE_CHAR
- && let Some(arm) = self.arm.as_mut()
- {
- arm.add_arg(p.span(), mem::replace(&mut input.tt, tt), &mut input.iter, &mut self.expn)?;
- if input.next().is_none() {
- return Ok(());
- }
- } else if let TT::Punct(p) = &input.tt
- && p.as_char() == '!'
- && let TT::Ident(name) = &tt
- && name.to_string() == "inline"
- {
- let g = expect_tt(
- input.iter.next(),
- |tt| match tt {
- TT::Group(g) => Some(g),
- _ => None,
- },
- "macro arguments",
- p.span(),
- )?;
- mac.insert(name.span(), p.span(), g, self)?;
- if input.next().is_none() {
- return Ok(());
- }
- } else {
- self.write_tt(tt, mac)?;
- }
- }
- self.write_tt(input.tt, mac)
- }
-}
diff --git a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs
index c28220b97..d737a832d 100644
--- a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs
+++ b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:../../ui/auxiliary/proc_macros.rs
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
#![allow(unused)]
@@ -156,7 +156,7 @@ fn main() {
for i in {{{{xx}}}} {{{{{{{{}}}}}}}}
while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}}
-
+
while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}}
let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} };
diff --git a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr
index 1a7311b33..74be5b2e2 100644
--- a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr
+++ b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.stderr
@@ -6,6 +6,7 @@ LL | let w = { 3 };
|
= help: try refactoring your code to minimize nesting
= note: `-D clippy::excessive-nesting` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::excessive_nesting)]`
error: this block is too nested
--> $DIR/excessive_nesting.rs:67:17
diff --git a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
index 815d00935..13b6d7ff9 100644
--- a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
+++ b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
@@ -6,6 +6,7 @@ LL | let _ = opt.expect("");
|
= note: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::expect_used)]`
error: used `expect()` on a `Result` value
--> $DIR/expect_used.rs:12:13
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml
new file mode 100644
index 000000000..15d175ef1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml
@@ -0,0 +1 @@
+enforce-iter-loop-reborrow = true
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed
new file mode 100644
index 000000000..468da22a9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::explicit_iter_loop)]
+
+fn main() {
+ let mut vec = vec![1, 2, 3];
+ let rmvec = &mut vec;
+ for _ in &*rmvec {}
+ //~^ ERROR: it is more concise to loop over references to containers
+ for _ in &mut *rmvec {}
+ //~^ ERROR: it is more concise to loop over references to containers
+}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs
new file mode 100644
index 000000000..a93464860
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::explicit_iter_loop)]
+
+fn main() {
+ let mut vec = vec![1, 2, 3];
+ let rmvec = &mut vec;
+ for _ in rmvec.iter() {}
+ //~^ ERROR: it is more concise to loop over references to containers
+ for _ in rmvec.iter_mut() {}
+ //~^ ERROR: it is more concise to loop over references to containers
+}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr
new file mode 100644
index 000000000..587d4f9b3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr
@@ -0,0 +1,17 @@
+error: it is more concise to loop over references to containers instead of using explicit iteration methods
+ --> $DIR/explicit_iter_loop.rs:6:14
+ |
+LL | for _ in rmvec.iter() {}
+ | ^^^^^^^^^^^^ help: to write this more concisely, try: `&*rmvec`
+ |
+ = note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::explicit_iter_loop)]`
+
+error: it is more concise to loop over references to containers instead of using explicit iteration methods
+ --> $DIR/explicit_iter_loop.rs:8:14
+ |
+LL | for _ in rmvec.iter_mut() {}
+ | ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *rmvec`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr b/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr
index 87bdb61c6..717a4bbfb 100644
--- a/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr
@@ -6,6 +6,7 @@ LL | fn g(_: bool, _: bool) {}
|
= help: consider refactoring bools into two-variant enums
= note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_params_excessive_bools)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
index dc255bdca..a2ca623e9 100644
--- a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
@@ -8,6 +8,7 @@ LL | | }
| |_^
|
= note: `-D clippy::too-many-lines` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::too_many_lines)]`
error: this function has too many lines (4/1)
--> $DIR/test.rs:25:1
diff --git a/src/tools/clippy/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr b/src/tools/clippy/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr
index 2841f62bc..305e00af2 100644
--- a/src/tools/clippy/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr
+++ b/src/tools/clippy/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr
@@ -10,6 +10,7 @@ note: same as this
LL | if x.get() {
| ^^^^^^^
= note: `-D clippy::ifs-same-cond` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui-toml/large_futures/large_futures.fixed b/src/tools/clippy/tests/ui-toml/large_futures/large_futures.fixed
new file mode 100644
index 000000000..7dea9fb95
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_futures/large_futures.fixed
@@ -0,0 +1,27 @@
+#![warn(clippy::large_futures)]
+
+fn main() {}
+
+pub async fn should_warn() {
+ let x = [0u8; 1024];
+ async {}.await;
+ dbg!(x);
+}
+
+pub async fn should_not_warn() {
+ let x = [0u8; 1020];
+ async {}.await;
+ dbg!(x);
+}
+
+pub async fn bar() {
+ Box::pin(should_warn()).await;
+
+ async {
+ let x = [0u8; 1024];
+ dbg!(x);
+ }
+ .await;
+
+ should_not_warn().await;
+}
diff --git a/src/tools/clippy/tests/ui-toml/large_futures/large_futures.stderr b/src/tools/clippy/tests/ui-toml/large_futures/large_futures.stderr
index b92734de2..7a02fcdbd 100644
--- a/src/tools/clippy/tests/ui-toml/large_futures/large_futures.stderr
+++ b/src/tools/clippy/tests/ui-toml/large_futures/large_futures.stderr
@@ -5,6 +5,7 @@ LL | should_warn().await;
| ^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(should_warn())`
|
= note: `-D clippy::large-futures` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_futures)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
index 7b5fb9e87..7508cd6c4 100644
--- a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
@@ -6,6 +6,7 @@ LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
|
= note: the configuration allows a maximum size of 600 bytes
= note: `-D clippy::large-include-file` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]`
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: attempted to include a large file
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml b/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml
new file mode 100644
index 000000000..584335dc2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml
@@ -0,0 +1 @@
+stack-size-threshold = 1000
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs
new file mode 100644
index 000000000..39798ffea
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs
@@ -0,0 +1,17 @@
+#![warn(clippy::large_stack_frames)]
+
+// We use this helper function instead of writing [0; 4294967297] directly to represent a
+// case that large_stack_arrays can't catch
+fn create_array<const N: usize>() -> [u8; N] {
+ [0; N]
+}
+
+fn f() {
+ let _x = create_array::<1000>();
+}
+fn f2() {
+ //~^ ERROR: this function allocates a large amount of stack space
+ let _x = create_array::<1001>();
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr
new file mode 100644
index 000000000..67ee57ab6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr
@@ -0,0 +1,15 @@
+error: this function allocates a large amount of stack space
+ --> $DIR/large_stack_frames.rs:12:1
+ |
+LL | / fn f2() {
+LL | |
+LL | | let _x = create_array::<1001>();
+LL | | }
+ | |_^
+ |
+ = note: allocating large amounts of stack space can overflow the stack
+ = note: `-D clippy::large-stack-frames` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml
new file mode 100644
index 000000000..45bcbce1e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml
@@ -0,0 +1 @@
+pass-by-value-size-limit = 512
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed
new file mode 100644
index 000000000..3c87c79cf
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::large_types_passed_by_value)]
+
+fn f(_v: [u8; 512]) {}
+fn f2(_v: &[u8; 513]) {}
+//~^ ERROR: this argument (513 byte) is passed by value
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs
new file mode 100644
index 000000000..0572373a6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::large_types_passed_by_value)]
+
+fn f(_v: [u8; 512]) {}
+fn f2(_v: [u8; 513]) {}
+//~^ ERROR: this argument (513 byte) is passed by value
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr
new file mode 100644
index 000000000..6678a2b47
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr
@@ -0,0 +1,11 @@
+error: this argument (513 byte) is passed by value, but might be more efficient if passed by reference (limit: 512 byte)
+ --> $DIR/large_types_passed_by_value.rs:4:11
+ |
+LL | fn f2(_v: [u8; 513]) {}
+ | ^^^^^^^^^ help: consider passing by reference instead: `&[u8; 513]`
+ |
+ = note: `-D clippy::large-types-passed-by-value` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_types_passed_by_value)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.fixed b/src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.fixed
new file mode 100644
index 000000000..f013153f5
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.fixed
@@ -0,0 +1,23 @@
+#![allow(clippy::excessive_precision)]
+#![warn(clippy::unreadable_literal)]
+
+fn allow_inconsistent_digit_grouping() {
+ #![allow(clippy::inconsistent_digit_grouping)]
+ let _pass1 = 100_200_300.123456789;
+}
+
+fn main() {
+ allow_inconsistent_digit_grouping();
+
+ let _pass1 = 100_200_300.100_200_300;
+ let _pass2 = 1.123456789;
+ let _pass3 = 1.0;
+ let _pass4 = 10000.00001;
+ let _pass5 = 1.123456789e1;
+
+ // due to clippy::inconsistent-digit-grouping
+ let _fail1 = 100_200_300.123_456_789;
+
+ // fail due to the integer part
+ let _fail2 = 100_200_300.300_200_100;
+}
diff --git a/src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.stderr b/src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.stderr
index ac9d89d0c..ef97e5d3f 100644
--- a/src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/lint_decimal_readability/test.stderr
@@ -5,6 +5,7 @@ LL | let _fail1 = 100_200_300.123456789;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider: `100_200_300.123_456_789`
|
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`
error: long literal lacking separators
--> $DIR/test.rs:22:18
@@ -13,6 +14,7 @@ LL | let _fail2 = 100200300.300200100;
| ^^^^^^^^^^^^^^^^^^^ help: consider: `100_200_300.300_200_100`
|
= note: `-D clippy::unreadable-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unreadable_literal)]`
error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml b/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml
new file mode 100644
index 000000000..cdae1da01
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml
@@ -0,0 +1 @@
+matches-for-let-else = "AllTypes"
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed
new file mode 100644
index 000000000..972f6aa40
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::manual_let_else)]
+
+enum Foo {
+ A(u8),
+ B,
+}
+
+fn main() {
+ let Foo::A(x) = Foo::A(1) else { return };
+}
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs
new file mode 100644
index 000000000..fdaba4ad2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs
@@ -0,0 +1,14 @@
+#![warn(clippy::manual_let_else)]
+
+enum Foo {
+ A(u8),
+ B,
+}
+
+fn main() {
+ let x = match Foo::A(1) {
+ //~^ ERROR: this could be rewritten as `let...else`
+ Foo::A(x) => x,
+ Foo::B => return,
+ };
+}
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr
new file mode 100644
index 000000000..5c2c86c37
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr
@@ -0,0 +1,15 @@
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:9:5
+ |
+LL | / let x = match Foo::A(1) {
+LL | |
+LL | | Foo::A(x) => x,
+LL | | Foo::B => return,
+LL | | };
+ | |______^ help: consider writing: `let Foo::A(x) = Foo::A(1) else { return };`
+ |
+ = note: `-D clippy::manual-let-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed b/src/tools/clippy/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed
new file mode 100644
index 000000000..36540bf1d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed
@@ -0,0 +1,24 @@
+#![deny(clippy::index_refutable_slice)]
+
+fn below_limit() {
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
+ //~^ ERROR: binding can be a slice pattern
+ // This would usually not be linted but is included now due to the
+ // index limit in the config file
+ println!("{}", slice_7);
+ }
+}
+
+fn above_limit() {
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some(slice) = slice {
+ // This will not be linted as 8 is above the limit
+ println!("{}", slice[8]);
+ }
+}
+
+fn main() {
+ below_limit();
+ above_limit();
+}
diff --git a/src/tools/clippy/tests/ui-toml/min_ident_chars/min_ident_chars.stderr b/src/tools/clippy/tests/ui-toml/min_ident_chars/min_ident_chars.stderr
index d9a27628d..7f00fac49 100644
--- a/src/tools/clippy/tests/ui-toml/min_ident_chars/min_ident_chars.stderr
+++ b/src/tools/clippy/tests/ui-toml/min_ident_chars/min_ident_chars.stderr
@@ -5,6 +5,7 @@ LL | use extern_types::Aaa;
| ^^^
|
= note: `-D clippy::min-ident-chars` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]`
error: this ident is too short (3 <= 3)
--> $DIR/min_ident_chars.rs:10:5
diff --git a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed
new file mode 100644
index 000000000..6c58e07d8
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed
@@ -0,0 +1,98 @@
+#![allow(clippy::redundant_clone, clippy::unnecessary_operation)]
+#![warn(clippy::manual_non_exhaustive, clippy::borrow_as_ptr, clippy::manual_bits)]
+
+use std::mem::{size_of, size_of_val};
+use std::ops::Deref;
+
+mod enums {
+ enum E {
+ A,
+ B,
+ #[doc(hidden)]
+ _C,
+ }
+
+ // user forgot to remove the marker
+ #[non_exhaustive]
+ enum Ep {
+ A,
+ B,
+ #[doc(hidden)]
+ _C,
+ }
+}
+
+fn option_as_ref_deref() {
+ let mut opt = Some(String::from("123"));
+
+ let _ = opt.as_ref().map(String::as_str);
+ let _ = opt.as_ref().map(|x| x.as_str());
+ let _ = opt.as_mut().map(String::as_mut_str);
+ let _ = opt.as_mut().map(|x| x.as_mut_str());
+}
+
+fn match_like_matches() {
+ let _y = match Some(5) {
+ Some(0) => true,
+ _ => false,
+ };
+}
+
+fn match_same_arms() {
+ match (1, 2, 3) {
+ (1, .., 3) => 42,
+ (.., 3) => 42,
+ _ => 0,
+ };
+}
+
+fn match_same_arms2() {
+ let _ = match Some(42) {
+ Some(_) => 24,
+ None => 24,
+ };
+}
+
+fn manual_strip_msrv() {
+ let s = "hello, world!";
+ if s.starts_with("hello, ") {
+ assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
+ }
+}
+
+fn check_index_refutable_slice() {
+ // This shouldn't trigger `clippy::index_refutable_slice` as the suggestion
+ // would only be valid from 1.42.0 onward
+ let slice: Option<&[u32]> = Some(&[1]);
+ if let Some(slice) = slice {
+ println!("{}", slice[0]);
+ }
+}
+
+fn map_clone_suggest_copied() {
+ // This should still trigger the lint but suggest `cloned()` instead of `copied()`
+ let _: Option<u64> = Some(&16).cloned();
+}
+
+fn borrow_as_ptr() {
+ let val = 1;
+ let _p = &val as *const i32;
+
+ let mut val_mut = 1;
+ let _p_mut = &mut val_mut as *mut i32;
+}
+
+fn manual_bits() {
+ size_of::<i8>() * 8;
+ size_of_val(&0u32) * 8;
+}
+
+fn main() {
+ option_as_ref_deref();
+ match_like_matches();
+ match_same_arms();
+ match_same_arms2();
+ manual_strip_msrv();
+ check_index_refutable_slice();
+ borrow_as_ptr();
+}
diff --git a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr
index 5dae5af7e..5b1f8dbd3 100644
--- a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr
+++ b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr
@@ -5,6 +5,7 @@ LL | let _: Option<u64> = Some(&16).map(|b| *b);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `Some(&16).cloned()`
|
= note: `-D clippy::map-clone` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_clone)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed
new file mode 100644
index 000000000..5f4f007cf
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed
@@ -0,0 +1,16 @@
+#![warn(clippy::missing_enforced_import_renames)]
+
+use std::alloc as colla;
+use std::option::Option as Maybe;
+use std::process::{exit as goodbye, Child as Kid};
+use std::thread::sleep as thread_sleep;
+#[rustfmt::skip]
+use std::{
+ any::{type_name as ident, Any},
+ clone as foo,
+ sync :: Mutex as StdMutie,
+};
+
+fn main() {
+ use std::collections::BTreeMap as Map;
+}
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
index 45de8fdff..0aea330d4 100644
--- a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
@@ -5,6 +5,7 @@ LL | use std::process::{exit as wrong_exit, Child as Kid};
| ^^^^^^^^^^^^^^^^^^ help: try: `exit as goodbye`
|
= note: `-D clippy::missing-enforced-import-renames` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_enforced_import_renames)]`
error: this import should be renamed
--> $DIR/conf_missing_enforced_import_rename.rs:6:1
diff --git a/src/tools/clippy/tests/ui-toml/module_inception/module_inception.stderr b/src/tools/clippy/tests/ui-toml/module_inception/module_inception.stderr
index a5a09c322..0eb25453b 100644
--- a/src/tools/clippy/tests/ui-toml/module_inception/module_inception.stderr
+++ b/src/tools/clippy/tests/ui-toml/module_inception/module_inception.stderr
@@ -7,6 +7,7 @@ LL | | }
| |_________^
|
= note: `-D clippy::module-inception` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::module_inception)]`
error: module has the same name as its containing module
--> $DIR/module_inception.rs:11:5
diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed
index 054db5d93..673106f0b 100644
--- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed
+++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed
@@ -1,5 +1,4 @@
-//@aux-build:proc_macro_derive.rs:proc-macro
-//@run-rustfix
+//@aux-build:proc_macro_derive.rs
#![warn(clippy::nonstandard_macro_braces)]
diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs
index 95d1a2297..b9c69037b 100644
--- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs
+++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs
@@ -1,5 +1,4 @@
-//@aux-build:proc_macro_derive.rs:proc-macro
-//@run-rustfix
+//@aux-build:proc_macro_derive.rs
#![warn(clippy::nonstandard_macro_braces)]
diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
index 7ae381597..483941d3c 100644
--- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
+++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
@@ -1,37 +1,38 @@
error: use of irregular braces for `vec!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:44:13
+ --> $DIR/conf_nonstandard_macro_braces.rs:43:13
|
LL | let _ = vec! {1, 2, 3};
| ^^^^^^^^^^^^^^ help: consider writing: `vec![1, 2, 3]`
|
= note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::nonstandard_macro_braces)]`
error: use of irregular braces for `format!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:45:13
+ --> $DIR/conf_nonstandard_macro_braces.rs:44:13
|
LL | let _ = format!["ugh {} stop being such a good compiler", "hello"];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `format!("ugh {} stop being such a good compiler", "hello")`
error: use of irregular braces for `matches!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:46:13
+ --> $DIR/conf_nonstandard_macro_braces.rs:45:13
|
LL | let _ = matches!{{}, ()};
| ^^^^^^^^^^^^^^^^ help: consider writing: `matches!({}, ())`
error: use of irregular braces for `quote!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:47:13
+ --> $DIR/conf_nonstandard_macro_braces.rs:46:13
|
LL | let _ = quote!(let x = 1;);
| ^^^^^^^^^^^^^^^^^^ help: consider writing: `quote!{let x = 1;}`
error: use of irregular braces for `quote::quote!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:48:13
+ --> $DIR/conf_nonstandard_macro_braces.rs:47:13
|
LL | let _ = quote::quote!(match match match);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `quote::quote!{match match match}`
error: use of irregular braces for `vec!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:19:9
+ --> $DIR/conf_nonstandard_macro_braces.rs:18:9
|
LL | vec!{0, 0, 0}
| ^^^^^^^^^^^^^ help: consider writing: `vec![0, 0, 0]`
@@ -42,13 +43,13 @@ LL | let _ = test!(); // trigger when macro def is inside our own crate
= note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
error: use of irregular braces for `type_pos!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:57:12
+ --> $DIR/conf_nonstandard_macro_braces.rs:56:12
|
LL | let _: type_pos!(usize) = vec![];
| ^^^^^^^^^^^^^^^^ help: consider writing: `type_pos![usize]`
error: use of irregular braces for `eprint!` macro
- --> $DIR/conf_nonstandard_macro_braces.rs:59:5
+ --> $DIR/conf_nonstandard_macro_braces.rs:58:5
|
LL | eprint!("test if user config overrides defaults");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `eprint!["test if user config overrides defaults"]`
diff --git a/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml
new file mode 100644
index 000000000..40d7dfd93
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml
@@ -0,0 +1 @@
+allowed-dotfiles = ["dot"]
diff --git a/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs
new file mode 100644
index 000000000..a34b15f4a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::path_ends_with_ext)]
+
+use std::path::Path;
+
+fn f(p: &Path) {
+ p.ends_with(".dot");
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/print_macro/print_macro.stderr b/src/tools/clippy/tests/ui-toml/print_macro/print_macro.stderr
index d4b1ae84f..fe2d5afc6 100644
--- a/src/tools/clippy/tests/ui-toml/print_macro/print_macro.stderr
+++ b/src/tools/clippy/tests/ui-toml/print_macro/print_macro.stderr
@@ -5,6 +5,7 @@ LL | print!("{n}");
| ^^^^^^^^^^^^^
|
= note: `-D clippy::print-stdout` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_stdout)]`
error: use of `eprint!`
--> $DIR/print_macro.rs:7:5
@@ -13,6 +14,7 @@ LL | eprint!("{n}");
| ^^^^^^^^^^^^^^
|
= note: `-D clippy::print-stderr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_stderr)]`
error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr
index a47418705..1ecdabbc0 100644
--- a/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr
+++ b/src/tools/clippy/tests/ui-toml/pub_crate_missing_docs/pub_crate_missing_doc.stderr
@@ -5,6 +5,7 @@ LL | pub(crate) fn crate_no_docs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]`
error: missing documentation for a function
--> $DIR/pub_crate_missing_doc.rs:15:5
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml b/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml
new file mode 100644
index 000000000..df505ed96
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml
@@ -0,0 +1 @@
+large-error-threshold = 512
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs
new file mode 100644
index 000000000..dea4d61a9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::result_large_err)]
+
+fn f() -> Result<(), [u8; 511]> {
+ todo!()
+}
+fn f2() -> Result<(), [u8; 512]> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
+ todo!()
+}
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr
new file mode 100644
index 000000000..b0936319d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr
@@ -0,0 +1,12 @@
+error: the `Err`-variant returned from this function is very large
+ --> $DIR/result_large_err.rs:6:12
+ |
+LL | fn f2() -> Result<(), [u8; 512]> {
+ | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
+ |
+ = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
+ = note: `-D clippy::result-large-err` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_large_err)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed b/src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed
index fc8038a09..306cd23c8 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/both.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/both.rs b/src/tools/clippy/tests/ui-toml/semicolon_block/both.rs
index 52ce1f038..b9f012cfb 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/both.rs
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/both.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr b/src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr
index 2f58842ea..ca6a7475c 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/both.stderr
@@ -1,10 +1,11 @@
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/both.rs:43:5
+ --> $DIR/both.rs:42:5
|
LL | { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::semicolon-outside-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::semicolon_outside_block)]`
help: put the `;` here
|
LL - { unit_fn_block(); }
@@ -12,7 +13,7 @@ LL + { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/both.rs:44:5
+ --> $DIR/both.rs:43:5
|
LL | unsafe { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + unsafe { unit_fn_block() };
|
error: consider moving the `;` inside the block for consistent formatting
- --> $DIR/both.rs:49:5
+ --> $DIR/both.rs:48:5
|
LL | / {
LL | | unit_fn_block();
@@ -33,6 +34,7 @@ LL | | };
| |______^
|
= note: `-D clippy::semicolon-inside-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`
help: put the `;` here
|
LL ~ unit_fn_block();
@@ -40,7 +42,7 @@ LL ~ }
|
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/both.rs:63:5
+ --> $DIR/both.rs:62:5
|
LL | { m!(()); }
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed
index 23df98301..5b7f8e00c 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs
index e8516f79b..3a81661cd 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr
index 2569dc4b4..ce03d7d75 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr
@@ -1,5 +1,5 @@
error: consider moving the `;` inside the block for consistent formatting
- --> $DIR/semicolon_inside_block.rs:48:5
+ --> $DIR/semicolon_inside_block.rs:47:5
|
LL | / {
LL | | unit_fn_block();
@@ -8,6 +8,7 @@ LL | | };
| |______^
|
= note: `-D clippy::semicolon-inside-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`
help: put the `;` here
|
LL ~ unit_fn_block();
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed
index 7e9055e71..14604eaea 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs
index 4dc956d8a..c76720146 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr
index 6dd3577dd..fcc409796 100644
--- a/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr
+++ b/src/tools/clippy/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr
@@ -1,10 +1,11 @@
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/semicolon_outside_block.rs:42:5
+ --> $DIR/semicolon_outside_block.rs:41:5
|
LL | { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::semicolon-outside-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::semicolon_outside_block)]`
help: put the `;` here
|
LL - { unit_fn_block(); }
@@ -12,7 +13,7 @@ LL + { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/semicolon_outside_block.rs:43:5
+ --> $DIR/semicolon_outside_block.rs:42:5
|
LL | unsafe { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + unsafe { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/semicolon_outside_block.rs:62:5
+ --> $DIR/semicolon_outside_block.rs:61:5
|
LL | { m!(()); }
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr b/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
index c72f8c648..6df11cc1f 100644
--- a/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
@@ -11,6 +11,7 @@ LL | rc_is_not_send: Rc<String>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use a thread-safe type that implements `Send`
= note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_send_fields_in_send_ty)]`
error: some fields in `MultiField<T>` are not safe to be sent to another thread
--> $DIR/test.rs:19:1
diff --git a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr
index 4e7c70d18..9237c9c9d 100644
--- a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr
@@ -8,6 +8,7 @@ LL | | }
|
= help: consider using a state machine or refactoring bools into two-variant enums
= note: `-D clippy::struct-excessive-bools` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::struct_excessive_bools)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
index 14e131944..f8ace7995 100644
--- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
@@ -4,7 +4,7 @@ error[E0080]: evaluation of `main::{constant#3}` failed
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
-note: erroneous constant used
+note: erroneous constant encountered
--> $DIR/test.rs:37:5
|
LL | const { &ARR[idx4()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.
@@ -18,6 +18,7 @@ LL | x[index];
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
= note: `-D clippy::indexing-slicing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
error: indexing may panic
--> $DIR/test.rs:46:5
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr b/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr
index 9082c1c54..621328292 100644
--- a/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr
@@ -5,6 +5,7 @@ LL | fn test(toto: ()) {}
| ^^^^
|
= note: `-D clippy::disallowed-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`
error: use of a disallowed/placeholder name `toto`
--> $DIR/conf_french_disallowed_name.rs:9:9
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr
index fc137c225..d9b70e3b7 100644
--- a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr
@@ -5,6 +5,7 @@ LL | let re = Regex::new(r"ab.*c").unwrap();
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::disallowed-methods` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
error: use of a disallowed method `regex::Regex::is_match`
--> $DIR/conf_disallowed_methods.rs:36:5
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr b/src/tools/clippy/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr
index e3ece799c..4ac96deb4 100644
--- a/src/tools/clippy/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr
@@ -5,6 +5,7 @@ LL | use std::sync::atomic::AtomicU32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::disallowed-types` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]`
error: `std::time::Instant` is not allowed according to config
--> $DIR/conf_disallowed_types.rs:8:1
diff --git a/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs b/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs
index 78784bfff..145a2ce44 100644
--- a/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs
+++ b/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs
@@ -1,6 +1,6 @@
//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)"
//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)"
-
+//@no-rustfix
#![warn(clippy::trivially_copy_pass_by_ref)]
#![allow(clippy::needless_pass_by_ref_mut)]
diff --git a/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.stderr b/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.stderr
index db5d68053..262d302e7 100644
--- a/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.stderr
@@ -5,6 +5,7 @@ LL | fn bad(x: &u16, y: &Foo) {}
| ^^^^ help: consider passing by value instead: `u16`
|
= note: `-D clippy::trivially-copy-pass-by-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::trivially_copy_pass_by_ref)]`
error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
--> $DIR/test.rs:15:20
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index cdabe6460..4bed5c149 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -10,6 +10,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
allow-print-in-tests
allow-private-module-inception
allow-unwrap-in-tests
+ allowed-dotfiles
allowed-idents-below-min-chars
allowed-scripts
arithmetic-side-effects-allowed
@@ -28,6 +29,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
disallowed-types
doc-valid-idents
enable-raw-pointer-heuristic-for-send
+ enforce-iter-loop-reborrow
enforced-import-renames
enum-variant-name-threshold
enum-variant-size-threshold
@@ -81,6 +83,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
allow-print-in-tests
allow-private-module-inception
allow-unwrap-in-tests
+ allowed-dotfiles
allowed-idents-below-min-chars
allowed-scripts
arithmetic-side-effects-allowed
@@ -99,6 +102,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
disallowed-types
doc-valid-idents
enable-raw-pointer-heuristic-for-send
+ enforce-iter-loop-reborrow
enforced-import-renames
enum-variant-name-threshold
enum-variant-size-threshold
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs
new file mode 100644
index 000000000..2f0236122
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs
@@ -0,0 +1,5 @@
+fn f(x: Box<[u8; 500]>) {}
+//~^ ERROR: local variable doesn't need to be boxed here
+fn f2(x: Box<[u8; 501]>) {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr
new file mode 100644
index 000000000..2859a29f1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr
@@ -0,0 +1,11 @@
+error: local variable doesn't need to be boxed here
+ --> $DIR/boxed_local.rs:1:6
+ |
+LL | fn f(x: Box<[u8; 500]>) {}
+ | ^
+ |
+ = note: `-D clippy::boxed-local` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml b/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml
new file mode 100644
index 000000000..a9c42fca4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml
@@ -0,0 +1 @@
+too-large-for-stack = 500
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed
new file mode 100644
index 000000000..ebe92d9b5
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed
@@ -0,0 +1,9 @@
+#![warn(clippy::useless_vec)]
+
+fn main() {
+ let x = [0u8; 500];
+ //~^ ERROR: useless use of `vec!`
+ x.contains(&1);
+ let y = vec![0u8; 501];
+ y.contains(&1);
+}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs
new file mode 100644
index 000000000..e2886a8cc
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::useless_vec)]
+
+fn main() {
+ let x = vec![0u8; 500];
+ //~^ ERROR: useless use of `vec!`
+ x.contains(&1);
+ let y = vec![0u8; 501];
+ y.contains(&1);
+}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr
new file mode 100644
index 000000000..923cded5e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr
@@ -0,0 +1,11 @@
+error: useless use of `vec!`
+ --> $DIR/useless_vec.rs:4:13
+ |
+LL | let x = vec![0u8; 500];
+ | ^^^^^^^^^^^^^^ help: you can use an array directly: `[0u8; 500]`
+ |
+ = note: `-D clippy::useless-vec` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml b/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml
new file mode 100644
index 000000000..15906305c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml
@@ -0,0 +1 @@
+too-many-arguments-threshold = 10
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs
new file mode 100644
index 000000000..7b2d6897d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::too_many_arguments)]
+
+fn not_too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8) {}
+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) {}
+//~^ ERROR: this function has too many arguments
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr
new file mode 100644
index 000000000..a52e1fcb9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr
@@ -0,0 +1,11 @@
+error: this function has too many arguments (11/10)
+ --> $DIR/too_many_arguments.rs:4:1
+ |
+LL | 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) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::too-many-arguments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml b/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml
new file mode 100644
index 000000000..bf2ffdd0e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml
@@ -0,0 +1 @@
+type-complexity-threshold = 500
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs
new file mode 100644
index 000000000..b95f51343
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs
@@ -0,0 +1,7 @@
+// 480
+fn f(_: (u8, (u8, (u8, (u8, (u8, (u8,))))))) {}
+// 550
+fn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}
+//~^ ERROR: very complex type used
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr
new file mode 100644
index 000000000..8ca637f72
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr
@@ -0,0 +1,11 @@
+error: very complex type used. Consider factoring parts into `type` definitions
+ --> $DIR/type_complexity.rs:4:10
+ |
+LL | fn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::type-complexity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml
new file mode 100644
index 000000000..2f91866aa
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml
@@ -0,0 +1 @@
+max-trait-bounds = 5
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs
new file mode 100644
index 000000000..2454c1038
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs
@@ -0,0 +1,18 @@
+#![warn(clippy::type_repetition_in_bounds)]
+
+fn f<T>()
+where
+ T: Copy + Clone + Sync + Send + ?Sized + Unpin,
+ T: PartialEq,
+{
+}
+
+fn f2<T>()
+where
+ T: Copy + Clone + Sync + Send + ?Sized,
+ T: Unpin + PartialEq,
+ //~^ ERROR: this type has already been used as a bound predicate
+{
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr
new file mode 100644
index 000000000..2ae298497
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr
@@ -0,0 +1,12 @@
+error: this type has already been used as a bound predicate
+ --> $DIR/main.rs:13:5
+ |
+LL | T: Unpin + PartialEq,
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider combining the bounds: `T: Copy + Clone + Sync + Send + ?Sized + Unpin + PartialEq`
+ = note: `-D clippy::type-repetition-in-bounds` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::type_repetition_in_bounds)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs
deleted file mode 100644
index 1c591fc76..000000000
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-extern crate proc_macro;
-
-use proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree};
-
-#[proc_macro]
-pub fn unsafe_block(input: TokenStream) -> TokenStream {
- let span = input.into_iter().next().unwrap().span();
- TokenStream::from_iter([TokenTree::Ident(Ident::new("unsafe", span)), {
- let mut group = Group::new(Delimiter::Brace, TokenStream::new());
- group.set_span(span);
- TokenTree::Group(group)
- }])
-}
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
deleted file mode 100644
index e6dbb3d37..000000000
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-accept-comment-above-statement = true
-accept-comment-above-attributes = true
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml
new file mode 100644
index 000000000..3b205d536
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml
@@ -0,0 +1,2 @@
+# default configuration has `accept-comment-above-statement` and
+# `accept-comment-above-attributes` true
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml
new file mode 100644
index 000000000..57ecb902d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml
@@ -0,0 +1,3 @@
+# test with these options disabled
+accept-comment-above-statement = false
+accept-comment-above-attributes = false
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index 9a0fd0593..15edf2a7d 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
@@ -1,14 +1,15 @@
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:263:19
+ --> $DIR/undocumented_unsafe_blocks.rs:266:19
|
LL | /* Safety: */ unsafe {}
| ^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line
= note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:267:5
+ --> $DIR/undocumented_unsafe_blocks.rs:270:5
|
LL | unsafe {}
| ^^^^^^^^^
@@ -16,7 +17,7 @@ LL | unsafe {}
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:271:14
+ --> $DIR/undocumented_unsafe_blocks.rs:274:14
|
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
| ^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:271:29
+ --> $DIR/undocumented_unsafe_blocks.rs:274:29
|
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
| ^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:271:48
+ --> $DIR/undocumented_unsafe_blocks.rs:274:48
|
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
| ^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:275:18
+ --> $DIR/undocumented_unsafe_blocks.rs:278:18
|
LL | let _ = (42, unsafe {}, "test", unsafe {});
| ^^^^^^^^^
@@ -48,7 +49,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {});
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:275:37
+ --> $DIR/undocumented_unsafe_blocks.rs:278:37
|
LL | let _ = (42, unsafe {}, "test", unsafe {});
| ^^^^^^^^^
@@ -56,7 +57,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {});
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:279:14
+ --> $DIR/undocumented_unsafe_blocks.rs:282:14
|
LL | let _ = *unsafe { &42 };
| ^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | let _ = *unsafe { &42 };
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:284:19
+ --> $DIR/undocumented_unsafe_blocks.rs:287:19
|
LL | let _ = match unsafe {} {
| ^^^^^^^^^
@@ -72,7 +73,7 @@ LL | let _ = match unsafe {} {
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:290:14
+ --> $DIR/undocumented_unsafe_blocks.rs:293:14
|
LL | let _ = &unsafe {};
| ^^^^^^^^^
@@ -80,7 +81,7 @@ LL | let _ = &unsafe {};
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:294:14
+ --> $DIR/undocumented_unsafe_blocks.rs:297:14
|
LL | let _ = [unsafe {}; 5];
| ^^^^^^^^^
@@ -88,7 +89,7 @@ LL | let _ = [unsafe {}; 5];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:298:13
+ --> $DIR/undocumented_unsafe_blocks.rs:301:13
|
LL | let _ = unsafe {};
| ^^^^^^^^^
@@ -96,7 +97,7 @@ LL | let _ = unsafe {};
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:308:8
+ --> $DIR/undocumented_unsafe_blocks.rs:311:8
|
LL | t!(unsafe {});
| ^^^^^^^^^
@@ -104,7 +105,7 @@ LL | t!(unsafe {});
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:314:13
+ --> $DIR/undocumented_unsafe_blocks.rs:317:13
|
LL | unsafe {}
| ^^^^^^^^^
@@ -116,7 +117,7 @@ LL | t!();
= note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:322:5
+ --> $DIR/undocumented_unsafe_blocks.rs:325:5
|
LL | unsafe {} // SAFETY:
| ^^^^^^^^^
@@ -124,7 +125,7 @@ LL | unsafe {} // SAFETY:
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:326:5
+ --> $DIR/undocumented_unsafe_blocks.rs:329:5
|
LL | unsafe {
| ^^^^^^^^
@@ -132,7 +133,7 @@ LL | unsafe {
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:336:5
+ --> $DIR/undocumented_unsafe_blocks.rs:339:5
|
LL | unsafe {};
| ^^^^^^^^^
@@ -140,7 +141,7 @@ LL | unsafe {};
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:340:20
+ --> $DIR/undocumented_unsafe_blocks.rs:343:20
|
LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -148,7 +149,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:347:5
+ --> $DIR/undocumented_unsafe_blocks.rs:350:5
|
LL | unsafe impl A for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -156,7 +157,7 @@ LL | unsafe impl A for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:354:9
+ --> $DIR/undocumented_unsafe_blocks.rs:357:9
|
LL | unsafe impl B for (u32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -164,7 +165,7 @@ LL | unsafe impl B for (u32) {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:375:13
+ --> $DIR/undocumented_unsafe_blocks.rs:378:13
|
LL | unsafe impl T for $t {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -176,7 +177,7 @@ LL | no_safety_comment!(());
= note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:400:13
+ --> $DIR/undocumented_unsafe_blocks.rs:403:13
|
LL | unsafe impl T for $t {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -188,7 +189,7 @@ LL | no_safety_comment!(());
= note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:408:5
+ --> $DIR/undocumented_unsafe_blocks.rs:411:5
|
LL | unsafe impl T for (i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -196,7 +197,7 @@ LL | unsafe impl T for (i32) {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:400:13
+ --> $DIR/undocumented_unsafe_blocks.rs:403:13
|
LL | unsafe impl T for $t {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -208,7 +209,7 @@ LL | no_safety_comment!(u32);
= note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:414:5
+ --> $DIR/undocumented_unsafe_blocks.rs:417:5
|
LL | unsafe impl T for (bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -216,7 +217,7 @@ LL | unsafe impl T for (bool) {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:460:5
+ --> $DIR/undocumented_unsafe_blocks.rs:463:5
|
LL | unsafe impl NoComment for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -224,7 +225,7 @@ LL | unsafe impl NoComment for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:464:19
+ --> $DIR/undocumented_unsafe_blocks.rs:467:19
|
LL | /* SAFETY: */ unsafe impl InlineComment for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -232,7 +233,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:468:5
+ --> $DIR/undocumented_unsafe_blocks.rs:471:5
|
LL | unsafe impl TrailingComment for () {} // SAFETY:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -240,20 +241,21 @@ LL | unsafe impl TrailingComment for () {} // SAFETY:
= help: consider adding a safety comment on the preceding line
error: constant item has unnecessary safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:472:5
+ --> $DIR/undocumented_unsafe_blocks.rs:475:5
|
LL | const BIG_NUMBER: i32 = 1000000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:471:5
+ --> $DIR/undocumented_unsafe_blocks.rs:474:5
|
LL | // SAFETY:
| ^^^^^^^^^^
= note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:473:5
+ --> $DIR/undocumented_unsafe_blocks.rs:476:5
|
LL | unsafe impl Interference for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -261,7 +263,7 @@ LL | unsafe impl Interference for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:480:5
+ --> $DIR/undocumented_unsafe_blocks.rs:483:5
|
LL | unsafe impl ImplInFn for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -269,7 +271,7 @@ LL | unsafe impl ImplInFn for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:489:1
+ --> $DIR/undocumented_unsafe_blocks.rs:492:1
|
LL | unsafe impl CrateRoot for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -277,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
= help: consider adding a safety comment on the preceding line
error: statement has unnecessary safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:502:5
+ --> $DIR/undocumented_unsafe_blocks.rs:505:5
|
LL | / let _ = {
LL | | if unsafe { true } {
@@ -289,13 +291,13 @@ LL | | };
| |______^
|
help: consider removing the safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:501:5
+ --> $DIR/undocumented_unsafe_blocks.rs:504:5
|
LL | // SAFETY: this is more than one level away, so it should warn
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:503:12
+ --> $DIR/undocumented_unsafe_blocks.rs:506:12
|
LL | if unsafe { true } {
| ^^^^^^^^^^^^^^^
@@ -303,7 +305,7 @@ LL | if unsafe { true } {
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:506:23
+ --> $DIR/undocumented_unsafe_blocks.rs:509:23
|
LL | let bar = unsafe {};
| ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index ee1d3aa28..cc9530f79 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -1,14 +1,15 @@
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:262:19
+ --> $DIR/undocumented_unsafe_blocks.rs:266:19
|
LL | /* Safety: */ unsafe {}
| ^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line
= note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:266:5
+ --> $DIR/undocumented_unsafe_blocks.rs:270:5
|
LL | unsafe {}
| ^^^^^^^^^
@@ -16,7 +17,7 @@ LL | unsafe {}
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:270:14
+ --> $DIR/undocumented_unsafe_blocks.rs:274:14
|
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
| ^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:270:29
+ --> $DIR/undocumented_unsafe_blocks.rs:274:29
|
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
| ^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:270:48
+ --> $DIR/undocumented_unsafe_blocks.rs:274:48
|
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
| ^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:274:18
+ --> $DIR/undocumented_unsafe_blocks.rs:278:18
|
LL | let _ = (42, unsafe {}, "test", unsafe {});
| ^^^^^^^^^
@@ -48,7 +49,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {});
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:274:37
+ --> $DIR/undocumented_unsafe_blocks.rs:278:37
|
LL | let _ = (42, unsafe {}, "test", unsafe {});
| ^^^^^^^^^
@@ -56,7 +57,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {});
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:278:14
+ --> $DIR/undocumented_unsafe_blocks.rs:282:14
|
LL | let _ = *unsafe { &42 };
| ^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | let _ = *unsafe { &42 };
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:283:19
+ --> $DIR/undocumented_unsafe_blocks.rs:287:19
|
LL | let _ = match unsafe {} {
| ^^^^^^^^^
@@ -72,7 +73,7 @@ LL | let _ = match unsafe {} {
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:289:14
+ --> $DIR/undocumented_unsafe_blocks.rs:293:14
|
LL | let _ = &unsafe {};
| ^^^^^^^^^
@@ -80,7 +81,7 @@ LL | let _ = &unsafe {};
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:293:14
+ --> $DIR/undocumented_unsafe_blocks.rs:297:14
|
LL | let _ = [unsafe {}; 5];
| ^^^^^^^^^
@@ -88,7 +89,7 @@ LL | let _ = [unsafe {}; 5];
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:297:13
+ --> $DIR/undocumented_unsafe_blocks.rs:301:13
|
LL | let _ = unsafe {};
| ^^^^^^^^^
@@ -96,7 +97,7 @@ LL | let _ = unsafe {};
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:307:8
+ --> $DIR/undocumented_unsafe_blocks.rs:311:8
|
LL | t!(unsafe {});
| ^^^^^^^^^
@@ -104,7 +105,7 @@ LL | t!(unsafe {});
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:313:13
+ --> $DIR/undocumented_unsafe_blocks.rs:317:13
|
LL | unsafe {}
| ^^^^^^^^^
@@ -116,7 +117,7 @@ LL | t!();
= note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:321:5
+ --> $DIR/undocumented_unsafe_blocks.rs:325:5
|
LL | unsafe {} // SAFETY:
| ^^^^^^^^^
@@ -124,7 +125,7 @@ LL | unsafe {} // SAFETY:
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:325:5
+ --> $DIR/undocumented_unsafe_blocks.rs:329:5
|
LL | unsafe {
| ^^^^^^^^
@@ -132,7 +133,7 @@ LL | unsafe {
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:335:5
+ --> $DIR/undocumented_unsafe_blocks.rs:339:5
|
LL | unsafe {};
| ^^^^^^^^^
@@ -140,7 +141,7 @@ LL | unsafe {};
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:339:20
+ --> $DIR/undocumented_unsafe_blocks.rs:343:20
|
LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -148,7 +149,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:346:5
+ --> $DIR/undocumented_unsafe_blocks.rs:350:5
|
LL | unsafe impl A for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -156,7 +157,7 @@ LL | unsafe impl A for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:353:9
+ --> $DIR/undocumented_unsafe_blocks.rs:357:9
|
LL | unsafe impl B for (u32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -164,7 +165,7 @@ LL | unsafe impl B for (u32) {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:374:13
+ --> $DIR/undocumented_unsafe_blocks.rs:378:13
|
LL | unsafe impl T for $t {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -176,7 +177,7 @@ LL | no_safety_comment!(());
= note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:399:13
+ --> $DIR/undocumented_unsafe_blocks.rs:403:13
|
LL | unsafe impl T for $t {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -188,7 +189,7 @@ LL | no_safety_comment!(());
= note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:407:5
+ --> $DIR/undocumented_unsafe_blocks.rs:411:5
|
LL | unsafe impl T for (i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -196,7 +197,7 @@ LL | unsafe impl T for (i32) {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:399:13
+ --> $DIR/undocumented_unsafe_blocks.rs:403:13
|
LL | unsafe impl T for $t {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -208,7 +209,7 @@ LL | no_safety_comment!(u32);
= note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:413:5
+ --> $DIR/undocumented_unsafe_blocks.rs:417:5
|
LL | unsafe impl T for (bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -216,7 +217,7 @@ LL | unsafe impl T for (bool) {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:459:5
+ --> $DIR/undocumented_unsafe_blocks.rs:463:5
|
LL | unsafe impl NoComment for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -224,7 +225,7 @@ LL | unsafe impl NoComment for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:463:19
+ --> $DIR/undocumented_unsafe_blocks.rs:467:19
|
LL | /* SAFETY: */ unsafe impl InlineComment for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -232,7 +233,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:467:5
+ --> $DIR/undocumented_unsafe_blocks.rs:471:5
|
LL | unsafe impl TrailingComment for () {} // SAFETY:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -240,20 +241,21 @@ LL | unsafe impl TrailingComment for () {} // SAFETY:
= help: consider adding a safety comment on the preceding line
error: constant item has unnecessary safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:471:5
+ --> $DIR/undocumented_unsafe_blocks.rs:475:5
|
LL | const BIG_NUMBER: i32 = 1000000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:470:5
+ --> $DIR/undocumented_unsafe_blocks.rs:474:5
|
LL | // SAFETY:
| ^^^^^^^^^^
= note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:472:5
+ --> $DIR/undocumented_unsafe_blocks.rs:476:5
|
LL | unsafe impl Interference for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -261,7 +263,7 @@ LL | unsafe impl Interference for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:479:5
+ --> $DIR/undocumented_unsafe_blocks.rs:483:5
|
LL | unsafe impl ImplInFn for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -269,7 +271,7 @@ LL | unsafe impl ImplInFn for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe impl missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:488:1
+ --> $DIR/undocumented_unsafe_blocks.rs:492:1
|
LL | unsafe impl CrateRoot for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -277,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:498:9
+ --> $DIR/undocumented_unsafe_blocks.rs:502:9
|
LL | unsafe {};
| ^^^^^^^^^
@@ -285,7 +287,7 @@ LL | unsafe {};
= help: consider adding a safety comment on the preceding line
error: statement has unnecessary safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:501:5
+ --> $DIR/undocumented_unsafe_blocks.rs:505:5
|
LL | / let _ = {
LL | | if unsafe { true } {
@@ -297,13 +299,13 @@ LL | | };
| |______^
|
help: consider removing the safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:500:5
+ --> $DIR/undocumented_unsafe_blocks.rs:504:5
|
LL | // SAFETY: this is more than one level away, so it should warn
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:502:12
+ --> $DIR/undocumented_unsafe_blocks.rs:506:12
|
LL | if unsafe { true } {
| ^^^^^^^^^^^^^^^
@@ -311,7 +313,7 @@ LL | if unsafe { true } {
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:505:23
+ --> $DIR/undocumented_unsafe_blocks.rs:509:23
|
LL | let bar = unsafe {};
| ^^^^^^^^^
@@ -319,7 +321,7 @@ LL | let bar = unsafe {};
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:523:9
+ --> $DIR/undocumented_unsafe_blocks.rs:527:9
|
LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -327,7 +329,7 @@ LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() };
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:527:9
+ --> $DIR/undocumented_unsafe_blocks.rs:531:9
|
LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -335,12 +337,60 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line()
= help: consider adding a safety comment on the preceding line
error: unsafe block missing a safety comment
- --> $DIR/undocumented_unsafe_blocks.rs:531:9
+ --> $DIR/undocumented_unsafe_blocks.rs:535:9
+ |
+LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:541:5
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+ = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:545:5
+ |
+LL | unsafe {
+ | ^^^^^^^^
+ |
+ = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:552:9
+ |
+LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:557:9
+ |
+LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:563:9
|
LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line
-error: aborting due to 39 previous errors
+error: unsafe block missing a safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:568:5
+ |
+LL | unsafe {}
+ | ^^^^^^^^^
+ |
+ = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 45 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index 33d636709..a27813987 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -1,4 +1,7 @@
-//@aux-build:proc_macro_unsafe.rs:proc-macro
+//@aux-build:../../ui/auxiliary/proc_macro_unsafe.rs
+//@revisions: default disabled
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/default
+//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled
#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
#![allow(deref_nullptr, clippy::let_unit_value, clippy::missing_safety_doc)]
@@ -491,7 +494,7 @@ unsafe impl CrateRoot for () {}
// SAFETY: ok
unsafe impl CrateRoot for (i32) {}
-fn issue_9142() {
+fn nested_block_separation_issue_9142() {
// SAFETY: ok
let _ =
// we need this comment to avoid rustfmt putting
@@ -518,50 +521,65 @@ pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -
2
}
-fn issue_10832() {
- // Safety: A safety comment
+fn separate_line_from_let_issue_10832() {
+ // SAFETY: fail ONLY if `accept-comment-above-statement = false`
let _some_variable_with_a_very_long_name_to_break_the_line =
unsafe { a_function_with_a_very_long_name_to_break_the_line() };
- // Safety: Another safety comment
+ // SAFETY: fail ONLY if `accept-comment-above-statement = false`
const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
- // Safety: Yet another safety comment
+ // SAFETY: fail ONLY if `accept-comment-above-statement = false`
static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
}
-fn issue_8679<T: Copy>() {
- // SAFETY:
+fn above_expr_attribute_issue_8679<T: Copy>() {
+ // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
#[allow(unsafe_code)]
unsafe {}
- // SAFETY:
+ // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
#[expect(unsafe_code, reason = "totally safe")]
unsafe {
*std::ptr::null::<T>()
};
- // Safety: A safety comment
+ // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
#[allow(unsafe_code)]
let _some_variable_with_a_very_long_name_to_break_the_line =
unsafe { a_function_with_a_very_long_name_to_break_the_line() };
- // Safety: Another safety comment
+ // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
#[allow(unsafe_code)]
const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
- // Safety: Yet another safety comment
+ // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
#[allow(unsafe_code)]
- static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
+ #[allow(non_upper_case_globals)]
+ static _some_static_with_a_very_long_name_to_break_the_line: u32 =
unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
// SAFETY:
#[allow(unsafe_code)]
- // This also works I guess
+ // This shouldn't work either
unsafe {}
}
+mod issue_11246 {
+ // Safety: foo
+ const _: () = unsafe {};
+
+ // Safety: A safety comment
+ const FOO: () = unsafe {};
+
+ // Safety: bar
+ static BAR: u8 = unsafe { 0 };
+}
+
+// Safety: Another safety comment
+const FOO: () = unsafe {};
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml
new file mode 100644
index 000000000..7c3ffc290
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml
@@ -0,0 +1 @@
+unnecessary-box-size = 64
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed
new file mode 100644
index 000000000..413bc0bf1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed
@@ -0,0 +1,11 @@
+#![warn(clippy::unnecessary_box_returns)]
+
+fn f() -> [u8; 64] {
+ //~^ ERROR: boxed return of the sized type `[u8; 64]`
+ todo!()
+}
+fn f2() -> Box<[u8; 65]> {
+ todo!()
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs
new file mode 100644
index 000000000..b44fbb554
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::unnecessary_box_returns)]
+
+fn f() -> Box<[u8; 64]> {
+ //~^ ERROR: boxed return of the sized type `[u8; 64]`
+ todo!()
+}
+fn f2() -> Box<[u8; 65]> {
+ todo!()
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr
new file mode 100644
index 000000000..df9aa37ac
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr
@@ -0,0 +1,12 @@
+error: boxed return of the sized type `[u8; 64]`
+ --> $DIR/unnecessary_box_returns.rs:3:11
+ |
+LL | fn f() -> Box<[u8; 64]> {
+ | ^^^^^^^^^^^^^ help: try: `[u8; 64]`
+ |
+ = help: changing this also requires a change to the return expressions in this function
+ = note: `-D clippy::unnecessary-box-returns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
new file mode 100644
index 000000000..baf939af2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
@@ -0,0 +1,95 @@
+//@compile-flags: --test
+
+#![allow(
+ unused_mut,
+ clippy::get_first,
+ clippy::from_iter_instead_of_collect,
+ clippy::useless_vec
+)]
+#![warn(clippy::unwrap_used)]
+#![warn(clippy::get_unwrap)]
+
+use std::collections::{BTreeMap, HashMap, VecDeque};
+
+struct GetFalsePositive {
+ arr: [u32; 3],
+}
+
+impl GetFalsePositive {
+ fn get(&self, pos: usize) -> Option<&u32> {
+ self.arr.get(pos)
+ }
+ fn get_mut(&mut self, pos: usize) -> Option<&mut u32> {
+ self.arr.get_mut(pos)
+ }
+}
+
+fn main() {
+ let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
+ let mut some_slice = &mut [0, 1, 2, 3];
+ let mut some_vec = vec![0, 1, 2, 3];
+ let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect();
+ let mut some_hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]);
+ let mut some_btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]);
+ let mut false_positive = GetFalsePositive { arr: [0, 1, 2] };
+
+ {
+ // Test `get().unwrap()`
+ let _ = &boxed_slice[1];
+ let _ = &some_slice[0];
+ let _ = &some_vec[0];
+ let _ = &some_vecdeque[0];
+ let _ = &some_hashmap[&1];
+ let _ = &some_btreemap[&1];
+ #[allow(clippy::unwrap_used)]
+ let _ = false_positive.get(0).unwrap();
+ // Test with deref
+ let _: u8 = boxed_slice[1];
+ }
+
+ {
+ // Test `get_mut().unwrap()`
+ boxed_slice[0] = 1;
+ some_slice[0] = 1;
+ some_vec[0] = 1;
+ some_vecdeque[0] = 1;
+ // Check false positives
+ #[allow(clippy::unwrap_used)]
+ {
+ *some_hashmap.get_mut(&1).unwrap() = 'b';
+ *some_btreemap.get_mut(&1).unwrap() = 'b';
+ *false_positive.get_mut(0).unwrap() = 1;
+ }
+ }
+
+ {
+ // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()`
+ let _ = some_vec[0..1].to_vec();
+ let _ = some_vec[0..1].to_vec();
+ }
+}
+
+#[test]
+fn test() {
+ let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
+ let _ = &boxed_slice[1];
+}
+
+#[cfg(test)]
+mod issue9612 {
+ // should not lint in `#[cfg(test)]` modules
+ #[test]
+ fn test_fn() {
+ let _a: u8 = 2.try_into().unwrap();
+ let _a: u8 = 3.try_into().expect("");
+
+ util();
+ }
+
+ fn util() {
+ let _a: u8 = 4.try_into().unwrap();
+ let _a: u8 = 5.try_into().expect("");
+ // should still warn
+ let _ = &Box::new([0])[1];
+ }
+}
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
index 10219beaf..cc22ea273 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
@@ -5,6 +5,7 @@ LL | let _ = boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]`
|
= note: `-D clippy::get-unwrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::get_unwrap)]`
error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:38:17
@@ -15,6 +16,7 @@ LL | let _ = boxed_slice.get(1).unwrap();
= note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
= note: `-D clippy::unwrap-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:39:17
diff --git a/src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed b/src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed
new file mode 100644
index 000000000..afb889f15
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed
@@ -0,0 +1,44 @@
+#![warn(clippy::upper_case_acronyms)]
+
+struct HttpResponse; // not linted by default, but with cfg option
+
+struct CString; // not linted
+
+enum Flags {
+ Ns, // not linted
+ Cwr,
+ Ece,
+ Urg,
+ Ack,
+ Psh,
+ Rst,
+ Syn,
+ Fin,
+}
+
+// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of
+// `GccLlvmSomething`
+struct GccllvmSomething;
+
+// don't warn on public items
+pub struct MIXEDCapital;
+
+pub struct FULLCAPITAL;
+
+// enum variants should not be linted if the num is pub
+pub enum ParseError<T> {
+ FULLCAPITAL(u8),
+ MIXEDCapital(String),
+ Utf8(std::string::FromUtf8Error),
+ Parse(T, String),
+}
+
+// private, do lint here
+enum ParseErrorPrivate<T> {
+ Wasd(u8),
+ WasdMixed(String),
+ Utf8(std::string::FromUtf8Error),
+ Parse(T, String),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr b/src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr
index 02f29bbef..3fad561b1 100644
--- a/src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr
+++ b/src/tools/clippy/tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr
@@ -5,6 +5,7 @@ LL | struct HTTPResponse; // not linted by default, but with cfg option
| ^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `HttpResponse`
|
= note: `-D clippy::upper-case-acronyms` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::upper_case_acronyms)]`
error: name `NS` contains a capitalized acronym
--> $DIR/upper_case_acronyms.rs:8:5
diff --git a/src/tools/clippy/tests/ui-toml/vec_box_sized/test.fixed b/src/tools/clippy/tests/ui-toml/vec_box_sized/test.fixed
new file mode 100644
index 000000000..bb4936401
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/vec_box_sized/test.fixed
@@ -0,0 +1,16 @@
+struct S {
+ x: u64,
+}
+
+struct C {
+ y: u16,
+}
+
+struct Foo(Vec<u8>);
+struct Bar(Vec<u16>);
+struct Quux(Vec<Box<u32>>);
+struct Baz(Vec<Box<(u16, u16)>>);
+struct BarBaz(Vec<Box<S>>);
+struct FooBarBaz(Vec<C>);
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/vec_box_sized/test.stderr b/src/tools/clippy/tests/ui-toml/vec_box_sized/test.stderr
index 55de68f8e..c88860ea8 100644
--- a/src/tools/clippy/tests/ui-toml/vec_box_sized/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/vec_box_sized/test.stderr
@@ -5,6 +5,7 @@ LL | struct Foo(Vec<Box<u8>>);
| ^^^^^^^^^^^^ help: try: `Vec<u8>`
|
= note: `-D clippy::vec-box` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::vec_box)]`
error: `Vec<T>` is already on the heap, the boxing is unnecessary
--> $DIR/test.rs:10:12
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml
new file mode 100644
index 000000000..55a202eef
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml
@@ -0,0 +1 @@
+verbose-bit-mask-threshold = 31
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed
new file mode 100644
index 000000000..437692a4d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::verbose_bit_mask)]
+fn main() {
+ let v: i32 = 0;
+ let _ = v & 0b11111 == 0;
+ let _ = v.trailing_zeros() >= 6;
+ //~^ ERROR: bit mask could be simplified
+}
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs
new file mode 100644
index 000000000..ce1027080
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::verbose_bit_mask)]
+fn main() {
+ let v: i32 = 0;
+ let _ = v & 0b11111 == 0;
+ let _ = v & 0b111111 == 0;
+ //~^ ERROR: bit mask could be simplified
+}
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr
new file mode 100644
index 000000000..7377921b4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr
@@ -0,0 +1,11 @@
+error: bit mask could be simplified with a call to `trailing_zeros`
+ --> $DIR/verbose_bit_mask.rs:5:13
+ |
+LL | let _ = v & 0b111111 == 0;
+ | ^^^^^^^^^^^^^^^^^ help: try: `v.trailing_zeros() >= 6`
+ |
+ = note: `-D clippy::verbose-bit-mask` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
new file mode 100644
index 000000000..875aaeef6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
@@ -0,0 +1 @@
+warn-on-all-wildcard-imports = true
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
new file mode 100644
index 000000000..1752f4885
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
@@ -0,0 +1,11 @@
+#![warn(clippy::wildcard_imports)]
+
+mod prelude {
+ pub const FOO: u8 = 1;
+}
+use prelude::FOO;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+ let _ = FOO;
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
new file mode 100644
index 000000000..331c2c59c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::wildcard_imports)]
+
+mod prelude {
+ pub const FOO: u8 = 1;
+}
+use prelude::*;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+ let _ = FOO;
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
new file mode 100644
index 000000000..13ec3a229
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
@@ -0,0 +1,11 @@
+error: usage of wildcard import
+ --> $DIR/wildcard_imports.rs:6:5
+ |
+LL | use prelude::*;
+ | ^^^^^^^^^^ help: try: `prelude::FOO`
+ |
+ = note: `-D clippy::wildcard-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.rs b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.rs
index f682b280c..60f2ba4ab 100644
--- a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.rs
+++ b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.rs
@@ -12,27 +12,46 @@ fn main() {
const Z: u32 = 0;
let u: u32 = 42;
u <= 0;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u <= Z;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u < Z;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
Z >= u;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
Z > u;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u > u32::MAX;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u >= u32::MAX;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u32::MAX < u;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u32::MAX <= u;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
1-1 > u;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u >= !0;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u <= 12 - 2*6;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
let i: i8 = 0;
i < -127 - 1;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
i8::MAX >= i;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
3-7 < i32::MIN;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
let b = false;
b >= true;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
false > b;
+ //~^ ERROR: this comparison involving the minimum or maximum element for this type con
u > 0; // ok
// this is handled by clippy::unit_cmp
() < {};
+ //~^ ERROR: <-comparison of unit values detected. This will always be false
+ //~| NOTE: `#[deny(clippy::unit_cmp)]` on by default
}
use std::cmp::{Ordering, PartialEq, PartialOrd};
diff --git a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr
index 21cb11fa1..64d38e60d 100644
--- a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr
+++ b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr
@@ -6,9 +6,10 @@ LL | u <= 0;
|
= 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
= note: `-D clippy::absurd-extreme-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::absurd_extreme_comparisons)]`
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:15:5
+ --> $DIR/absurd-extreme-comparisons.rs:16:5
|
LL | u <= Z;
| ^^^^^^
@@ -16,7 +17,7 @@ LL | u <= Z;
= 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
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:16:5
+ --> $DIR/absurd-extreme-comparisons.rs:18:5
|
LL | u < Z;
| ^^^^^
@@ -24,7 +25,7 @@ LL | u < Z;
= help: because `Z` is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:17:5
+ --> $DIR/absurd-extreme-comparisons.rs:20:5
|
LL | Z >= u;
| ^^^^^^
@@ -32,7 +33,7 @@ LL | Z >= u;
= 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
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:18:5
+ --> $DIR/absurd-extreme-comparisons.rs:22:5
|
LL | Z > u;
| ^^^^^
@@ -40,7 +41,7 @@ LL | Z > u;
= help: because `Z` is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:19:5
+ --> $DIR/absurd-extreme-comparisons.rs:24:5
|
LL | u > u32::MAX;
| ^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | u > u32::MAX;
= help: because `u32::MAX` is the maximum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:20:5
+ --> $DIR/absurd-extreme-comparisons.rs:26:5
|
LL | u >= u32::MAX;
| ^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | u >= u32::MAX;
= 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
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:21:5
+ --> $DIR/absurd-extreme-comparisons.rs:28:5
|
LL | u32::MAX < u;
| ^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | u32::MAX < u;
= help: because `u32::MAX` is the maximum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:22:5
+ --> $DIR/absurd-extreme-comparisons.rs:30:5
|
LL | u32::MAX <= u;
| ^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | u32::MAX <= u;
= 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
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:23:5
+ --> $DIR/absurd-extreme-comparisons.rs:32:5
|
LL | 1-1 > u;
| ^^^^^^^
@@ -80,7 +81,7 @@ LL | 1-1 > u;
= help: because `1-1` is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:24:5
+ --> $DIR/absurd-extreme-comparisons.rs:34:5
|
LL | u >= !0;
| ^^^^^^^
@@ -88,7 +89,7 @@ LL | u >= !0;
= 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
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:25:5
+ --> $DIR/absurd-extreme-comparisons.rs:36:5
|
LL | u <= 12 - 2*6;
| ^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL | u <= 12 - 2*6;
= 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
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:27:5
+ --> $DIR/absurd-extreme-comparisons.rs:39:5
|
LL | i < -127 - 1;
| ^^^^^^^^^^^^
@@ -104,7 +105,7 @@ LL | i < -127 - 1;
= help: because `-127 - 1` is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:28:5
+ --> $DIR/absurd-extreme-comparisons.rs:41:5
|
LL | i8::MAX >= i;
| ^^^^^^^^^^^^
@@ -112,7 +113,7 @@ LL | i8::MAX >= i;
= help: because `i8::MAX` is the maximum value for this type, this comparison is always true
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:29:5
+ --> $DIR/absurd-extreme-comparisons.rs:43:5
|
LL | 3-7 < i32::MIN;
| ^^^^^^^^^^^^^^
@@ -120,7 +121,7 @@ LL | 3-7 < i32::MIN;
= help: because `i32::MIN` is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:31:5
+ --> $DIR/absurd-extreme-comparisons.rs:46:5
|
LL | b >= true;
| ^^^^^^^^^
@@ -128,7 +129,7 @@ LL | b >= true;
= 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
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
- --> $DIR/absurd-extreme-comparisons.rs:32:5
+ --> $DIR/absurd-extreme-comparisons.rs:48:5
|
LL | false > b;
| ^^^^^^^^^
@@ -136,7 +137,7 @@ LL | false > b;
= help: because `false` is the minimum value for this type, this comparison is always false
error: <-comparison of unit values detected. This will always be false
- --> $DIR/absurd-extreme-comparisons.rs:35:5
+ --> $DIR/absurd-extreme-comparisons.rs:52:5
|
LL | () < {};
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/allow_attributes.fixed b/src/tools/clippy/tests/ui/allow_attributes.fixed
index cc95a0681..b506a9890 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.fixed
+++ b/src/tools/clippy/tests/ui/allow_attributes.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused)]
#![warn(clippy::allow_attributes)]
#![feature(lint_reasons)]
@@ -23,6 +22,13 @@ struct T4;
#[cfg_attr(panic = "unwind", expect(dead_code))]
struct CfgT;
+#[allow(clippy::allow_attributes, unused)]
+struct Allowed;
+
+#[expect(clippy::allow_attributes)]
+#[allow(unused)]
+struct Expected;
+
fn ignore_external() {
external! {
#[allow(clippy::needless_borrow)] // Should not lint
diff --git a/src/tools/clippy/tests/ui/allow_attributes.rs b/src/tools/clippy/tests/ui/allow_attributes.rs
index 2eb6ad304..c7daa7abd 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.rs
+++ b/src/tools/clippy/tests/ui/allow_attributes.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused)]
#![warn(clippy::allow_attributes)]
#![feature(lint_reasons)]
@@ -23,6 +22,13 @@ struct T4;
#[cfg_attr(panic = "unwind", allow(dead_code))]
struct CfgT;
+#[allow(clippy::allow_attributes, unused)]
+struct Allowed;
+
+#[expect(clippy::allow_attributes)]
+#[allow(unused)]
+struct Expected;
+
fn ignore_external() {
external! {
#[allow(clippy::needless_borrow)] // Should not lint
diff --git a/src/tools/clippy/tests/ui/allow_attributes.stderr b/src/tools/clippy/tests/ui/allow_attributes.stderr
index d17fd86cb..7ac0bd456 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.stderr
+++ b/src/tools/clippy/tests/ui/allow_attributes.stderr
@@ -1,13 +1,14 @@
error: #[allow] attribute found
- --> $DIR/allow_attributes.rs:14:3
+ --> $DIR/allow_attributes.rs:13:3
|
LL | #[allow(dead_code)]
| ^^^^^ help: replace it with: `expect`
|
= note: `-D clippy::allow-attributes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::allow_attributes)]`
error: #[allow] attribute found
- --> $DIR/allow_attributes.rs:23:30
+ --> $DIR/allow_attributes.rs:22:30
|
LL | #[cfg_attr(panic = "unwind", allow(dead_code))]
| ^^^^^ help: replace it with: `expect`
diff --git a/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs b/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs
index d223d5642..663c2eb2c 100644
--- a/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs
+++ b/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(lint_reasons)]
#![deny(clippy::allow_attributes_without_reason)]
#![allow(unfulfilled_lint_expectations)]
diff --git a/src/tools/clippy/tests/ui/almost_complete_range.fixed b/src/tools/clippy/tests/ui/almost_complete_range.fixed
index 50a13f16b..21caeb153 100644
--- a/src/tools/clippy/tests/ui/almost_complete_range.fixed
+++ b/src/tools/clippy/tests/ui/almost_complete_range.fixed
@@ -1,6 +1,5 @@
-//@run-rustfix
//@edition:2018
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(exclusive_range_pattern)]
#![feature(stmt_expr_attributes)]
diff --git a/src/tools/clippy/tests/ui/almost_complete_range.rs b/src/tools/clippy/tests/ui/almost_complete_range.rs
index fd8223a23..556110a5c 100644
--- a/src/tools/clippy/tests/ui/almost_complete_range.rs
+++ b/src/tools/clippy/tests/ui/almost_complete_range.rs
@@ -1,6 +1,5 @@
-//@run-rustfix
//@edition:2018
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(exclusive_range_pattern)]
#![feature(stmt_expr_attributes)]
diff --git a/src/tools/clippy/tests/ui/almost_complete_range.stderr b/src/tools/clippy/tests/ui/almost_complete_range.stderr
index 34521c13a..054a02c9c 100644
--- a/src/tools/clippy/tests/ui/almost_complete_range.stderr
+++ b/src/tools/clippy/tests/ui/almost_complete_range.stderr
@@ -1,5 +1,5 @@
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:19:17
+ --> $DIR/almost_complete_range.rs:18:17
|
LL | let _ = ('a') ..'z';
| ^^^^^^--^^^
@@ -7,9 +7,10 @@ LL | let _ = ('a') ..'z';
| help: use an inclusive range: `..=`
|
= note: `-D clippy::almost-complete-range` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::almost_complete_range)]`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:20:17
+ --> $DIR/almost_complete_range.rs:19:17
|
LL | let _ = 'A' .. ('Z');
| ^^^^--^^^^^^
@@ -17,7 +18,7 @@ LL | let _ = 'A' .. ('Z');
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:21:17
+ --> $DIR/almost_complete_range.rs:20:17
|
LL | let _ = ((('0'))) .. ('9');
| ^^^^^^^^^^--^^^^^^
@@ -25,7 +26,7 @@ LL | let _ = ((('0'))) .. ('9');
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:28:13
+ --> $DIR/almost_complete_range.rs:27:13
|
LL | let _ = (b'a')..(b'z');
| ^^^^^^--^^^^^^
@@ -33,7 +34,7 @@ LL | let _ = (b'a')..(b'z');
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:29:13
+ --> $DIR/almost_complete_range.rs:28:13
|
LL | let _ = b'A'..b'Z';
| ^^^^--^^^^
@@ -41,7 +42,7 @@ LL | let _ = b'A'..b'Z';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:30:13
+ --> $DIR/almost_complete_range.rs:29:13
|
LL | let _ = b'0'..b'9';
| ^^^^--^^^^
@@ -49,7 +50,7 @@ LL | let _ = b'0'..b'9';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:36:13
+ --> $DIR/almost_complete_range.rs:35:13
|
LL | let _ = inline!('a')..'z';
| ^^^^^^^^^^^^--^^^
@@ -57,7 +58,7 @@ LL | let _ = inline!('a')..'z';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:37:13
+ --> $DIR/almost_complete_range.rs:36:13
|
LL | let _ = inline!('A')..'Z';
| ^^^^^^^^^^^^--^^^
@@ -65,7 +66,7 @@ LL | let _ = inline!('A')..'Z';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:38:13
+ --> $DIR/almost_complete_range.rs:37:13
|
LL | let _ = inline!('0')..'9';
| ^^^^^^^^^^^^--^^^
@@ -73,7 +74,7 @@ LL | let _ = inline!('0')..'9';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:41:9
+ --> $DIR/almost_complete_range.rs:40:9
|
LL | b'a'..b'z' if true => 1,
| ^^^^--^^^^
@@ -81,7 +82,7 @@ LL | b'a'..b'z' if true => 1,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:42:9
+ --> $DIR/almost_complete_range.rs:41:9
|
LL | b'A'..b'Z' if true => 2,
| ^^^^--^^^^
@@ -89,7 +90,7 @@ LL | b'A'..b'Z' if true => 2,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:43:9
+ --> $DIR/almost_complete_range.rs:42:9
|
LL | b'0'..b'9' if true => 3,
| ^^^^--^^^^
@@ -97,7 +98,7 @@ LL | b'0'..b'9' if true => 3,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:51:9
+ --> $DIR/almost_complete_range.rs:50:9
|
LL | 'a'..'z' if true => 1,
| ^^^--^^^
@@ -105,7 +106,7 @@ LL | 'a'..'z' if true => 1,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:52:9
+ --> $DIR/almost_complete_range.rs:51:9
|
LL | 'A'..'Z' if true => 2,
| ^^^--^^^
@@ -113,7 +114,7 @@ LL | 'A'..'Z' if true => 2,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:53:9
+ --> $DIR/almost_complete_range.rs:52:9
|
LL | '0'..'9' if true => 3,
| ^^^--^^^
@@ -121,7 +122,7 @@ LL | '0'..'9' if true => 3,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:66:17
+ --> $DIR/almost_complete_range.rs:65:17
|
LL | let _ = 'a'..'z';
| ^^^--^^^
@@ -131,7 +132,7 @@ LL | let _ = 'a'..'z';
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:67:17
+ --> $DIR/almost_complete_range.rs:66:17
|
LL | let _ = 'A'..'Z';
| ^^^--^^^
@@ -141,7 +142,7 @@ LL | let _ = 'A'..'Z';
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:68:17
+ --> $DIR/almost_complete_range.rs:67:17
|
LL | let _ = '0'..'9';
| ^^^--^^^
@@ -151,7 +152,7 @@ LL | let _ = '0'..'9';
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:75:9
+ --> $DIR/almost_complete_range.rs:74:9
|
LL | 'a'..'z' => 1,
| ^^^--^^^
@@ -159,7 +160,7 @@ LL | 'a'..'z' => 1,
| help: use an inclusive range: `...`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:76:9
+ --> $DIR/almost_complete_range.rs:75:9
|
LL | 'A'..'Z' => 2,
| ^^^--^^^
@@ -167,7 +168,7 @@ LL | 'A'..'Z' => 2,
| help: use an inclusive range: `...`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:77:9
+ --> $DIR/almost_complete_range.rs:76:9
|
LL | '0'..'9' => 3,
| ^^^--^^^
@@ -175,7 +176,7 @@ LL | '0'..'9' => 3,
| help: use an inclusive range: `...`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:84:13
+ --> $DIR/almost_complete_range.rs:83:13
|
LL | let _ = 'a'..'z';
| ^^^--^^^
@@ -183,7 +184,7 @@ LL | let _ = 'a'..'z';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:85:13
+ --> $DIR/almost_complete_range.rs:84:13
|
LL | let _ = 'A'..'Z';
| ^^^--^^^
@@ -191,7 +192,7 @@ LL | let _ = 'A'..'Z';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:86:13
+ --> $DIR/almost_complete_range.rs:85:13
|
LL | let _ = '0'..'9';
| ^^^--^^^
@@ -199,7 +200,7 @@ LL | let _ = '0'..'9';
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:88:9
+ --> $DIR/almost_complete_range.rs:87:9
|
LL | 'a'..'z' => 1,
| ^^^--^^^
@@ -207,7 +208,7 @@ LL | 'a'..'z' => 1,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:89:9
+ --> $DIR/almost_complete_range.rs:88:9
|
LL | 'A'..'Z' => 1,
| ^^^--^^^
@@ -215,7 +216,7 @@ LL | 'A'..'Z' => 1,
| help: use an inclusive range: `..=`
error: almost complete ascii range
- --> $DIR/almost_complete_range.rs:90:9
+ --> $DIR/almost_complete_range.rs:89:9
|
LL | '0'..'9' => 3,
| ^^^--^^^
diff --git a/src/tools/clippy/tests/ui/approx_const.rs b/src/tools/clippy/tests/ui/approx_const.rs
index ccdbd34f7..2c3e0978c 100644
--- a/src/tools/clippy/tests/ui/approx_const.rs
+++ b/src/tools/clippy/tests/ui/approx_const.rs
@@ -2,63 +2,86 @@
#[allow(clippy::similar_names)]
fn main() {
let my_e = 2.7182;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::E` found
let almost_e = 2.718;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::E` found
let no_e = 2.71;
let my_1_frac_pi = 0.3183;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_1_PI` found
let no_1_frac_pi = 0.31;
let my_frac_1_sqrt_2 = 0.70710678;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found
let almost_frac_1_sqrt_2 = 0.70711;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found
let my_frac_1_sqrt_2 = 0.707;
let my_frac_2_pi = 0.63661977;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_2_PI` found
let no_frac_2_pi = 0.636;
let my_frac_2_sq_pi = 1.128379;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_2_SQRT_PI` found
let no_frac_2_sq_pi = 1.128;
let my_frac_pi_2 = 1.57079632679;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_2` found
let no_frac_pi_2 = 1.5705;
let my_frac_pi_3 = 1.04719755119;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_3` found
let no_frac_pi_3 = 1.047;
let my_frac_pi_4 = 0.785398163397;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_4` found
let no_frac_pi_4 = 0.785;
let my_frac_pi_6 = 0.523598775598;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_6` found
let no_frac_pi_6 = 0.523;
let my_frac_pi_8 = 0.3926990816987;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::FRAC_PI_8` found
let no_frac_pi_8 = 0.392;
let my_ln_10 = 2.302585092994046;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LN_10` found
let no_ln_10 = 2.303;
let my_ln_2 = 0.6931471805599453;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LN_2` found
let no_ln_2 = 0.693;
let my_log10_e = 0.4342944819032518;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG10_E` found
let no_log10_e = 0.434;
let my_log2_e = 1.4426950408889634;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_E` found
let no_log2_e = 1.442;
let log2_10 = 3.321928094887362;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found
let no_log2_10 = 3.321;
let log10_2 = 0.301029995663981;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG10_2` found
let no_log10_2 = 0.301;
let my_pi = 3.1415;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::PI` found
let almost_pi = 3.14;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::PI` found
let no_pi = 3.15;
let my_sq2 = 1.4142;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::SQRT_2` found
let no_sq2 = 1.414;
let my_tau = 6.2832;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::TAU` found
let almost_tau = 6.28;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::TAU` found
let no_tau = 6.3;
}
diff --git a/src/tools/clippy/tests/ui/approx_const.stderr b/src/tools/clippy/tests/ui/approx_const.stderr
index 0932a2eec..4b5cd2a7a 100644
--- a/src/tools/clippy/tests/ui/approx_const.stderr
+++ b/src/tools/clippy/tests/ui/approx_const.stderr
@@ -6,9 +6,10 @@ LL | let my_e = 2.7182;
|
= help: consider using the constant directly
= note: `-D clippy::approx-constant` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::approx_constant)]`
error: approximate value of `f{32, 64}::consts::E` found
- --> $DIR/approx_const.rs:5:20
+ --> $DIR/approx_const.rs:6:20
|
LL | let almost_e = 2.718;
| ^^^^^
@@ -16,7 +17,7 @@ LL | let almost_e = 2.718;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_1_PI` found
- --> $DIR/approx_const.rs:8:24
+ --> $DIR/approx_const.rs:10:24
|
LL | let my_1_frac_pi = 0.3183;
| ^^^^^^
@@ -24,7 +25,7 @@ LL | let my_1_frac_pi = 0.3183;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found
- --> $DIR/approx_const.rs:11:28
+ --> $DIR/approx_const.rs:14:28
|
LL | let my_frac_1_sqrt_2 = 0.70710678;
| ^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | let my_frac_1_sqrt_2 = 0.70710678;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found
- --> $DIR/approx_const.rs:12:32
+ --> $DIR/approx_const.rs:16:32
|
LL | let almost_frac_1_sqrt_2 = 0.70711;
| ^^^^^^^
@@ -40,7 +41,7 @@ LL | let almost_frac_1_sqrt_2 = 0.70711;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_2_PI` found
- --> $DIR/approx_const.rs:15:24
+ --> $DIR/approx_const.rs:20:24
|
LL | let my_frac_2_pi = 0.63661977;
| ^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | let my_frac_2_pi = 0.63661977;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_2_SQRT_PI` found
- --> $DIR/approx_const.rs:18:27
+ --> $DIR/approx_const.rs:24:27
|
LL | let my_frac_2_sq_pi = 1.128379;
| ^^^^^^^^
@@ -56,7 +57,7 @@ LL | let my_frac_2_sq_pi = 1.128379;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_PI_2` found
- --> $DIR/approx_const.rs:21:24
+ --> $DIR/approx_const.rs:28:24
|
LL | let my_frac_pi_2 = 1.57079632679;
| ^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | let my_frac_pi_2 = 1.57079632679;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_PI_3` found
- --> $DIR/approx_const.rs:24:24
+ --> $DIR/approx_const.rs:32:24
|
LL | let my_frac_pi_3 = 1.04719755119;
| ^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | let my_frac_pi_3 = 1.04719755119;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_PI_4` found
- --> $DIR/approx_const.rs:27:24
+ --> $DIR/approx_const.rs:36:24
|
LL | let my_frac_pi_4 = 0.785398163397;
| ^^^^^^^^^^^^^^
@@ -80,7 +81,7 @@ LL | let my_frac_pi_4 = 0.785398163397;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_PI_6` found
- --> $DIR/approx_const.rs:30:24
+ --> $DIR/approx_const.rs:40:24
|
LL | let my_frac_pi_6 = 0.523598775598;
| ^^^^^^^^^^^^^^
@@ -88,7 +89,7 @@ LL | let my_frac_pi_6 = 0.523598775598;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::FRAC_PI_8` found
- --> $DIR/approx_const.rs:33:24
+ --> $DIR/approx_const.rs:44:24
|
LL | let my_frac_pi_8 = 0.3926990816987;
| ^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL | let my_frac_pi_8 = 0.3926990816987;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LN_10` found
- --> $DIR/approx_const.rs:36:20
+ --> $DIR/approx_const.rs:48:20
|
LL | let my_ln_10 = 2.302585092994046;
| ^^^^^^^^^^^^^^^^^
@@ -104,7 +105,7 @@ LL | let my_ln_10 = 2.302585092994046;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LN_2` found
- --> $DIR/approx_const.rs:39:19
+ --> $DIR/approx_const.rs:52:19
|
LL | let my_ln_2 = 0.6931471805599453;
| ^^^^^^^^^^^^^^^^^^
@@ -112,7 +113,7 @@ LL | let my_ln_2 = 0.6931471805599453;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG10_E` found
- --> $DIR/approx_const.rs:42:22
+ --> $DIR/approx_const.rs:56:22
|
LL | let my_log10_e = 0.4342944819032518;
| ^^^^^^^^^^^^^^^^^^
@@ -120,7 +121,7 @@ LL | let my_log10_e = 0.4342944819032518;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG2_E` found
- --> $DIR/approx_const.rs:45:21
+ --> $DIR/approx_const.rs:60:21
|
LL | let my_log2_e = 1.4426950408889634;
| ^^^^^^^^^^^^^^^^^^
@@ -128,7 +129,7 @@ LL | let my_log2_e = 1.4426950408889634;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG2_10` found
- --> $DIR/approx_const.rs:48:19
+ --> $DIR/approx_const.rs:64:19
|
LL | let log2_10 = 3.321928094887362;
| ^^^^^^^^^^^^^^^^^
@@ -136,7 +137,7 @@ LL | let log2_10 = 3.321928094887362;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG10_2` found
- --> $DIR/approx_const.rs:51:19
+ --> $DIR/approx_const.rs:68:19
|
LL | let log10_2 = 0.301029995663981;
| ^^^^^^^^^^^^^^^^^
@@ -144,7 +145,7 @@ LL | let log10_2 = 0.301029995663981;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::PI` found
- --> $DIR/approx_const.rs:54:17
+ --> $DIR/approx_const.rs:72:17
|
LL | let my_pi = 3.1415;
| ^^^^^^
@@ -152,7 +153,7 @@ LL | let my_pi = 3.1415;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::PI` found
- --> $DIR/approx_const.rs:55:21
+ --> $DIR/approx_const.rs:74:21
|
LL | let almost_pi = 3.14;
| ^^^^
@@ -160,7 +161,7 @@ LL | let almost_pi = 3.14;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::SQRT_2` found
- --> $DIR/approx_const.rs:58:18
+ --> $DIR/approx_const.rs:78:18
|
LL | let my_sq2 = 1.4142;
| ^^^^^^
@@ -168,7 +169,7 @@ LL | let my_sq2 = 1.4142;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::TAU` found
- --> $DIR/approx_const.rs:61:18
+ --> $DIR/approx_const.rs:82:18
|
LL | let my_tau = 6.2832;
| ^^^^^^
@@ -176,7 +177,7 @@ LL | let my_tau = 6.2832;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::TAU` found
- --> $DIR/approx_const.rs:62:22
+ --> $DIR/approx_const.rs:84:22
|
LL | let almost_tau = 6.28;
| ^^^^
diff --git a/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs b/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs
index 2940c2732..d03a577c4 100644
--- a/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs
+++ b/src/tools/clippy/tests/ui/arc_with_non_send_sync.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::arc_with_non_send_sync)]
#![allow(unused_variables)]
diff --git a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr
index de3f2fb9e..fd239580d 100644
--- a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr
+++ b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr
@@ -8,6 +8,7 @@ LL | let _ = Arc::new(RefCell::new(42));
= note: required for `Arc<RefCell<i32>>` to implement `Send` and `Sync`
= help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
= note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]`
error: usage of an `Arc` that is not `Send` or `Sync`
--> $DIR/arc_with_non_send_sync.rs:40:13
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
index 2ac2fa220..b454c29ae 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![allow(
clippy::assign_op_pattern,
@@ -10,12 +10,12 @@
arithmetic_overflow,
unconditional_panic
)]
-#![feature(const_mut_refs, inline_const, saturating_int_impl)]
+#![feature(const_mut_refs, inline_const)]
#![warn(clippy::arithmetic_side_effects)]
extern crate proc_macro_derive;
-use core::num::{Saturating, Wrapping};
+use core::num::{NonZeroUsize, Saturating, Wrapping};
const ONE: i32 = 1;
const ZERO: i32 = 0;
@@ -493,4 +493,32 @@ pub fn issue_11262() {
let _ = 2 / zero;
}
+pub fn issue_11392() {
+ fn example_div(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize {
+ unsigned / nonzero_unsigned
+ }
+
+ fn example_rem(unsigned: usize, nonzero_unsigned: NonZeroUsize) -> usize {
+ unsigned % nonzero_unsigned
+ }
+
+ let (unsigned, nonzero_unsigned) = (0, NonZeroUsize::new(1).unwrap());
+ example_div(unsigned, nonzero_unsigned);
+ example_rem(unsigned, nonzero_unsigned);
+}
+
+pub fn issue_11393() {
+ fn example_div(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> {
+ x / maybe_zero
+ }
+
+ fn example_rem(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> {
+ x % maybe_zero
+ }
+
+ let [x, maybe_zero] = [1, 0].map(Wrapping);
+ example_div(x, maybe_zero);
+ example_rem(x, maybe_zero);
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index e9a626643..13729a6c5 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -5,6 +5,7 @@ LL | _n += 1;
| ^^^^^^^
|
= note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`
error: arithmetic operation that can potentially result in unexpected side-effects
--> $DIR/arithmetic_side_effects.rs:305:5
@@ -702,5 +703,17 @@ error: arithmetic operation that can potentially result in unexpected side-effec
LL | 10 / a
| ^^^^^^
-error: aborting due to 117 previous errors
+error: arithmetic operation that can potentially result in unexpected side-effects
+ --> $DIR/arithmetic_side_effects.rs:512:9
+ |
+LL | x / maybe_zero
+ | ^^^^^^^^^^^^^^
+
+error: arithmetic operation that can potentially result in unexpected side-effects
+ --> $DIR/arithmetic_side_effects.rs:516:9
+ |
+LL | x % maybe_zero
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 119 previous errors
diff --git a/src/tools/clippy/tests/ui/as_conversions.rs b/src/tools/clippy/tests/ui/as_conversions.rs
index 69f1c541c..192eb51ea 100644
--- a/src/tools/clippy/tests/ui/as_conversions.rs
+++ b/src/tools/clippy/tests/ui/as_conversions.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::as_conversions)]
#![allow(clippy::borrow_as_ptr, unused)]
diff --git a/src/tools/clippy/tests/ui/as_conversions.stderr b/src/tools/clippy/tests/ui/as_conversions.stderr
index 54037a649..4bb964399 100644
--- a/src/tools/clippy/tests/ui/as_conversions.stderr
+++ b/src/tools/clippy/tests/ui/as_conversions.stderr
@@ -6,6 +6,7 @@ LL | let i = 0u32 as u64;
|
= help: consider using a safe wrapper for this conversion
= note: `-D clippy::as-conversions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::as_conversions)]`
error: using a potentially dangerous silent `as` conversion
--> $DIR/as_conversions.rs:12:13
diff --git a/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs b/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
index 7d71947e4..297a53b1b 100644
--- a/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
+++ b/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
@@ -1,6 +1,7 @@
#![allow(unused)]
#![warn(clippy::as_ptr_cast_mut)]
#![allow(clippy::wrong_self_convention, clippy::unnecessary_cast)]
+//@no-rustfix
struct MutPtrWrapper(Vec<u8>);
impl MutPtrWrapper {
@@ -19,7 +20,10 @@ impl<T> Covariant<T> {
fn main() {
let mut string = String::new();
let _ = string.as_ptr() as *mut u8;
+ //~^ ERROR: casting the result of `as_ptr` to *mut u8
+ //~| NOTE: `-D clippy::as-ptr-cast-mut` implied by `-D warnings`
let _: *mut i8 = string.as_ptr() as *mut _;
+ //~^ ERROR: casting the result of `as_ptr` to *mut i8
let _ = string.as_ptr() as *const i8;
let _ = string.as_mut_ptr();
let _ = string.as_mut_ptr() as *mut u8;
diff --git a/src/tools/clippy/tests/ui/as_ptr_cast_mut.stderr b/src/tools/clippy/tests/ui/as_ptr_cast_mut.stderr
index 2189c3d2f..92cdf9115 100644
--- a/src/tools/clippy/tests/ui/as_ptr_cast_mut.stderr
+++ b/src/tools/clippy/tests/ui/as_ptr_cast_mut.stderr
@@ -1,13 +1,14 @@
error: casting the result of `as_ptr` to *mut u8
- --> $DIR/as_ptr_cast_mut.rs:21:13
+ --> $DIR/as_ptr_cast_mut.rs:22:13
|
LL | let _ = string.as_ptr() as *mut u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `string.as_mut_ptr()`
|
= note: `-D clippy::as-ptr-cast-mut` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::as_ptr_cast_mut)]`
error: casting the result of `as_ptr` to *mut i8
- --> $DIR/as_ptr_cast_mut.rs:22:22
+ --> $DIR/as_ptr_cast_mut.rs:25:22
|
LL | let _: *mut i8 = string.as_ptr() as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `string.as_mut_ptr()`
diff --git a/src/tools/clippy/tests/ui/as_underscore.fixed b/src/tools/clippy/tests/ui/as_underscore.fixed
index 69af84a0e..c7f26e64c 100644
--- a/src/tools/clippy/tests/ui/as_underscore.fixed
+++ b/src/tools/clippy/tests/ui/as_underscore.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::as_underscore)]
fn foo(_n: usize) {}
diff --git a/src/tools/clippy/tests/ui/as_underscore.rs b/src/tools/clippy/tests/ui/as_underscore.rs
index a8cfb81d9..70f3b3866 100644
--- a/src/tools/clippy/tests/ui/as_underscore.rs
+++ b/src/tools/clippy/tests/ui/as_underscore.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::as_underscore)]
fn foo(_n: usize) {}
diff --git a/src/tools/clippy/tests/ui/as_underscore.stderr b/src/tools/clippy/tests/ui/as_underscore.stderr
index d7cd58d96..1842eeeac 100644
--- a/src/tools/clippy/tests/ui/as_underscore.stderr
+++ b/src/tools/clippy/tests/ui/as_underscore.stderr
@@ -1,5 +1,5 @@
error: using `as _` conversion
- --> $DIR/as_underscore.rs:9:9
+ --> $DIR/as_underscore.rs:7:9
|
LL | foo(n as _);
| ^^^^^-
@@ -7,9 +7,10 @@ LL | foo(n as _);
| help: consider giving the type explicitly: `usize`
|
= note: `-D clippy::as-underscore` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::as_underscore)]`
error: using `as _` conversion
- --> $DIR/as_underscore.rs:12:18
+ --> $DIR/as_underscore.rs:10:18
|
LL | let _n: u8 = n as _;
| ^^^^^-
diff --git a/src/tools/clippy/tests/ui/asm_syntax.rs b/src/tools/clippy/tests/ui/asm_syntax.rs
index af02e202b..0a7eb86bc 100644
--- a/src/tools/clippy/tests/ui/asm_syntax.rs
+++ b/src/tools/clippy/tests/ui/asm_syntax.rs
@@ -6,8 +6,11 @@ mod warn_intel {
pub(super) unsafe fn use_asm() {
use std::arch::asm;
asm!("");
+ //~^ ERROR: Intel x86 assembly syntax used
asm!("", options());
+ //~^ ERROR: Intel x86 assembly syntax used
asm!("", options(nostack));
+ //~^ ERROR: Intel x86 assembly syntax used
asm!("", options(att_syntax));
asm!("", options(nostack, att_syntax));
}
@@ -21,7 +24,9 @@ mod warn_att {
asm!("", options());
asm!("", options(nostack));
asm!("", options(att_syntax));
+ //~^ ERROR: AT&T x86 assembly syntax used
asm!("", options(nostack, att_syntax));
+ //~^ ERROR: AT&T x86 assembly syntax used
}
}
diff --git a/src/tools/clippy/tests/ui/asm_syntax.stderr b/src/tools/clippy/tests/ui/asm_syntax.stderr
index 9c7c3ba7d..537ea8c57 100644
--- a/src/tools/clippy/tests/ui/asm_syntax.stderr
+++ b/src/tools/clippy/tests/ui/asm_syntax.stderr
@@ -6,9 +6,10 @@ LL | asm!("");
|
= help: use AT&T x86 assembly syntax
= note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_intel_syntax)]`
error: Intel x86 assembly syntax used
- --> $DIR/asm_syntax.rs:9:9
+ --> $DIR/asm_syntax.rs:10:9
|
LL | asm!("", options());
| ^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | asm!("", options());
= help: use AT&T x86 assembly syntax
error: Intel x86 assembly syntax used
- --> $DIR/asm_syntax.rs:10:9
+ --> $DIR/asm_syntax.rs:12:9
|
LL | asm!("", options(nostack));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,16 +25,17 @@ LL | asm!("", options(nostack));
= help: use AT&T x86 assembly syntax
error: AT&T x86 assembly syntax used
- --> $DIR/asm_syntax.rs:23:9
+ --> $DIR/asm_syntax.rs:26:9
|
LL | asm!("", options(att_syntax));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: use Intel x86 assembly syntax
= note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_att_syntax)]`
error: AT&T x86 assembly syntax used
- --> $DIR/asm_syntax.rs:24:9
+ --> $DIR/asm_syntax.rs:28:9
|
LL | asm!("", options(nostack, att_syntax));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.rs b/src/tools/clippy/tests/ui/assertions_on_constants.rs
index 7bea9563d..10809a6d2 100644
--- a/src/tools/clippy/tests/ui/assertions_on_constants.rs
+++ b/src/tools/clippy/tests/ui/assertions_on_constants.rs
@@ -8,21 +8,30 @@ macro_rules! assert_const {
}
fn main() {
assert!(true);
+ //~^ ERROR: `assert!(true)` will be optimized out by the compiler
assert!(false);
+ //~^ ERROR: `assert!(false)` should probably be replaced
assert!(true, "true message");
+ //~^ ERROR: `assert!(true)` will be optimized out by the compiler
assert!(false, "false message");
+ //~^ ERROR: `assert!(false, ..)` should probably be replaced
let msg = "panic message";
assert!(false, "{}", msg.to_uppercase());
+ //~^ ERROR: `assert!(false, ..)` should probably be replaced
const B: bool = true;
assert!(B);
+ //~^ ERROR: `assert!(true)` will be optimized out by the compiler
const C: bool = false;
assert!(C);
+ //~^ ERROR: `assert!(false)` should probably be replaced
assert!(C, "C message");
+ //~^ ERROR: `assert!(false, ..)` should probably be replaced
debug_assert!(true);
+ //~^ ERROR: `debug_assert!(true)` will be optimized out by the compiler
// Don't lint this, since there is no better way for expressing "Only panic in debug mode".
debug_assert!(false); // #3948
assert_const!(3);
diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.stderr b/src/tools/clippy/tests/ui/assertions_on_constants.stderr
index 29fe00903..780d1fe1c 100644
--- a/src/tools/clippy/tests/ui/assertions_on_constants.stderr
+++ b/src/tools/clippy/tests/ui/assertions_on_constants.stderr
@@ -6,9 +6,10 @@ LL | assert!(true);
|
= help: remove it
= note: `-D clippy::assertions-on-constants` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::assertions_on_constants)]`
error: `assert!(false)` should probably be replaced
- --> $DIR/assertions_on_constants.rs:11:5
+ --> $DIR/assertions_on_constants.rs:12:5
|
LL | assert!(false);
| ^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | assert!(false);
= help: use `panic!()` or `unreachable!()`
error: `assert!(true)` will be optimized out by the compiler
- --> $DIR/assertions_on_constants.rs:12:5
+ --> $DIR/assertions_on_constants.rs:14:5
|
LL | assert!(true, "true message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | assert!(true, "true message");
= help: remove it
error: `assert!(false, ..)` should probably be replaced
- --> $DIR/assertions_on_constants.rs:13:5
+ --> $DIR/assertions_on_constants.rs:16:5
|
LL | assert!(false, "false message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | assert!(false, "false message");
= help: use `panic!(..)` or `unreachable!(..)`
error: `assert!(false, ..)` should probably be replaced
- --> $DIR/assertions_on_constants.rs:16:5
+ --> $DIR/assertions_on_constants.rs:20:5
|
LL | assert!(false, "{}", msg.to_uppercase());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | assert!(false, "{}", msg.to_uppercase());
= help: use `panic!(..)` or `unreachable!(..)`
error: `assert!(true)` will be optimized out by the compiler
- --> $DIR/assertions_on_constants.rs:19:5
+ --> $DIR/assertions_on_constants.rs:24:5
|
LL | assert!(B);
| ^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | assert!(B);
= help: remove it
error: `assert!(false)` should probably be replaced
- --> $DIR/assertions_on_constants.rs:22:5
+ --> $DIR/assertions_on_constants.rs:28:5
|
LL | assert!(C);
| ^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | assert!(C);
= help: use `panic!()` or `unreachable!()`
error: `assert!(false, ..)` should probably be replaced
- --> $DIR/assertions_on_constants.rs:23:5
+ --> $DIR/assertions_on_constants.rs:30:5
|
LL | assert!(C, "C message");
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | assert!(C, "C message");
= help: use `panic!(..)` or `unreachable!(..)`
error: `debug_assert!(true)` will be optimized out by the compiler
- --> $DIR/assertions_on_constants.rs:25:5
+ --> $DIR/assertions_on_constants.rs:33:5
|
LL | debug_assert!(true);
| ^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
index 3152bd3ca..14d9b8b99 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::assertions_on_result_states)]
#![allow(clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.rs b/src/tools/clippy/tests/ui/assertions_on_result_states.rs
index 42755e935..ac1911d87 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.rs
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::assertions_on_result_states)]
#![allow(clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
index be581030c..23af51cfe 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
@@ -1,43 +1,44 @@
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:25:5
+ --> $DIR/assertions_on_result_states.rs:24:5
|
LL | assert!(r.is_ok());
| ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`
|
= note: `-D clippy::assertions-on-result-states` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::assertions_on_result_states)]`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:43:5
+ --> $DIR/assertions_on_result_states.rs:42:5
|
LL | assert!(get_ok().is_ok());
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok().unwrap()`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:46:5
+ --> $DIR/assertions_on_result_states.rs:45:5
|
LL | assert!(get_ok_macro!().is_ok());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok_macro!().unwrap()`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:59:5
+ --> $DIR/assertions_on_result_states.rs:58:5
|
LL | assert!(r.is_ok());
| ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`
error: called `assert!` with `Result::is_ok`
- --> $DIR/assertions_on_result_states.rs:65:9
+ --> $DIR/assertions_on_result_states.rs:64:9
|
LL | assert!(r.is_ok());
| ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`
error: called `assert!` with `Result::is_err`
- --> $DIR/assertions_on_result_states.rs:73:5
+ --> $DIR/assertions_on_result_states.rs:72:5
|
LL | assert!(r.is_err());
| ^^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap_err()`
error: called `assert!` with `Result::is_err`
- --> $DIR/assertions_on_result_states.rs:83:5
+ --> $DIR/assertions_on_result_states.rs:82:5
|
LL | assert!(res.is_err())
| ^^^^^^^^^^^^^^^^^^^^^ help: replace with: `res.unwrap_err();`
diff --git a/src/tools/clippy/tests/ui/assign_ops.fixed b/src/tools/clippy/tests/ui/assign_ops.fixed
index ef45e97d1..2bd0807f4 100644
--- a/src/tools/clippy/tests/ui/assign_ops.fixed
+++ b/src/tools/clippy/tests/ui/assign_ops.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
use core::num::Wrapping;
#[allow(dead_code, unused_assignments, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/assign_ops.rs b/src/tools/clippy/tests/ui/assign_ops.rs
index ae87afc48..be3491a44 100644
--- a/src/tools/clippy/tests/ui/assign_ops.rs
+++ b/src/tools/clippy/tests/ui/assign_ops.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
use core::num::Wrapping;
#[allow(dead_code, unused_assignments, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/assign_ops.stderr b/src/tools/clippy/tests/ui/assign_ops.stderr
index 63a938ab4..e021e1bab 100644
--- a/src/tools/clippy/tests/ui/assign_ops.stderr
+++ b/src/tools/clippy/tests/ui/assign_ops.stderr
@@ -1,67 +1,68 @@
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:9:5
+ --> $DIR/assign_ops.rs:7:5
|
LL | a = a + 1;
| ^^^^^^^^^ help: replace it with: `a += 1`
|
= note: `-D clippy::assign-op-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:10:5
+ --> $DIR/assign_ops.rs:8:5
|
LL | a = 1 + a;
| ^^^^^^^^^ help: replace it with: `a += 1`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:11:5
+ --> $DIR/assign_ops.rs:9:5
|
LL | a = a - 1;
| ^^^^^^^^^ help: replace it with: `a -= 1`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:12:5
+ --> $DIR/assign_ops.rs:10:5
|
LL | a = a * 99;
| ^^^^^^^^^^ help: replace it with: `a *= 99`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:13:5
+ --> $DIR/assign_ops.rs:11:5
|
LL | a = 42 * a;
| ^^^^^^^^^^ help: replace it with: `a *= 42`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:14:5
+ --> $DIR/assign_ops.rs:12:5
|
LL | a = a / 2;
| ^^^^^^^^^ help: replace it with: `a /= 2`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:15:5
+ --> $DIR/assign_ops.rs:13:5
|
LL | a = a % 5;
| ^^^^^^^^^ help: replace it with: `a %= 5`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:16:5
+ --> $DIR/assign_ops.rs:14:5
|
LL | a = a & 1;
| ^^^^^^^^^ help: replace it with: `a &= 1`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:22:5
+ --> $DIR/assign_ops.rs:20:5
|
LL | s = s + "bla";
| ^^^^^^^^^^^^^ help: replace it with: `s += "bla"`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:26:5
+ --> $DIR/assign_ops.rs:24:5
|
LL | a = a + Wrapping(1u32);
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a += Wrapping(1u32)`
error: manual implementation of an assign operation
- --> $DIR/assign_ops.rs:28:5
+ --> $DIR/assign_ops.rs:26:5
|
LL | v[0] = v[0] + v[1];
| ^^^^^^^^^^^^^^^^^^ help: replace it with: `v[0] += v[1]`
diff --git a/src/tools/clippy/tests/ui/assign_ops2.rs b/src/tools/clippy/tests/ui/assign_ops2.rs
index 2c876a96c..a53556425 100644
--- a/src/tools/clippy/tests/ui/assign_ops2.rs
+++ b/src/tools/clippy/tests/ui/assign_ops2.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![allow(clippy::uninlined_format_args)]
#[allow(unused_assignments)]
@@ -5,14 +6,24 @@
fn main() {
let mut a = 5;
a += a + 1;
+ //~^ ERROR: variable appears on both sides of an assignment operation
+ //~| NOTE: `-D clippy::misrefactored-assign-op` implied by `-D warnings`
a += 1 + a;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a -= a - 1;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a *= a * 99;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a *= 42 * a;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a /= a / 2;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a %= a % 5;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a &= a & 1;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a *= a * a;
+ //~^ ERROR: variable appears on both sides of an assignment operation
a = a * a * a;
a = a * 42 * a;
a = a * 2 + a;
@@ -50,6 +61,8 @@ fn cow_add_assign() {
// this can be linted
buf = buf + cows.clone();
+ //~^ ERROR: manual implementation of an assign operation
+ //~| NOTE: `-D clippy::assign-op-pattern` implied by `-D warnings`
// this should not as cow<str> Add is not commutative
buf = cows + buf;
diff --git a/src/tools/clippy/tests/ui/assign_ops2.stderr b/src/tools/clippy/tests/ui/assign_ops2.stderr
index 25e746022..6e9b96c0a 100644
--- a/src/tools/clippy/tests/ui/assign_ops2.stderr
+++ b/src/tools/clippy/tests/ui/assign_ops2.stderr
@@ -1,10 +1,11 @@
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:7:5
+ --> $DIR/assign_ops2.rs:8:5
|
LL | a += a + 1;
| ^^^^^^^^^^
|
= note: `-D clippy::misrefactored-assign-op` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::misrefactored_assign_op)]`
help: did you mean `a = a + 1` or `a = a + a + 1`? Consider replacing it with
|
LL | a += 1;
@@ -15,7 +16,7 @@ LL | a = a + a + 1;
| ~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:8:5
+ --> $DIR/assign_ops2.rs:11:5
|
LL | a += 1 + a;
| ^^^^^^^^^^
@@ -30,7 +31,7 @@ LL | a = a + 1 + a;
| ~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:9:5
+ --> $DIR/assign_ops2.rs:13:5
|
LL | a -= a - 1;
| ^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | a = a - (a - 1);
| ~~~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:10:5
+ --> $DIR/assign_ops2.rs:15:5
|
LL | a *= a * 99;
| ^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL | a = a * a * 99;
| ~~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:11:5
+ --> $DIR/assign_ops2.rs:17:5
|
LL | a *= 42 * a;
| ^^^^^^^^^^^
@@ -75,7 +76,7 @@ LL | a = a * 42 * a;
| ~~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:12:5
+ --> $DIR/assign_ops2.rs:19:5
|
LL | a /= a / 2;
| ^^^^^^^^^^
@@ -90,7 +91,7 @@ LL | a = a / (a / 2);
| ~~~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:13:5
+ --> $DIR/assign_ops2.rs:21:5
|
LL | a %= a % 5;
| ^^^^^^^^^^
@@ -105,7 +106,7 @@ LL | a = a % (a % 5);
| ~~~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:14:5
+ --> $DIR/assign_ops2.rs:23:5
|
LL | a &= a & 1;
| ^^^^^^^^^^
@@ -120,7 +121,7 @@ LL | a = a & a & 1;
| ~~~~~~~~~~~~~
error: variable appears on both sides of an assignment operation
- --> $DIR/assign_ops2.rs:15:5
+ --> $DIR/assign_ops2.rs:25:5
|
LL | a *= a * a;
| ^^^^^^^^^^
@@ -135,12 +136,13 @@ LL | a = a * a * a;
| ~~~~~~~~~~~~~
error: manual implementation of an assign operation
- --> $DIR/assign_ops2.rs:52:5
+ --> $DIR/assign_ops2.rs:63:5
|
LL | buf = buf + cows.clone();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `buf += cows.clone()`
|
= note: `-D clippy::assign-op-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]`
error: aborting due to 10 previous errors
diff --git a/src/tools/clippy/tests/ui/async_yields_async.fixed b/src/tools/clippy/tests/ui/async_yields_async.fixed
index 8d9b02389..cfad78138 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.fixed
+++ b/src/tools/clippy/tests/ui/async_yields_async.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(lint_reasons)]
#![feature(async_closure)]
#![warn(clippy::async_yields_async)]
diff --git a/src/tools/clippy/tests/ui/async_yields_async.rs b/src/tools/clippy/tests/ui/async_yields_async.rs
index bed79062f..7bc266479 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.rs
+++ b/src/tools/clippy/tests/ui/async_yields_async.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(lint_reasons)]
#![feature(async_closure)]
#![warn(clippy::async_yields_async)]
diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr
index 7f7253483..c29e3c734 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.stderr
+++ b/src/tools/clippy/tests/ui/async_yields_async.stderr
@@ -1,5 +1,5 @@
error: an async construct yields a type which is itself awaitable
- --> $DIR/async_yields_async.rs:40:9
+ --> $DIR/async_yields_async.rs:39:9
|
LL | let _h = async {
| _____________________-
@@ -11,6 +11,7 @@ LL | | };
| |______- outer async construct
|
= note: `-D clippy::async-yields-async` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::async_yields_async)]`
help: consider awaiting this value
|
LL ~ async {
@@ -19,7 +20,7 @@ LL + }.await
|
error: an async construct yields a type which is itself awaitable
- --> $DIR/async_yields_async.rs:45:9
+ --> $DIR/async_yields_async.rs:44:9
|
LL | let _i = async {
| ____________________-
@@ -32,7 +33,7 @@ LL | | };
| |_____- outer async construct
error: an async construct yields a type which is itself awaitable
- --> $DIR/async_yields_async.rs:51:9
+ --> $DIR/async_yields_async.rs:50:9
|
LL | let _j = async || {
| ________________________-
@@ -51,7 +52,7 @@ LL + }.await
|
error: an async construct yields a type which is itself awaitable
- --> $DIR/async_yields_async.rs:56:9
+ --> $DIR/async_yields_async.rs:55:9
|
LL | let _k = async || {
| _______________________-
@@ -64,7 +65,7 @@ LL | | };
| |_____- outer async construct
error: an async construct yields a type which is itself awaitable
- --> $DIR/async_yields_async.rs:58:23
+ --> $DIR/async_yields_async.rs:57:23
|
LL | let _l = async || CustomFutureType;
| ^^^^^^^^^^^^^^^^
@@ -74,7 +75,7 @@ LL | let _l = async || CustomFutureType;
| help: consider awaiting this value: `CustomFutureType.await`
error: an async construct yields a type which is itself awaitable
- --> $DIR/async_yields_async.rs:64:9
+ --> $DIR/async_yields_async.rs:63:9
|
LL | let _m = async || {
| _______________________-
diff --git a/src/tools/clippy/tests/ui/attrs.rs b/src/tools/clippy/tests/ui/attrs.rs
index 8df6e1942..05ee48d17 100644
--- a/src/tools/clippy/tests/ui/attrs.rs
+++ b/src/tools/clippy/tests/ui/attrs.rs
@@ -3,6 +3,8 @@
#![allow(clippy::missing_docs_in_private_items, clippy::panic, clippy::unreachable)]
#[inline(always)]
+//~^ ERROR: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a b
+//~| NOTE: `-D clippy::inline-always` implied by `-D warnings`
fn test_attr_lint() {
assert!(true)
}
@@ -23,9 +25,12 @@ fn empty_and_false_positive_stmt() {
}
#[deprecated(since = "forever")]
+//~^ ERROR: the since field must contain a semver-compliant version
+//~| NOTE: `-D clippy::deprecated-semver` implied by `-D warnings`
pub const SOME_CONST: u8 = 42;
#[deprecated(since = "1")]
+//~^ ERROR: the since field must contain a semver-compliant version
pub const ANOTHER_CONST: u8 = 23;
#[deprecated(since = "0.1.1")]
diff --git a/src/tools/clippy/tests/ui/attrs.stderr b/src/tools/clippy/tests/ui/attrs.stderr
index df4e9e20b..16402a4dd 100644
--- a/src/tools/clippy/tests/ui/attrs.stderr
+++ b/src/tools/clippy/tests/ui/attrs.stderr
@@ -5,17 +5,19 @@ LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::inline-always` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inline_always)]`
error: the since field must contain a semver-compliant version
- --> $DIR/attrs.rs:25:14
+ --> $DIR/attrs.rs:27:14
|
LL | #[deprecated(since = "forever")]
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::deprecated-semver` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::deprecated_semver)]`
error: the since field must contain a semver-compliant version
- --> $DIR/attrs.rs:28:14
+ --> $DIR/attrs.rs:32:14
|
LL | #[deprecated(since = "1")]
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/await_holding_lock.rs b/src/tools/clippy/tests/ui/await_holding_lock.rs
index 57e5b5504..27b57b648 100644
--- a/src/tools/clippy/tests/ui/await_holding_lock.rs
+++ b/src/tools/clippy/tests/ui/await_holding_lock.rs
@@ -7,6 +7,7 @@ mod std_mutex {
pub async fn bad(x: &Mutex<u32>) -> u32 {
let guard = x.lock().unwrap();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
@@ -22,11 +23,13 @@ mod std_mutex {
pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
let guard = x.read().unwrap();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
let mut guard = x.write().unwrap();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
@@ -48,6 +51,7 @@ mod std_mutex {
let first = baz().await;
let guard = x.lock().unwrap();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
let second = baz().await;
@@ -61,6 +65,7 @@ mod std_mutex {
let second = {
let guard = x.lock().unwrap();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
};
@@ -73,6 +78,7 @@ mod std_mutex {
pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move {
let guard = x.lock().unwrap();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
}
@@ -85,6 +91,7 @@ mod parking_lot_mutex {
pub async fn bad(x: &Mutex<u32>) -> u32 {
let guard = x.lock();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
@@ -100,11 +107,13 @@ mod parking_lot_mutex {
pub async fn bad_rw(x: &RwLock<u32>) -> u32 {
let guard = x.read();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {
let mut guard = x.write();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
@@ -126,6 +135,7 @@ mod parking_lot_mutex {
let first = baz().await;
let guard = x.lock();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
let second = baz().await;
@@ -139,6 +149,7 @@ mod parking_lot_mutex {
let second = {
let guard = x.lock();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
};
@@ -151,6 +162,7 @@ mod parking_lot_mutex {
pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move {
let guard = x.lock();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
baz().await
}
}
@@ -171,6 +183,7 @@ async fn no_await(x: std::sync::Mutex<u32>) {
// `*guard += 1` is removed it is picked up.
async fn dropped_before_await(x: std::sync::Mutex<u32>) {
let mut guard = x.lock().unwrap();
+ //~^ ERROR: this `MutexGuard` is held across an `await` point
*guard += 1;
drop(guard);
baz().await;
diff --git a/src/tools/clippy/tests/ui/await_holding_lock.stderr b/src/tools/clippy/tests/ui/await_holding_lock.stderr
index 81a2d0524..478210400 100644
--- a/src/tools/clippy/tests/ui/await_holding_lock.stderr
+++ b/src/tools/clippy/tests/ui/await_holding_lock.stderr
@@ -6,203 +6,174 @@ LL | let guard = x.lock().unwrap();
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:9:9
+ --> $DIR/await_holding_lock.rs:11:15
|
-LL | / let guard = x.lock().unwrap();
-LL | | baz().await
-LL | | }
- | |_____^
+LL | baz().await
+ | ^^^^^
= note: `-D clippy::await-holding-lock` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::await_holding_lock)]`
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:24:13
+ --> $DIR/await_holding_lock.rs:25:13
|
LL | let guard = x.read().unwrap();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:24:9
+ --> $DIR/await_holding_lock.rs:27:15
|
-LL | / let guard = x.read().unwrap();
-LL | | baz().await
-LL | | }
- | |_____^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:29:13
+ --> $DIR/await_holding_lock.rs:31:13
|
LL | let mut guard = x.write().unwrap();
| ^^^^^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:29:9
+ --> $DIR/await_holding_lock.rs:33:15
|
-LL | / let mut guard = x.write().unwrap();
-LL | | baz().await
-LL | | }
- | |_____^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:50:13
+ --> $DIR/await_holding_lock.rs:53:13
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:50:9
- |
-LL | / let guard = x.lock().unwrap();
-LL | |
-LL | | let second = baz().await;
-LL | |
-... |
-LL | | first + second + third
-LL | | }
- | |_____^
+ --> $DIR/await_holding_lock.rs:56:28
+ |
+LL | let second = baz().await;
+ | ^^^^^
+LL |
+LL | let third = baz().await;
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:63:17
+ --> $DIR/await_holding_lock.rs:67:17
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:63:13
+ --> $DIR/await_holding_lock.rs:69:19
|
-LL | / let guard = x.lock().unwrap();
-LL | | baz().await
-LL | | };
- | |_________^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:75:17
+ --> $DIR/await_holding_lock.rs:80:17
|
LL | let guard = x.lock().unwrap();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:75:13
+ --> $DIR/await_holding_lock.rs:82:19
|
-LL | / let guard = x.lock().unwrap();
-LL | | baz().await
-LL | | }
- | |_________^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:87:13
+ --> $DIR/await_holding_lock.rs:93:13
|
LL | let guard = x.lock();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:87:9
+ --> $DIR/await_holding_lock.rs:95:15
|
-LL | / let guard = x.lock();
-LL | | baz().await
-LL | | }
- | |_____^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:102:13
+ --> $DIR/await_holding_lock.rs:109:13
|
LL | let guard = x.read();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:102:9
+ --> $DIR/await_holding_lock.rs:111:15
|
-LL | / let guard = x.read();
-LL | | baz().await
-LL | | }
- | |_____^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:107:13
+ --> $DIR/await_holding_lock.rs:115:13
|
LL | let mut guard = x.write();
| ^^^^^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:107:9
+ --> $DIR/await_holding_lock.rs:117:15
|
-LL | / let mut guard = x.write();
-LL | | baz().await
-LL | | }
- | |_____^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:128:13
+ --> $DIR/await_holding_lock.rs:137:13
|
LL | let guard = x.lock();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:128:9
- |
-LL | / let guard = x.lock();
-LL | |
-LL | | let second = baz().await;
-LL | |
-... |
-LL | | first + second + third
-LL | | }
- | |_____^
+ --> $DIR/await_holding_lock.rs:140:28
+ |
+LL | let second = baz().await;
+ | ^^^^^
+LL |
+LL | let third = baz().await;
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:141:17
+ --> $DIR/await_holding_lock.rs:151:17
|
LL | let guard = x.lock();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:141:13
+ --> $DIR/await_holding_lock.rs:153:19
|
-LL | / let guard = x.lock();
-LL | | baz().await
-LL | | };
- | |_________^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:153:17
+ --> $DIR/await_holding_lock.rs:164:17
|
LL | let guard = x.lock();
| ^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:153:13
+ --> $DIR/await_holding_lock.rs:166:19
|
-LL | / let guard = x.lock();
-LL | | baz().await
-LL | | }
- | |_________^
+LL | baz().await
+ | ^^^^^
error: this `MutexGuard` is held across an `await` point
- --> $DIR/await_holding_lock.rs:173:9
+ --> $DIR/await_holding_lock.rs:185:9
|
LL | let mut guard = x.lock().unwrap();
| ^^^^^^^^^
|
= help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
note: these are all the `await` points this lock is held through
- --> $DIR/await_holding_lock.rs:173:5
- |
-LL | / let mut guard = x.lock().unwrap();
-LL | | *guard += 1;
-LL | | drop(guard);
-LL | | baz().await;
-LL | | }
- | |_^
+ --> $DIR/await_holding_lock.rs:189:11
+ |
+LL | baz().await;
+ | ^^^^^
error: aborting due to 13 previous errors
diff --git a/src/tools/clippy/tests/ui/await_holding_refcell_ref.rs b/src/tools/clippy/tests/ui/await_holding_refcell_ref.rs
index 23b7095de..5bd26c628 100644
--- a/src/tools/clippy/tests/ui/await_holding_refcell_ref.rs
+++ b/src/tools/clippy/tests/ui/await_holding_refcell_ref.rs
@@ -4,11 +4,13 @@ use std::cell::RefCell;
async fn bad(x: &RefCell<u32>) -> u32 {
let b = x.borrow();
+ //~^ ERROR: this `RefCell` reference is held across an `await` point
baz().await
}
async fn bad_mut(x: &RefCell<u32>) -> u32 {
let b = x.borrow_mut();
+ //~^ ERROR: this `RefCell` reference is held across an `await` point
baz().await
}
@@ -30,6 +32,7 @@ async fn also_bad(x: &RefCell<u32>) -> u32 {
let first = baz().await;
let b = x.borrow_mut();
+ //~^ ERROR: this `RefCell` reference is held across an `await` point
let second = baz().await;
@@ -42,6 +45,7 @@ async fn less_bad(x: &RefCell<u32>) -> u32 {
let first = baz().await;
let b = x.borrow_mut();
+ //~^ ERROR: this `RefCell` reference is held across an `await` point
let second = baz().await;
@@ -57,6 +61,7 @@ async fn not_good(x: &RefCell<u32>) -> u32 {
let second = {
let b = x.borrow_mut();
+ //~^ ERROR: this `RefCell` reference is held across an `await` point
baz().await
};
@@ -69,6 +74,7 @@ async fn not_good(x: &RefCell<u32>) -> u32 {
fn block_bad(x: &RefCell<u32>) -> impl std::future::Future<Output = u32> + '_ {
async move {
let b = x.borrow_mut();
+ //~^ ERROR: this `RefCell` reference is held across an `await` point
baz().await
}
}
diff --git a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
index 25c15ab80..9264af93d 100644
--- a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
+++ b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
@@ -6,96 +6,80 @@ LL | let b = x.borrow();
|
= help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through
- --> $DIR/await_holding_refcell_ref.rs:6:5
+ --> $DIR/await_holding_refcell_ref.rs:8:11
|
-LL | / let b = x.borrow();
-LL | | baz().await
-LL | | }
- | |_^
+LL | baz().await
+ | ^^^^^
= note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::await_holding_refcell_ref)]`
error: this `RefCell` reference is held across an `await` point
- --> $DIR/await_holding_refcell_ref.rs:11:9
+ --> $DIR/await_holding_refcell_ref.rs:12:9
|
LL | let b = x.borrow_mut();
| ^
|
= help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through
- --> $DIR/await_holding_refcell_ref.rs:11:5
+ --> $DIR/await_holding_refcell_ref.rs:14:11
|
-LL | / let b = x.borrow_mut();
-LL | | baz().await
-LL | | }
- | |_^
+LL | baz().await
+ | ^^^^^
error: this `RefCell` reference is held across an `await` point
- --> $DIR/await_holding_refcell_ref.rs:32:9
+ --> $DIR/await_holding_refcell_ref.rs:34:9
|
LL | let b = x.borrow_mut();
| ^
|
= help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through
- --> $DIR/await_holding_refcell_ref.rs:32:5
- |
-LL | / let b = x.borrow_mut();
-LL | |
-LL | | let second = baz().await;
-LL | |
-... |
-LL | | first + second + third
-LL | | }
- | |_^
+ --> $DIR/await_holding_refcell_ref.rs:37:24
+ |
+LL | let second = baz().await;
+ | ^^^^^
+LL |
+LL | let third = baz().await;
+ | ^^^^^
error: this `RefCell` reference is held across an `await` point
- --> $DIR/await_holding_refcell_ref.rs:44:9
+ --> $DIR/await_holding_refcell_ref.rs:47:9
|
LL | let b = x.borrow_mut();
| ^
|
= help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through
- --> $DIR/await_holding_refcell_ref.rs:44:5
- |
-LL | / let b = x.borrow_mut();
-LL | |
-LL | | let second = baz().await;
-LL | |
-... |
-LL | | first + second + third
-LL | | }
- | |_^
+ --> $DIR/await_holding_refcell_ref.rs:50:24
+ |
+LL | let second = baz().await;
+ | ^^^^^
error: this `RefCell` reference is held across an `await` point
- --> $DIR/await_holding_refcell_ref.rs:59:13
+ --> $DIR/await_holding_refcell_ref.rs:63:13
|
LL | let b = x.borrow_mut();
| ^
|
= help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through
- --> $DIR/await_holding_refcell_ref.rs:59:9
+ --> $DIR/await_holding_refcell_ref.rs:65:15
|
-LL | / let b = x.borrow_mut();
-LL | | baz().await
-LL | | };
- | |_____^
+LL | baz().await
+ | ^^^^^
error: this `RefCell` reference is held across an `await` point
- --> $DIR/await_holding_refcell_ref.rs:71:13
+ --> $DIR/await_holding_refcell_ref.rs:76:13
|
LL | let b = x.borrow_mut();
| ^
|
= help: ensure the reference is dropped before calling `await`
note: these are all the `await` points this reference is held through
- --> $DIR/await_holding_refcell_ref.rs:71:9
+ --> $DIR/await_holding_refcell_ref.rs:78:15
|
-LL | / let b = x.borrow_mut();
-LL | | baz().await
-LL | | }
- | |_____^
+LL | baz().await
+ | ^^^^^
error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map.fixed b/src/tools/clippy/tests/ui/bind_instead_of_map.fixed
index ea2dc2e22..910cec2f2 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map.fixed
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::bind_instead_of_map)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map.rs b/src/tools/clippy/tests/ui/bind_instead_of_map.rs
index 1db58dae5..6d66f659b 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map.rs
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::bind_instead_of_map)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map.stderr b/src/tools/clippy/tests/ui/bind_instead_of_map.stderr
index f17fee746..3af61e6d4 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map.stderr
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map.stderr
@@ -1,23 +1,23 @@
error: using `Option.and_then(Some)`, which is a no-op
- --> $DIR/bind_instead_of_map.rs:9:13
+ --> $DIR/bind_instead_of_map.rs:8:13
|
LL | let _ = x.and_then(Some);
| ^^^^^^^^^^^^^^^^ help: use the expression directly: `x`
|
note: the lint level is defined here
- --> $DIR/bind_instead_of_map.rs:2:9
+ --> $DIR/bind_instead_of_map.rs:1:9
|
LL | #![deny(clippy::bind_instead_of_map)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
- --> $DIR/bind_instead_of_map.rs:10:13
+ --> $DIR/bind_instead_of_map.rs:9:13
|
LL | let _ = x.and_then(|o| Some(o + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map(|o| o + 1)`
error: using `Result.and_then(Ok)`, which is a no-op
- --> $DIR/bind_instead_of_map.rs:16:13
+ --> $DIR/bind_instead_of_map.rs:15:13
|
LL | let _ = x.and_then(Ok);
| ^^^^^^^^^^^^^^ help: use the expression directly: `x`
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed
index 63c7aafcd..8cbadc67d 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::bind_instead_of_map)]
#![allow(clippy::blocks_in_if_conditions)]
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs
index 69b982fa8..91d9d11e3 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::bind_instead_of_map)]
#![allow(clippy::blocks_in_if_conditions)]
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
index cedbca785..63f25f26f 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
@@ -1,11 +1,11 @@
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
- --> $DIR/bind_instead_of_map_multipart.rs:6:13
+ --> $DIR/bind_instead_of_map_multipart.rs:5:13
|
LL | let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/bind_instead_of_map_multipart.rs:2:9
+ --> $DIR/bind_instead_of_map_multipart.rs:1:9
|
LL | #![deny(clippy::bind_instead_of_map)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL | let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
| ~~~ ~ ~~~~~~~
error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)`
- --> $DIR/bind_instead_of_map_multipart.rs:9:13
+ --> $DIR/bind_instead_of_map_multipart.rs:8:13
|
LL | let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len()
| ~~~ ~ ~~~~~~~
error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)`
- --> $DIR/bind_instead_of_map_multipart.rs:12:13
+ --> $DIR/bind_instead_of_map_multipart.rs:11:13
|
LL | let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL | let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 }
| ~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
- --> $DIR/bind_instead_of_map_multipart.rs:20:5
+ --> $DIR/bind_instead_of_map_multipart.rs:19:5
|
LL | / Some("42").and_then(|s| {
LL | | if {
@@ -77,7 +77,7 @@ LL ~ _ => 1,
|
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
- --> $DIR/bind_instead_of_map_multipart.rs:61:13
+ --> $DIR/bind_instead_of_map_multipart.rs:60:13
|
LL | let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/bit_masks.rs b/src/tools/clippy/tests/ui/bit_masks.rs
index cfb493fb5..8e1d066c2 100644
--- a/src/tools/clippy/tests/ui/bit_masks.rs
+++ b/src/tools/clippy/tests/ui/bit_masks.rs
@@ -12,19 +12,27 @@ fn main() {
let x = 5;
x & 0 == 0;
+ //~^ ERROR: &-masking with zero
+ //~| NOTE: `-D clippy::bad-bit-mask` implied by `-D warnings`
+ //~| ERROR: this operation will always return zero. This is likely not the intended ou
+ //~| NOTE: `#[deny(clippy::erasing_op)]` on by default
x & 1 == 1; //ok, distinguishes bit 0
x & 1 == 0; //ok, compared with zero
x & 2 == 1;
+ //~^ ERROR: incompatible bit mask: `_ & 2` can never be equal to `1`
x | 0 == 0; //ok, equals x == 0 (maybe warn?)
x | 1 == 3; //ok, equals x == 2 || x == 3
x | 3 == 3; //ok, equals x <= 3
x | 3 == 2;
+ //~^ ERROR: incompatible bit mask: `_ | 3` can never be equal to `2`
x & 1 > 1;
+ //~^ ERROR: incompatible bit mask: `_ & 1` will never be higher than `1`
x & 2 > 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0
x & 2 < 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0
x | 1 > 1; // ok (if a bit silly), equals x > 1
x | 2 > 1;
+ //~^ ERROR: incompatible bit mask: `_ | 2` will always be higher than `1`
x | 2 <= 2; // ok (if a bit silly), equals x <= 2
x & 192 == 128; // ok, tests for bit 7 and not bit 6
@@ -32,15 +40,22 @@ fn main() {
// this also now works with constants
x & THREE_BITS == 8;
+ //~^ ERROR: incompatible bit mask: `_ & 7` can never be equal to `8`
x | EVEN_MORE_REDIRECTION < 7;
+ //~^ ERROR: incompatible bit mask: `_ | 7` will never be lower than `7`
0 & x == 0;
+ //~^ ERROR: &-masking with zero
+ //~| ERROR: this operation will always return zero. This is likely not the intended ou
1 | x > 1;
// and should now also match uncommon usage
1 < 2 | x;
+ //~^ ERROR: incompatible bit mask: `_ | 2` will always be higher than `1`
2 == 3 | x;
+ //~^ ERROR: incompatible bit mask: `_ | 3` can never be equal to `2`
1 == x & 2;
+ //~^ ERROR: incompatible bit mask: `_ & 2` can never be equal to `1`
x | 1 > 2; // no error, because we allowed ineffective bit masks
ineffective();
@@ -52,9 +67,14 @@ fn ineffective() {
let x = 5;
x | 1 > 3;
+ //~^ ERROR: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared d
+ //~| NOTE: `-D clippy::ineffective-bit-mask` implied by `-D warnings`
x | 1 < 4;
+ //~^ ERROR: ineffective bit mask: `x | 1` compared to `4`, is the same as x compared d
x | 1 <= 3;
+ //~^ ERROR: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared d
x | 1 >= 8;
+ //~^ ERROR: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared d
x | 1 > 2; // not an error (yet), better written as x >= 2
x | 1 >= 7; // not an error (yet), better written as x >= 6
diff --git a/src/tools/clippy/tests/ui/bit_masks.stderr b/src/tools/clippy/tests/ui/bit_masks.stderr
index dc5ad6dfb..4423d15d7 100644
--- a/src/tools/clippy/tests/ui/bit_masks.stderr
+++ b/src/tools/clippy/tests/ui/bit_masks.stderr
@@ -5,6 +5,7 @@ LL | x & 0 == 0;
| ^^^^^^^^^^
|
= note: `-D clippy::bad-bit-mask` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::bad_bit_mask)]`
error: this operation will always return zero. This is likely not the intended outcome
--> $DIR/bit_masks.rs:14:5
@@ -15,93 +16,94 @@ LL | x & 0 == 0;
= note: `#[deny(clippy::erasing_op)]` on by default
error: incompatible bit mask: `_ & 2` can never be equal to `1`
- --> $DIR/bit_masks.rs:17:5
+ --> $DIR/bit_masks.rs:21:5
|
LL | x & 2 == 1;
| ^^^^^^^^^^
error: incompatible bit mask: `_ | 3` can never be equal to `2`
- --> $DIR/bit_masks.rs:21:5
+ --> $DIR/bit_masks.rs:26:5
|
LL | x | 3 == 2;
| ^^^^^^^^^^
error: incompatible bit mask: `_ & 1` will never be higher than `1`
- --> $DIR/bit_masks.rs:23:5
+ --> $DIR/bit_masks.rs:29:5
|
LL | x & 1 > 1;
| ^^^^^^^^^
error: incompatible bit mask: `_ | 2` will always be higher than `1`
- --> $DIR/bit_masks.rs:27:5
+ --> $DIR/bit_masks.rs:34:5
|
LL | x | 2 > 1;
| ^^^^^^^^^
error: incompatible bit mask: `_ & 7` can never be equal to `8`
- --> $DIR/bit_masks.rs:34:5
+ --> $DIR/bit_masks.rs:42:5
|
LL | x & THREE_BITS == 8;
| ^^^^^^^^^^^^^^^^^^^
error: incompatible bit mask: `_ | 7` will never be lower than `7`
- --> $DIR/bit_masks.rs:35:5
+ --> $DIR/bit_masks.rs:44:5
|
LL | x | EVEN_MORE_REDIRECTION < 7;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: &-masking with zero
- --> $DIR/bit_masks.rs:37:5
+ --> $DIR/bit_masks.rs:47:5
|
LL | 0 & x == 0;
| ^^^^^^^^^^
error: this operation will always return zero. This is likely not the intended outcome
- --> $DIR/bit_masks.rs:37:5
+ --> $DIR/bit_masks.rs:47:5
|
LL | 0 & x == 0;
| ^^^^^
error: incompatible bit mask: `_ | 2` will always be higher than `1`
- --> $DIR/bit_masks.rs:41:5
+ --> $DIR/bit_masks.rs:53:5
|
LL | 1 < 2 | x;
| ^^^^^^^^^
error: incompatible bit mask: `_ | 3` can never be equal to `2`
- --> $DIR/bit_masks.rs:42:5
+ --> $DIR/bit_masks.rs:55:5
|
LL | 2 == 3 | x;
| ^^^^^^^^^^
error: incompatible bit mask: `_ & 2` can never be equal to `1`
- --> $DIR/bit_masks.rs:43:5
+ --> $DIR/bit_masks.rs:57:5
|
LL | 1 == x & 2;
| ^^^^^^^^^^
error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly
- --> $DIR/bit_masks.rs:54:5
+ --> $DIR/bit_masks.rs:69:5
|
LL | x | 1 > 3;
| ^^^^^^^^^
|
= note: `-D clippy::ineffective-bit-mask` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ineffective_bit_mask)]`
error: ineffective bit mask: `x | 1` compared to `4`, is the same as x compared directly
- --> $DIR/bit_masks.rs:55:5
+ --> $DIR/bit_masks.rs:72:5
|
LL | x | 1 < 4;
| ^^^^^^^^^
error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly
- --> $DIR/bit_masks.rs:56:5
+ --> $DIR/bit_masks.rs:74:5
|
LL | x | 1 <= 3;
| ^^^^^^^^^^
error: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared directly
- --> $DIR/bit_masks.rs:57:5
+ --> $DIR/bit_masks.rs:76:5
|
LL | x | 1 >= 8;
| ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs
index e1ff25c54..2bfaadf8d 100644
--- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs
+++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs
@@ -4,7 +4,10 @@
//! Test that the whole restriction group is not enabled
#![warn(clippy::restriction)]
+//~^ ERROR: `clippy::restriction` is not meant to be enabled as a group
#![deny(clippy::restriction)]
+//~^ ERROR: `clippy::restriction` is not meant to be enabled as a group
#![forbid(clippy::restriction)]
+//~^ ERROR: `clippy::restriction` is not meant to be enabled as a group
fn main() {}
diff --git a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
index 2bf89ab69..afb634f34 100644
--- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
+++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
@@ -1,19 +1,15 @@
error: `clippy::restriction` is not meant to be enabled as a group
- |
- = note: because of the command line `--warn clippy::restriction`
- = help: enable the restriction lints you need individually
- = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`
-
-error: `clippy::restriction` is not meant to be enabled as a group
--> $DIR/blanket_clippy_restriction_lints.rs:6:9
|
LL | #![warn(clippy::restriction)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: enable the restriction lints you need individually
+ = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::blanket_clippy_restriction_lints)]`
error: `clippy::restriction` is not meant to be enabled as a group
- --> $DIR/blanket_clippy_restriction_lints.rs:7:9
+ --> $DIR/blanket_clippy_restriction_lints.rs:8:9
|
LL | #![deny(clippy::restriction)]
| ^^^^^^^^^^^^^^^^^^^
@@ -21,12 +17,17 @@ LL | #![deny(clippy::restriction)]
= help: enable the restriction lints you need individually
error: `clippy::restriction` is not meant to be enabled as a group
- --> $DIR/blanket_clippy_restriction_lints.rs:8:11
+ --> $DIR/blanket_clippy_restriction_lints.rs:10:11
|
LL | #![forbid(clippy::restriction)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: enable the restriction lints you need individually
+error: `clippy::restriction` is not meant to be enabled as a group
+ |
+ = note: because of the command line `--warn clippy::restriction`
+ = help: enable the restriction lints you need individually
+
error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed
index 2a3867ac8..f89c46504 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed
+++ b/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::blocks_in_if_conditions)]
#![allow(unused, clippy::let_and_return, clippy::needless_if)]
#![warn(clippy::nonminimal_bool)]
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs
index 704d09fba..34febc5fa 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::blocks_in_if_conditions)]
#![allow(unused, clippy::let_and_return, clippy::needless_if)]
#![warn(clippy::nonminimal_bool)]
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr b/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr
index 079f2feb5..d80ef9c0f 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr
+++ b/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr
@@ -1,5 +1,5 @@
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`
- --> $DIR/blocks_in_if_conditions.rs:24:5
+ --> $DIR/blocks_in_if_conditions.rs:23:5
|
LL | / if {
LL | | let x = 3;
@@ -8,6 +8,7 @@ LL | | } {
| |_____^
|
= note: `-D clippy::blocks-in-if-conditions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::blocks_in_if_conditions)]`
help: try
|
LL ~ let res = {
@@ -17,18 +18,19 @@ LL ~ }; if res {
|
error: omit braces around single expression condition
- --> $DIR/blocks_in_if_conditions.rs:35:8
+ --> $DIR/blocks_in_if_conditions.rs:34:8
|
LL | if { true } { 6 } else { 10 }
| ^^^^^^^^ help: try: `true`
error: this boolean expression can be simplified
- --> $DIR/blocks_in_if_conditions.rs:40:8
+ --> $DIR/blocks_in_if_conditions.rs:39:8
|
LL | if true && x == 3 { 6 } else { 10 }
| ^^^^^^^^^^^^^^ help: try: `x == 3`
|
= note: `-D clippy::nonminimal-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs b/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs
index d6d085d7f..539f2df15 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs
@@ -21,6 +21,8 @@ fn pred_test() {
&& sky == "blue"
&& predicate(
|x| {
+ //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks
+ //~| NOTE: `-D clippy::blocks-in-if-conditions` implied by `-D warnings`
let target = 3;
x == target
},
@@ -30,6 +32,7 @@ fn pred_test() {
if predicate(
|x| {
+ //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; in
let target = 3;
x == target
},
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr b/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr
index 5ac02e750..ab68997d4 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr
+++ b/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr
@@ -3,18 +3,22 @@ error: in an `if` condition, avoid complex blocks or closures with blocks; inste
|
LL | |x| {
| _________________^
+LL | |
+LL | |
LL | | let target = 3;
LL | | x == target
LL | | },
| |_____________^
|
= note: `-D clippy::blocks-in-if-conditions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::blocks_in_if_conditions)]`
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`
- --> $DIR/blocks_in_if_conditions_closure.rs:32:13
+ --> $DIR/blocks_in_if_conditions_closure.rs:34:13
|
LL | |x| {
| _____________^
+LL | |
LL | | let target = 3;
LL | | x == target
LL | | },
diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.fixed b/src/tools/clippy/tests/ui/bool_assert_comparison.fixed
index 53f63444a..63b8e27e1 100644
--- a/src/tools/clippy/tests/ui/bool_assert_comparison.fixed
+++ b/src/tools/clippy/tests/ui/bool_assert_comparison.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::assertions_on_constants)]
#![warn(clippy::bool_assert_comparison)]
diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.rs b/src/tools/clippy/tests/ui/bool_assert_comparison.rs
index 151d93a92..58f81fedb 100644
--- a/src/tools/clippy/tests/ui/bool_assert_comparison.rs
+++ b/src/tools/clippy/tests/ui/bool_assert_comparison.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::assertions_on_constants)]
#![warn(clippy::bool_assert_comparison)]
diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr
index 89cefc95a..5969e4faa 100644
--- a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr
+++ b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr
@@ -1,10 +1,11 @@
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:89:5
+ --> $DIR/bool_assert_comparison.rs:87:5
|
LL | assert_eq!("a".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::bool-assert-comparison` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::bool_assert_comparison)]`
help: replace it with `assert!(..)`
|
LL - assert_eq!("a".is_empty(), false);
@@ -12,7 +13,7 @@ LL + assert!(!"a".is_empty());
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:90:5
+ --> $DIR/bool_assert_comparison.rs:88:5
|
LL | assert_eq!("".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + assert!("".is_empty());
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:91:5
+ --> $DIR/bool_assert_comparison.rs:89:5
|
LL | assert_eq!(true, "".is_empty());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL + assert!("".is_empty());
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:96:5
+ --> $DIR/bool_assert_comparison.rs:94:5
|
LL | assert_eq!(b, true);
| ^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL + assert!(b);
|
error: used `assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:99:5
+ --> $DIR/bool_assert_comparison.rs:97:5
|
LL | assert_ne!("a".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL + assert!("a".is_empty());
|
error: used `assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:100:5
+ --> $DIR/bool_assert_comparison.rs:98:5
|
LL | assert_ne!("".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL + assert!(!"".is_empty());
|
error: used `assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:101:5
+ --> $DIR/bool_assert_comparison.rs:99:5
|
LL | assert_ne!(true, "".is_empty());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +85,7 @@ LL + assert!(!"".is_empty());
|
error: used `assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:106:5
+ --> $DIR/bool_assert_comparison.rs:104:5
|
LL | assert_ne!(b, true);
| ^^^^^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL + assert!(!b);
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:109:5
+ --> $DIR/bool_assert_comparison.rs:107:5
|
LL | debug_assert_eq!("a".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -108,7 +109,7 @@ LL + debug_assert!(!"a".is_empty());
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:110:5
+ --> $DIR/bool_assert_comparison.rs:108:5
|
LL | debug_assert_eq!("".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,7 +121,7 @@ LL + debug_assert!("".is_empty());
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:111:5
+ --> $DIR/bool_assert_comparison.rs:109:5
|
LL | debug_assert_eq!(true, "".is_empty());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,7 +133,7 @@ LL + debug_assert!("".is_empty());
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:116:5
+ --> $DIR/bool_assert_comparison.rs:114:5
|
LL | debug_assert_eq!(b, true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +145,7 @@ LL + debug_assert!(b);
|
error: used `debug_assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:119:5
+ --> $DIR/bool_assert_comparison.rs:117:5
|
LL | debug_assert_ne!("a".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -156,7 +157,7 @@ LL + debug_assert!("a".is_empty());
|
error: used `debug_assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:120:5
+ --> $DIR/bool_assert_comparison.rs:118:5
|
LL | debug_assert_ne!("".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,7 +169,7 @@ LL + debug_assert!(!"".is_empty());
|
error: used `debug_assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:121:5
+ --> $DIR/bool_assert_comparison.rs:119:5
|
LL | debug_assert_ne!(true, "".is_empty());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -180,7 +181,7 @@ LL + debug_assert!(!"".is_empty());
|
error: used `debug_assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:126:5
+ --> $DIR/bool_assert_comparison.rs:124:5
|
LL | debug_assert_ne!(b, true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -192,7 +193,7 @@ LL + debug_assert!(!b);
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:131:5
+ --> $DIR/bool_assert_comparison.rs:129:5
|
LL | assert_eq!("a".is_empty(), false, "tadam {}", 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -204,7 +205,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", 1);
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:132:5
+ --> $DIR/bool_assert_comparison.rs:130:5
|
LL | assert_eq!("a".is_empty(), false, "tadam {}", true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -216,7 +217,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", true);
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:133:5
+ --> $DIR/bool_assert_comparison.rs:131:5
|
LL | assert_eq!(false, "a".is_empty(), "tadam {}", true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -228,7 +229,7 @@ LL + assert!(!"a".is_empty(), "tadam {}", true);
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:138:5
+ --> $DIR/bool_assert_comparison.rs:136:5
|
LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -240,7 +241,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", 1);
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:139:5
+ --> $DIR/bool_assert_comparison.rs:137:5
|
LL | debug_assert_eq!("a".is_empty(), false, "tadam {}", true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -252,7 +253,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", true);
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:140:5
+ --> $DIR/bool_assert_comparison.rs:138:5
|
LL | debug_assert_eq!(false, "a".is_empty(), "tadam {}", true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -264,7 +265,7 @@ LL + debug_assert!(!"a".is_empty(), "tadam {}", true);
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:143:5
+ --> $DIR/bool_assert_comparison.rs:141:5
|
LL | assert_eq!(a!(), true);
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -276,7 +277,7 @@ LL + assert!(a!());
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:144:5
+ --> $DIR/bool_assert_comparison.rs:142:5
|
LL | assert_eq!(true, b!());
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -288,7 +289,7 @@ LL + assert!(b!());
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:148:5
+ --> $DIR/bool_assert_comparison.rs:146:5
|
LL | renamed!(b, true);
| ^^^^^^^^^^^^^^^^^
@@ -300,7 +301,7 @@ LL + debug_assert!(b);
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:162:5
+ --> $DIR/bool_assert_comparison.rs:160:5
|
LL | assert_eq!("".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -312,7 +313,7 @@ LL + assert!("".is_empty());
|
error: used `assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:163:5
+ --> $DIR/bool_assert_comparison.rs:161:5
|
LL | assert_ne!("".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -324,7 +325,7 @@ LL + assert!("".is_empty());
|
error: used `assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:164:5
+ --> $DIR/bool_assert_comparison.rs:162:5
|
LL | assert_ne!("requires negation".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -336,7 +337,7 @@ LL + assert!(!"requires negation".is_empty());
|
error: used `assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:165:5
+ --> $DIR/bool_assert_comparison.rs:163:5
|
LL | assert_eq!("requires negation".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -348,7 +349,7 @@ LL + assert!(!"requires negation".is_empty());
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:167:5
+ --> $DIR/bool_assert_comparison.rs:165:5
|
LL | debug_assert_eq!("".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -360,7 +361,7 @@ LL + debug_assert!("".is_empty());
|
error: used `debug_assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:168:5
+ --> $DIR/bool_assert_comparison.rs:166:5
|
LL | debug_assert_ne!("".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -372,7 +373,7 @@ LL + debug_assert!("".is_empty());
|
error: used `debug_assert_ne!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:169:5
+ --> $DIR/bool_assert_comparison.rs:167:5
|
LL | debug_assert_ne!("requires negation".is_empty(), true);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -384,7 +385,7 @@ LL + debug_assert!(!"requires negation".is_empty());
|
error: used `debug_assert_eq!` with a literal bool
- --> $DIR/bool_assert_comparison.rs:170:5
+ --> $DIR/bool_assert_comparison.rs:168:5
|
LL | debug_assert_eq!("requires negation".is_empty(), false);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/bool_comparison.fixed b/src/tools/clippy/tests/ui/bool_comparison.fixed
index 8689f89d2..e3f2ca72d 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.fixed
+++ b/src/tools/clippy/tests/ui/bool_comparison.fixed
@@ -1,8 +1,6 @@
-//@run-rustfix
-
#![allow(clippy::needless_if)]
#![warn(clippy::bool_comparison)]
-#![allow(clippy::incorrect_partial_ord_impl_on_ord_type)]
+#![allow(clippy::non_canonical_partial_ord_impl)]
fn main() {
let x = true;
diff --git a/src/tools/clippy/tests/ui/bool_comparison.rs b/src/tools/clippy/tests/ui/bool_comparison.rs
index a1c94aff9..d1bc20d68 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.rs
+++ b/src/tools/clippy/tests/ui/bool_comparison.rs
@@ -1,8 +1,6 @@
-//@run-rustfix
-
#![allow(clippy::needless_if)]
#![warn(clippy::bool_comparison)]
-#![allow(clippy::incorrect_partial_ord_impl_on_ord_type)]
+#![allow(clippy::non_canonical_partial_ord_impl)]
fn main() {
let x = true;
diff --git a/src/tools/clippy/tests/ui/bool_comparison.stderr b/src/tools/clippy/tests/ui/bool_comparison.stderr
index 19bdf3013..4560df6d4 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.stderr
+++ b/src/tools/clippy/tests/ui/bool_comparison.stderr
@@ -1,133 +1,134 @@
error: equality checks against true are unnecessary
- --> $DIR/bool_comparison.rs:9:8
+ --> $DIR/bool_comparison.rs:7:8
|
LL | if x == true {
| ^^^^^^^^^ help: try simplifying it as shown: `x`
|
= note: `-D clippy::bool-comparison` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
error: equality checks against false can be replaced by a negation
- --> $DIR/bool_comparison.rs:14:8
+ --> $DIR/bool_comparison.rs:12:8
|
LL | if x == false {
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: equality checks against true are unnecessary
- --> $DIR/bool_comparison.rs:19:8
+ --> $DIR/bool_comparison.rs:17:8
|
LL | if true == x {
| ^^^^^^^^^ help: try simplifying it as shown: `x`
error: equality checks against false can be replaced by a negation
- --> $DIR/bool_comparison.rs:24:8
+ --> $DIR/bool_comparison.rs:22:8
|
LL | if false == x {
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: inequality checks against true can be replaced by a negation
- --> $DIR/bool_comparison.rs:29:8
+ --> $DIR/bool_comparison.rs:27:8
|
LL | if x != true {
| ^^^^^^^^^ help: try simplifying it as shown: `!x`
error: inequality checks against false are unnecessary
- --> $DIR/bool_comparison.rs:34:8
+ --> $DIR/bool_comparison.rs:32:8
|
LL | if x != false {
| ^^^^^^^^^^ help: try simplifying it as shown: `x`
error: inequality checks against true can be replaced by a negation
- --> $DIR/bool_comparison.rs:39:8
+ --> $DIR/bool_comparison.rs:37:8
|
LL | if true != x {
| ^^^^^^^^^ help: try simplifying it as shown: `!x`
error: inequality checks against false are unnecessary
- --> $DIR/bool_comparison.rs:44:8
+ --> $DIR/bool_comparison.rs:42:8
|
LL | if false != x {
| ^^^^^^^^^^ help: try simplifying it as shown: `x`
error: less than comparison against true can be replaced by a negation
- --> $DIR/bool_comparison.rs:49:8
+ --> $DIR/bool_comparison.rs:47:8
|
LL | if x < true {
| ^^^^^^^^ help: try simplifying it as shown: `!x`
error: greater than checks against false are unnecessary
- --> $DIR/bool_comparison.rs:54:8
+ --> $DIR/bool_comparison.rs:52:8
|
LL | if false < x {
| ^^^^^^^^^ help: try simplifying it as shown: `x`
error: greater than checks against false are unnecessary
- --> $DIR/bool_comparison.rs:59:8
+ --> $DIR/bool_comparison.rs:57:8
|
LL | if x > false {
| ^^^^^^^^^ help: try simplifying it as shown: `x`
error: less than comparison against true can be replaced by a negation
- --> $DIR/bool_comparison.rs:64:8
+ --> $DIR/bool_comparison.rs:62:8
|
LL | if true > x {
| ^^^^^^^^ help: try simplifying it as shown: `!x`
error: order comparisons between booleans can be simplified
- --> $DIR/bool_comparison.rs:70:8
+ --> $DIR/bool_comparison.rs:68:8
|
LL | if x < y {
| ^^^^^ help: try simplifying it as shown: `!x & y`
error: order comparisons between booleans can be simplified
- --> $DIR/bool_comparison.rs:75:8
+ --> $DIR/bool_comparison.rs:73:8
|
LL | if x > y {
| ^^^^^ help: try simplifying it as shown: `x & !y`
error: this comparison might be written more concisely
- --> $DIR/bool_comparison.rs:123:8
+ --> $DIR/bool_comparison.rs:121:8
|
LL | if a == !b {};
| ^^^^^^^ help: try simplifying it as shown: `a != b`
error: this comparison might be written more concisely
- --> $DIR/bool_comparison.rs:124:8
+ --> $DIR/bool_comparison.rs:122:8
|
LL | if !a == b {};
| ^^^^^^^ help: try simplifying it as shown: `a != b`
error: this comparison might be written more concisely
- --> $DIR/bool_comparison.rs:128:8
+ --> $DIR/bool_comparison.rs:126:8
|
LL | if b == !a {};
| ^^^^^^^ help: try simplifying it as shown: `b != a`
error: this comparison might be written more concisely
- --> $DIR/bool_comparison.rs:129:8
+ --> $DIR/bool_comparison.rs:127:8
|
LL | if !b == a {};
| ^^^^^^^ help: try simplifying it as shown: `b != a`
error: equality checks against false can be replaced by a negation
- --> $DIR/bool_comparison.rs:153:8
+ --> $DIR/bool_comparison.rs:151:8
|
LL | if false == m!(func) {}
| ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)`
error: equality checks against false can be replaced by a negation
- --> $DIR/bool_comparison.rs:154:8
+ --> $DIR/bool_comparison.rs:152:8
|
LL | if m!(func) == false {}
| ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)`
error: equality checks against true are unnecessary
- --> $DIR/bool_comparison.rs:155:8
+ --> $DIR/bool_comparison.rs:153:8
|
LL | if true == m!(func) {}
| ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)`
error: equality checks against true are unnecessary
- --> $DIR/bool_comparison.rs:156:8
+ --> $DIR/bool_comparison.rs:154:8
|
LL | if m!(func) == true {}
| ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)`
diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed
index fbb10a133..44d7f6e6d 100644
--- a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed
+++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(let_chains, inline_const)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs
index 709a18d63..7d989ae4b 100644
--- a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs
+++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(let_chains, inline_const)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
index 3bdae75ca..837ed05d3 100644
--- a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
+++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
@@ -1,5 +1,5 @@
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:16:5
+ --> $DIR/bool_to_int_with_if.rs:14:5
|
LL | / if a {
LL | | 1
@@ -10,9 +10,10 @@ LL | | };
|
= note: `a as i32` or `a.into()` can also be valid options
= note: `-D clippy::bool-to-int-with-if` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::bool_to_int_with_if)]`
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:21:5
+ --> $DIR/bool_to_int_with_if.rs:19:5
|
LL | / if a {
LL | | 0
@@ -24,7 +25,7 @@ LL | | };
= note: `!a as i32` or `(!a).into()` can also be valid options
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:26:5
+ --> $DIR/bool_to_int_with_if.rs:24:5
|
LL | / if !a {
LL | | 1
@@ -36,7 +37,7 @@ LL | | };
= note: `!a as i32` or `(!a).into()` can also be valid options
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:31:5
+ --> $DIR/bool_to_int_with_if.rs:29:5
|
LL | / if a || b {
LL | | 1
@@ -48,7 +49,7 @@ LL | | };
= note: `(a || b) as i32` or `(a || b).into()` can also be valid options
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:36:5
+ --> $DIR/bool_to_int_with_if.rs:34:5
|
LL | / if cond(a, b) {
LL | | 1
@@ -60,7 +61,7 @@ LL | | };
= note: `cond(a, b) as i32` or `cond(a, b).into()` can also be valid options
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:41:5
+ --> $DIR/bool_to_int_with_if.rs:39:5
|
LL | / if x + y < 4 {
LL | | 1
@@ -72,7 +73,7 @@ LL | | };
= note: `(x + y < 4) as i32` or `(x + y < 4).into()` can also be valid options
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:50:12
+ --> $DIR/bool_to_int_with_if.rs:48:12
|
LL | } else if b {
| ____________^
@@ -85,7 +86,7 @@ LL | | };
= note: `b as i32` or `b.into()` can also be valid options
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:59:12
+ --> $DIR/bool_to_int_with_if.rs:57:12
|
LL | } else if b {
| ____________^
@@ -98,7 +99,7 @@ LL | | };
= note: `!b as i32` or `(!b).into()` can also be valid options
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:126:5
+ --> $DIR/bool_to_int_with_if.rs:124:5
|
LL | if a { 1 } else { 0 }
| ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)`
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
index 996cc3650..6c0de96d6 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::borrow_as_ptr)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.rs b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
index 5eafaeb2f..c37c5357c 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::borrow_as_ptr)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.stderr b/src/tools/clippy/tests/ui/borrow_as_ptr.stderr
index c9990bb6f..43a7a6bf5 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.stderr
@@ -1,13 +1,14 @@
error: borrow as raw pointer
- --> $DIR/borrow_as_ptr.rs:11:14
+ --> $DIR/borrow_as_ptr.rs:10:14
|
LL | let _p = &val as *const i32;
| ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of!(val)`
|
= note: `-D clippy::borrow-as-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
error: borrow as raw pointer
- --> $DIR/borrow_as_ptr.rs:18:18
+ --> $DIR/borrow_as_ptr.rs:17:18
|
LL | let _p_mut = &mut val_mut as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(val_mut)`
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed
index 10f2727c7..a361a3647 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::borrow_as_ptr)]
#![feature(lang_items, start, libc)]
#![no_std]
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs
index 311e9341a..b3fe01442 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::borrow_as_ptr)]
#![feature(lang_items, start, libc)]
#![no_std]
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr
index 84c8ba7d0..2f258bcf9 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr
@@ -1,13 +1,14 @@
error: borrow as raw pointer
- --> $DIR/borrow_as_ptr_no_std.rs:9:14
+ --> $DIR/borrow_as_ptr_no_std.rs:8:14
|
LL | let _p = &val as *const i32;
| ^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of!(val)`
|
= note: `-D clippy::borrow-as-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
error: borrow as raw pointer
- --> $DIR/borrow_as_ptr_no_std.rs:12:18
+ --> $DIR/borrow_as_ptr_no_std.rs:11:18
|
LL | let _p_mut = &mut val_mut as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of_mut!(val_mut)`
diff --git a/src/tools/clippy/tests/ui/borrow_box.rs b/src/tools/clippy/tests/ui/borrow_box.rs
index 95b6b0f50..e9994aac8 100644
--- a/src/tools/clippy/tests/ui/borrow_box.rs
+++ b/src/tools/clippy/tests/ui/borrow_box.rs
@@ -5,6 +5,7 @@
clippy::disallowed_names,
clippy::needless_pass_by_ref_mut
)]
+//@no-rustfix
use std::fmt::Display;
@@ -22,14 +23,17 @@ pub fn test1(foo: &mut Box<bool>) {
pub fn test2() {
let foo: &Box<bool>;
+ //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
}
struct Test3<'a> {
foo: &'a Box<bool>,
+ //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
}
trait Test4 {
fn test4(a: &Box<bool>);
+ //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
}
impl<'a> Test4 for Test3<'a> {
@@ -96,17 +100,24 @@ pub fn test13(boxed_slice: &mut Box<[i32]>) {
// The suggestion should include proper parentheses to avoid a syntax error.
pub fn test14(_display: &Box<dyn Display>) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
pub fn test15(_display: &Box<dyn Display + Send>) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
pub fn test16<'a>(_display: &'a Box<dyn Display + 'a>) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
pub fn test17(_display: &Box<impl Display>) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
pub fn test18(_display: &Box<impl Display + Send>) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
pub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
// This exists only to check what happens when parentheses are already present.
// Even though the current implementation doesn't put extra parentheses,
// it's fine that unnecessary parentheses appear in the future for some reason.
pub fn test20(_display: &Box<(dyn Display + Send)>) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
fn main() {
test1(&mut Box::new(false));
diff --git a/src/tools/clippy/tests/ui/borrow_box.stderr b/src/tools/clippy/tests/ui/borrow_box.stderr
index 90e752211..a9773958a 100644
--- a/src/tools/clippy/tests/ui/borrow_box.stderr
+++ b/src/tools/clippy/tests/ui/borrow_box.stderr
@@ -1,5 +1,5 @@
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:24:14
+ --> $DIR/borrow_box.rs:25:14
|
LL | let foo: &Box<bool>;
| ^^^^^^^^^^ help: try: `&bool`
@@ -11,55 +11,55 @@ LL | #![deny(clippy::borrowed_box)]
| ^^^^^^^^^^^^^^^^^^^^
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:28:10
+ --> $DIR/borrow_box.rs:30:10
|
LL | foo: &'a Box<bool>,
| ^^^^^^^^^^^^^ help: try: `&'a bool`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:32:17
+ --> $DIR/borrow_box.rs:35:17
|
LL | fn test4(a: &Box<bool>);
| ^^^^^^^^^^ help: try: `&bool`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:98:25
+ --> $DIR/borrow_box.rs:102:25
|
LL | pub fn test14(_display: &Box<dyn Display>) {}
| ^^^^^^^^^^^^^^^^^ help: try: `&dyn Display`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:99:25
+ --> $DIR/borrow_box.rs:104:25
|
LL | pub fn test15(_display: &Box<dyn Display + Send>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:100:29
+ --> $DIR/borrow_box.rs:106:29
|
LL | pub fn test16<'a>(_display: &'a Box<dyn Display + 'a>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (dyn Display + 'a)`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:102:25
+ --> $DIR/borrow_box.rs:109:25
|
LL | pub fn test17(_display: &Box<impl Display>) {}
| ^^^^^^^^^^^^^^^^^^ help: try: `&impl Display`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:103:25
+ --> $DIR/borrow_box.rs:111:25
|
LL | pub fn test18(_display: &Box<impl Display + Send>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(impl Display + Send)`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:104:29
+ --> $DIR/borrow_box.rs:113:29
|
LL | pub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (impl Display + 'a)`
error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
- --> $DIR/borrow_box.rs:109:25
+ --> $DIR/borrow_box.rs:119:25
|
LL | pub fn test20(_display: &Box<(dyn Display + Send)>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed
index b951ba04c..ea5e983de 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![allow(dead_code, unused_variables)]
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.rs b/src/tools/clippy/tests/ui/borrow_deref_ref.rs
index 52980e55f..8c8905b15 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref.rs
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![allow(dead_code, unused_variables)]
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref.stderr
index 1e47cda67..c389d6797 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref.stderr
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref.stderr
@@ -1,19 +1,20 @@
error: deref on an immutable reference
- --> $DIR/borrow_deref_ref.rs:14:17
+ --> $DIR/borrow_deref_ref.rs:13:17
|
LL | let b = &*a;
| ^^^ help: if you would like to reborrow, try removing `&*`: `a`
|
= note: `-D clippy::borrow-deref-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]`
error: deref on an immutable reference
- --> $DIR/borrow_deref_ref.rs:16:22
+ --> $DIR/borrow_deref_ref.rs:15:22
|
LL | let b = &mut &*bar(&12);
| ^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `bar(&12)`
error: deref on an immutable reference
- --> $DIR/borrow_deref_ref.rs:70:23
+ --> $DIR/borrow_deref_ref.rs:69:23
|
LL | let addr_y = &&*x as *const _ as usize; // assert ok
| ^^^ help: if you would like to reborrow, try removing `&*`: `x`
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.rs b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.rs
index a8e2bbfef..be9887339 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.rs
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![allow(dead_code, unused_variables)]
fn main() {}
@@ -6,5 +7,7 @@ mod should_lint {
fn two_helps() {
let s = &String::new();
let x: &str = &*s;
+ //~^ ERROR: deref on an immutable reference
+ //~| NOTE: `-D clippy::borrow-deref-ref` implied by `-D warnings`
}
}
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr
index 738b01e7e..2a21f5ca2 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr
@@ -1,10 +1,11 @@
error: deref on an immutable reference
- --> $DIR/borrow_deref_ref_unfixable.rs:8:23
+ --> $DIR/borrow_deref_ref_unfixable.rs:9:23
|
LL | let x: &str = &*s;
| ^^^
|
= note: `-D clippy::borrow-deref-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]`
help: if you would like to reborrow, try removing `&*`
|
LL | let x: &str = s;
diff --git a/src/tools/clippy/tests/ui/box_collection.rs b/src/tools/clippy/tests/ui/box_collection.rs
index 4c9947b9a..499625ea9 100644
--- a/src/tools/clippy/tests/ui/box_collection.rs
+++ b/src/tools/clippy/tests/ui/box_collection.rs
@@ -19,6 +19,7 @@ fn test_macro() {
}
fn test1(foo: Box<Vec<bool>>) {}
+//~^ ERROR: you seem to be trying to use `Box<Vec<..>>`. Consider using just `Vec<..>`
fn test2(foo: Box<dyn Fn(Vec<u32>)>) {
// pass if #31 is fixed
@@ -26,20 +27,28 @@ fn test2(foo: Box<dyn Fn(Vec<u32>)>) {
}
fn test3(foo: Box<String>) {}
+//~^ ERROR: you seem to be trying to use `Box<String>`. Consider using just `String`
fn test4(foo: Box<HashMap<String, String>>) {}
+//~^ ERROR: you seem to be trying to use `Box<HashMap<..>>`. Consider using just `HashMap<
fn test5(foo: Box<HashSet<i64>>) {}
+//~^ ERROR: you seem to be trying to use `Box<HashSet<..>>`. Consider using just `HashSet<
fn test6(foo: Box<VecDeque<i32>>) {}
+//~^ ERROR: you seem to be trying to use `Box<VecDeque<..>>`. Consider using just `VecDequ
fn test7(foo: Box<LinkedList<i16>>) {}
+//~^ ERROR: you seem to be trying to use `Box<LinkedList<..>>`. Consider using just `Linke
fn test8(foo: Box<BTreeMap<i8, String>>) {}
+//~^ ERROR: you seem to be trying to use `Box<BTreeMap<..>>`. Consider using just `BTreeMa
fn test9(foo: Box<BTreeSet<u64>>) {}
+//~^ ERROR: you seem to be trying to use `Box<BTreeSet<..>>`. Consider using just `BTreeSe
fn test10(foo: Box<BinaryHeap<u32>>) {}
+//~^ ERROR: you seem to be trying to use `Box<BinaryHeap<..>>`. Consider using just `Binar
fn test_local_not_linted() {
let _: Box<Vec<bool>>;
diff --git a/src/tools/clippy/tests/ui/box_collection.stderr b/src/tools/clippy/tests/ui/box_collection.stderr
index 40b6f9be6..1ae7c2a05 100644
--- a/src/tools/clippy/tests/ui/box_collection.stderr
+++ b/src/tools/clippy/tests/ui/box_collection.stderr
@@ -6,9 +6,10 @@ LL | fn test1(foo: Box<Vec<bool>>) {}
|
= help: `Vec<..>` is already on the heap, `Box<Vec<..>>` makes an extra allocation
= note: `-D clippy::box-collection` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::box_collection)]`
error: you seem to be trying to use `Box<String>`. Consider using just `String`
- --> $DIR/box_collection.rs:28:15
+ --> $DIR/box_collection.rs:29:15
|
LL | fn test3(foo: Box<String>) {}
| ^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | fn test3(foo: Box<String>) {}
= help: `String` is already on the heap, `Box<String>` makes an extra allocation
error: you seem to be trying to use `Box<HashMap<..>>`. Consider using just `HashMap<..>`
- --> $DIR/box_collection.rs:30:15
+ --> $DIR/box_collection.rs:32:15
|
LL | fn test4(foo: Box<HashMap<String, String>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | fn test4(foo: Box<HashMap<String, String>>) {}
= help: `HashMap<..>` is already on the heap, `Box<HashMap<..>>` makes an extra allocation
error: you seem to be trying to use `Box<HashSet<..>>`. Consider using just `HashSet<..>`
- --> $DIR/box_collection.rs:32:15
+ --> $DIR/box_collection.rs:35:15
|
LL | fn test5(foo: Box<HashSet<i64>>) {}
| ^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | fn test5(foo: Box<HashSet<i64>>) {}
= help: `HashSet<..>` is already on the heap, `Box<HashSet<..>>` makes an extra allocation
error: you seem to be trying to use `Box<VecDeque<..>>`. Consider using just `VecDeque<..>`
- --> $DIR/box_collection.rs:34:15
+ --> $DIR/box_collection.rs:38:15
|
LL | fn test6(foo: Box<VecDeque<i32>>) {}
| ^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | fn test6(foo: Box<VecDeque<i32>>) {}
= help: `VecDeque<..>` is already on the heap, `Box<VecDeque<..>>` makes an extra allocation
error: you seem to be trying to use `Box<LinkedList<..>>`. Consider using just `LinkedList<..>`
- --> $DIR/box_collection.rs:36:15
+ --> $DIR/box_collection.rs:41:15
|
LL | fn test7(foo: Box<LinkedList<i16>>) {}
| ^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | fn test7(foo: Box<LinkedList<i16>>) {}
= help: `LinkedList<..>` is already on the heap, `Box<LinkedList<..>>` makes an extra allocation
error: you seem to be trying to use `Box<BTreeMap<..>>`. Consider using just `BTreeMap<..>`
- --> $DIR/box_collection.rs:38:15
+ --> $DIR/box_collection.rs:44:15
|
LL | fn test8(foo: Box<BTreeMap<i8, String>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | fn test8(foo: Box<BTreeMap<i8, String>>) {}
= help: `BTreeMap<..>` is already on the heap, `Box<BTreeMap<..>>` makes an extra allocation
error: you seem to be trying to use `Box<BTreeSet<..>>`. Consider using just `BTreeSet<..>`
- --> $DIR/box_collection.rs:40:15
+ --> $DIR/box_collection.rs:47:15
|
LL | fn test9(foo: Box<BTreeSet<u64>>) {}
| ^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | fn test9(foo: Box<BTreeSet<u64>>) {}
= help: `BTreeSet<..>` is already on the heap, `Box<BTreeSet<..>>` makes an extra allocation
error: you seem to be trying to use `Box<BinaryHeap<..>>`. Consider using just `BinaryHeap<..>`
- --> $DIR/box_collection.rs:42:16
+ --> $DIR/box_collection.rs:50:16
|
LL | fn test10(foo: Box<BinaryHeap<u32>>) {}
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed
index 840902b53..69cabcb32 100644
--- a/src/tools/clippy/tests/ui/box_default.fixed
+++ b/src/tools/clippy/tests/ui/box_default.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::box_default)]
#![allow(clippy::default_constructed_unit_structs)]
@@ -37,7 +36,7 @@ fn main() {
issue_10381();
// `Box::<Option<_>>::default()` would be valid here, but not `Box::default()` or
- // `Box::<Option<[closure@...]>::default()`
+ // `Box::<Option<{closure@...}>::default()`
//
// Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563
let mut unnameable = Box::new(Option::default());
diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs
index 3618486a4..48fa8bc33 100644
--- a/src/tools/clippy/tests/ui/box_default.rs
+++ b/src/tools/clippy/tests/ui/box_default.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::box_default)]
#![allow(clippy::default_constructed_unit_structs)]
@@ -37,7 +36,7 @@ fn main() {
issue_10381();
// `Box::<Option<_>>::default()` would be valid here, but not `Box::default()` or
- // `Box::<Option<[closure@...]>::default()`
+ // `Box::<Option<{closure@...}>::default()`
//
// Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563
let mut unnameable = Box::new(Option::default());
diff --git a/src/tools/clippy/tests/ui/box_default.stderr b/src/tools/clippy/tests/ui/box_default.stderr
index 13dfc5ae4..004550c6c 100644
--- a/src/tools/clippy/tests/ui/box_default.stderr
+++ b/src/tools/clippy/tests/ui/box_default.stderr
@@ -1,97 +1,98 @@
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:23:32
+ --> $DIR/box_default.rs:22:32
|
LL | let _string: Box<String> = Box::new(Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
|
= note: `-D clippy::box-default` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::box_default)]`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:24:17
+ --> $DIR/box_default.rs:23:17
|
LL | let _byte = Box::new(u8::default());
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<u8>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:25:16
+ --> $DIR/box_default.rs:24:16
|
LL | let _vec = Box::new(Vec::<u8>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Vec<u8>>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:26:17
+ --> $DIR/box_default.rs:25:17
|
LL | let _impl = Box::new(ImplementsDefault::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:27:18
+ --> $DIR/box_default.rs:26:18
|
LL | let _impl2 = Box::new(<ImplementsDefault as Default>::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:28:42
+ --> $DIR/box_default.rs:27:42
|
LL | let _impl3: Box<ImplementsDefault> = Box::new(Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:30:28
+ --> $DIR/box_default.rs:29:28
|
LL | let _in_macro = outer!(Box::new(String::new()));
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<String>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:31:34
+ --> $DIR/box_default.rs:30:34
|
LL | let _string_default = outer!(Box::new(String::from("")));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<String>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:32:46
+ --> $DIR/box_default.rs:31:46
|
LL | let _vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);
| ^^^^^^^^^^^^^^^^ help: try: `Box::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:33:33
+ --> $DIR/box_default.rs:32:33
|
LL | let _vec3: Box<Vec<bool>> = Box::new(Vec::from([]));
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:34:25
+ --> $DIR/box_default.rs:33:25
|
LL | let _vec4: Box<_> = Box::new(Vec::from([false; 0]));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Vec<bool>>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:36:16
+ --> $DIR/box_default.rs:35:16
|
LL | call_ty_fn(Box::new(u8::default()));
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:48:5
+ --> $DIR/box_default.rs:47:5
|
LL | Box::new(bool::default())
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<bool>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:65:28
+ --> $DIR/box_default.rs:64:28
|
LL | let _: Box<dyn Read> = Box::new(ImplementsDefault::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:74:17
+ --> $DIR/box_default.rs:73:17
|
LL | let _ = Box::new(WeirdPathed::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<WeirdPathed>::default()`
error: `Box::new(_)` of default value
- --> $DIR/box_default.rs:86:18
+ --> $DIR/box_default.rs:85:18
|
LL | Some(Box::new(Foo::default()))
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Foo>::default()`
diff --git a/src/tools/clippy/tests/ui/boxed_local.rs b/src/tools/clippy/tests/ui/boxed_local.rs
index 79b6d33fc..e888154c4 100644
--- a/src/tools/clippy/tests/ui/boxed_local.rs
+++ b/src/tools/clippy/tests/ui/boxed_local.rs
@@ -38,6 +38,8 @@ fn warn_call() {
}
fn warn_arg(x: Box<A>) {
+ //~^ ERROR: local variable doesn't need to be boxed here
+ //~| NOTE: `-D clippy::boxed-local` implied by `-D warnings`
x.foo();
}
@@ -119,6 +121,7 @@ pub struct PeekableSeekable<I: Foo> {
}
pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
+//~^ ERROR: local variable doesn't need to be boxed here
/// Regression for #916, #1123
///
@@ -183,6 +186,7 @@ mod issue4804 {
// warn on `x: Box<u32>`
fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {
+ //~^ ERROR: local variable doesn't need to be boxed here
4
}
}
@@ -190,6 +194,7 @@ mod issue4804 {
trait WarnTrait {
// warn on `x: Box<u32>`
fn foo(x: Box<u32>) {}
+ //~^ ERROR: local variable doesn't need to be boxed here
}
}
diff --git a/src/tools/clippy/tests/ui/boxed_local.stderr b/src/tools/clippy/tests/ui/boxed_local.stderr
index 10d78fbc0..187cc8fa1 100644
--- a/src/tools/clippy/tests/ui/boxed_local.stderr
+++ b/src/tools/clippy/tests/ui/boxed_local.stderr
@@ -5,21 +5,22 @@ LL | fn warn_arg(x: Box<A>) {
| ^
|
= note: `-D clippy::boxed-local` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`
error: local variable doesn't need to be boxed here
- --> $DIR/boxed_local.rs:121:12
+ --> $DIR/boxed_local.rs:123:12
|
LL | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
| ^^^^^^^^^^^
error: local variable doesn't need to be boxed here
- --> $DIR/boxed_local.rs:185:44
+ --> $DIR/boxed_local.rs:188:44
|
LL | fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {
| ^
error: local variable doesn't need to be boxed here
- --> $DIR/boxed_local.rs:192:16
+ --> $DIR/boxed_local.rs:196:16
|
LL | fn foo(x: Box<u32>) {}
| ^
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs
index 6a63008b5..d102efa7a 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.rs
@@ -1,7 +1,7 @@
#![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
#![allow(dead_code)]
#![allow(clippy::equatable_if_let, clippy::uninlined_format_args)]
-
+//@no-rustfix
// This tests the branches_sharing_code lint at the end of blocks
fn simple_examples() {
@@ -29,6 +29,8 @@ fn simple_examples() {
// The rest is self contained and moveable => Only lint the rest
let result = false;
+ //~^ ERROR: all if blocks contain the same code at the end
+ //~| NOTE: the end suggestion probably needs some adjustments to use the expressio
println!("Block end!");
result
};
@@ -47,6 +49,7 @@ fn simple_examples() {
} else {
println!("This is also eq with the else block");
println!("Same end of block");
+ //~^ ERROR: all if blocks contain the same code at the end
}
// Use of outer scope value
@@ -64,6 +67,7 @@ fn simple_examples() {
println!("I'm a local because I use the value `z`: `{}`", z);
println!(
+ //~^ ERROR: all if blocks contain the same code at the end
"I'm moveable because I know: `outer_scope_value`: '{}'",
outer_scope_value
);
@@ -76,6 +80,7 @@ fn simple_examples() {
println!("Hello World");
} else {
println!("Hello World");
+ //~^ ERROR: all if blocks contain the same code at the end
}
}
}
@@ -92,6 +97,7 @@ fn simple_but_suggestion_is_invalid() {
println!("{}", later_used_value);
} else {
let later_used_value = "A string value";
+ //~^ ERROR: all if blocks contain the same code at the end
println!("{}", later_used_value);
// I'm expecting a note about this
}
@@ -105,6 +111,7 @@ fn simple_but_suggestion_is_invalid() {
println!("Separator print statement");
let simple_examples = "I now identify as a &str :)";
+ //~^ ERROR: all if blocks contain the same code at the end
println!("This is the new simple_example: {}", simple_examples);
}
simple_examples();
@@ -170,6 +177,8 @@ fn added_note_for_expression_use() -> u32 {
} else {
let _ = 6;
x << 2
+ //~^ ERROR: all if blocks contain the same code at the end
+ //~| NOTE: the end suggestion probably needs some adjustments to use the expressio
};
if x == 9 {
@@ -177,6 +186,8 @@ fn added_note_for_expression_use() -> u32 {
} else {
let _ = 17;
x * 4
+ //~^ ERROR: all if blocks contain the same code at the end
+ //~| NOTE: the end suggestion probably needs some adjustments to use the expressio
}
}
@@ -189,6 +200,7 @@ fn test_suggestion_with_weird_formatting() {
// The error message still looks weird tbh but this is the best I can do
// for weird formatting
if x == 17 { b = 1; a = 0x99; } else { a = 0x99; }
+ //~^ ERROR: all if blocks contain the same code at the end
}
fn fp_test() {
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
index b9b113dc0..d00717bef 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
@@ -2,6 +2,8 @@ error: all if blocks contain the same code at the end
--> $DIR/shared_at_bottom.rs:31:5
|
LL | / let result = false;
+LL | |
+LL | |
LL | | println!("Block end!");
LL | | result
LL | | };
@@ -17,14 +19,17 @@ help: consider moving these statements after the if
|
LL ~ }
LL + let result = false;
+LL +
+LL +
LL + println!("Block end!");
LL ~ result;
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:49:5
+ --> $DIR/shared_at_bottom.rs:51:5
|
LL | / println!("Same end of block");
+LL | |
LL | | }
| |_____^
|
@@ -35,9 +40,10 @@ LL + println!("Same end of block");
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:66:5
+ --> $DIR/shared_at_bottom.rs:69:5
|
LL | / println!(
+LL | |
LL | | "I'm moveable because I know: `outer_scope_value`: '{}'",
LL | | outer_scope_value
LL | | );
@@ -48,15 +54,17 @@ help: consider moving these statements after the if
|
LL ~ }
LL + println!(
+LL +
LL + "I'm moveable because I know: `outer_scope_value`: '{}'",
LL + outer_scope_value
LL + );
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:78:9
+ --> $DIR/shared_at_bottom.rs:82:9
|
LL | / println!("Hello World");
+LL | |
LL | | }
| |_________^
|
@@ -67,9 +75,10 @@ LL + println!("Hello World");
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:94:5
+ --> $DIR/shared_at_bottom.rs:99:5
|
LL | / let later_used_value = "A string value";
+LL | |
LL | | println!("{}", later_used_value);
LL | | // I'm expecting a note about this
LL | | }
@@ -80,13 +89,15 @@ help: consider moving these statements after the if
|
LL ~ }
LL + let later_used_value = "A string value";
+LL +
LL + println!("{}", later_used_value);
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:107:5
+ --> $DIR/shared_at_bottom.rs:113:5
|
LL | / let simple_examples = "I now identify as a &str :)";
+LL | |
LL | | println!("This is the new simple_example: {}", simple_examples);
LL | | }
| |_____^
@@ -96,13 +107,16 @@ help: consider moving these statements after the if
|
LL ~ }
LL + let simple_examples = "I now identify as a &str :)";
+LL +
LL + println!("This is the new simple_example: {}", simple_examples);
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:172:5
+ --> $DIR/shared_at_bottom.rs:179:5
|
LL | / x << 2
+LL | |
+LL | |
LL | | };
| |_____^
|
@@ -114,9 +128,11 @@ LL ~ x << 2;
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:179:5
+ --> $DIR/shared_at_bottom.rs:188:5
|
LL | / x * 4
+LL | |
+LL | |
LL | | }
| |_____^
|
@@ -128,7 +144,7 @@ LL + x * 4
|
error: all if blocks contain the same code at the end
- --> $DIR/shared_at_bottom.rs:191:44
+ --> $DIR/shared_at_bottom.rs:202:44
|
LL | if x == 17 { b = 1; a = 0x99; } else { a = 0x99; }
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs
index 9e0b99f16..44f8b2eab 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs
@@ -1,7 +1,7 @@
#![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]
#![allow(dead_code)]
#![allow(clippy::mixed_read_write_in_expression, clippy::uninlined_format_args)]
-
+//@no-rustfix
// This tests the branches_sharing_code lint at the start of blocks
fn simple_examples() {
@@ -9,6 +9,7 @@ fn simple_examples() {
// Simple
if true {
+ //~^ ERROR: all if blocks contain the same code at the start
println!("Hello World!");
println!("I'm branch nr: 1");
} else {
@@ -18,6 +19,7 @@ fn simple_examples() {
// Else if
if x == 0 {
+ //~^ ERROR: all if blocks contain the same code at the start
let y = 9;
println!("The value y was set to: `{}`", y);
let _z = y;
@@ -39,6 +41,7 @@ fn simple_examples() {
// Return a value
let _ = if x == 7 {
+ //~^ ERROR: all if blocks contain the same code at the start
let y = 16;
println!("What can I say except: \"you're welcome?\"");
let _ = y;
@@ -57,6 +60,7 @@ fn simple_but_suggestion_is_invalid() {
// Can't be automatically moved because used_value_name is getting used again
let used_value_name = 19;
if x == 10 {
+ //~^ ERROR: all if blocks contain the same code at the start
let used_value_name = "Different type";
println!("Str: {}", used_value_name);
let _ = 1;
@@ -71,6 +75,7 @@ fn simple_but_suggestion_is_invalid() {
let can_be_overridden = 8;
let _ = can_be_overridden;
if x == 11 {
+ //~^ ERROR: all if blocks contain the same code at the start
let can_be_overridden = "Move me";
println!("I'm also moveable");
let _ = 111;
@@ -87,6 +92,7 @@ fn check_if_same_than_else_mask() {
#[allow(clippy::if_same_then_else)]
if x == 2020 {
+ //~^ ERROR: all if blocks contain the same code at the start
println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.");
println!("Because `IF_SAME_THEN_ELSE` is allowed here");
} else {
@@ -95,6 +101,7 @@ fn check_if_same_than_else_mask() {
}
if x == 2019 {
+ //~^ ERROR: this `if` has identical blocks
println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
} else {
println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr
index 3e3242a75..9d4d42fb6 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr
@@ -2,6 +2,7 @@ error: all if blocks contain the same code at the start
--> $DIR/shared_at_top.rs:11:5
|
LL | / if true {
+LL | |
LL | | println!("Hello World!");
| |_________________________________^
|
@@ -17,9 +18,10 @@ LL + if true {
|
error: all if blocks contain the same code at the start
- --> $DIR/shared_at_top.rs:20:5
+ --> $DIR/shared_at_top.rs:21:5
|
LL | / if x == 0 {
+LL | |
LL | | let y = 9;
LL | | println!("The value y was set to: `{}`", y);
LL | | let _z = y;
@@ -35,9 +37,10 @@ LL + if x == 0 {
|
error: all if blocks contain the same code at the start
- --> $DIR/shared_at_top.rs:41:5
+ --> $DIR/shared_at_top.rs:43:5
|
LL | / let _ = if x == 7 {
+LL | |
LL | | let y = 16;
| |___________________^
|
@@ -48,9 +51,10 @@ LL + let _ = if x == 7 {
|
error: all if blocks contain the same code at the start
- --> $DIR/shared_at_top.rs:59:5
+ --> $DIR/shared_at_top.rs:62:5
|
LL | / if x == 10 {
+LL | |
LL | | let used_value_name = "Different type";
LL | | println!("Str: {}", used_value_name);
| |_____________________________________________^
@@ -64,9 +68,10 @@ LL + if x == 10 {
|
error: all if blocks contain the same code at the start
- --> $DIR/shared_at_top.rs:73:5
+ --> $DIR/shared_at_top.rs:77:5
|
LL | / if x == 11 {
+LL | |
LL | | let can_be_overridden = "Move me";
LL | | println!("I'm also moveable");
| |______________________________________^
@@ -80,9 +85,10 @@ LL + if x == 11 {
|
error: all if blocks contain the same code at the start
- --> $DIR/shared_at_top.rs:89:5
+ --> $DIR/shared_at_top.rs:94:5
|
LL | / if x == 2020 {
+LL | |
LL | | println!("This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.");
LL | | println!("Because `IF_SAME_THEN_ELSE` is allowed here");
| |________________________________________________________________^
@@ -95,16 +101,17 @@ LL + if x == 2020 {
|
error: this `if` has identical blocks
- --> $DIR/shared_at_top.rs:97:18
+ --> $DIR/shared_at_top.rs:103:18
|
LL | if x == 2019 {
| __________________^
+LL | |
LL | | println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
LL | | } else {
| |_____^
|
note: same as this
- --> $DIR/shared_at_top.rs:99:12
+ --> $DIR/shared_at_top.rs:106:12
|
LL | } else {
| ____________^
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs
index 93b8c6e10..36620ee1a 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs
@@ -1,7 +1,7 @@
#![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]
#![allow(dead_code)]
#![allow(clippy::uninlined_format_args)]
-
+//@no-rustfix
// branches_sharing_code at the top and bottom of the if blocks
struct DataPack {
@@ -15,6 +15,7 @@ fn overlapping_eq_regions() {
// Overlap with separator
if x == 7 {
+ //~^ ERROR: all if blocks contain the same code at both the start and the end
let t = 7;
let _overlap_start = t * 2;
let _overlap_end = 2 * t;
@@ -31,6 +32,7 @@ fn overlapping_eq_regions() {
// Overlap with separator
if x == 99 {
+ //~^ ERROR: all if blocks contain the same code at both the start and the end
let r = 7;
let _overlap_start = r;
let _overlap_middle = r * r;
@@ -60,6 +62,7 @@ fn complexer_example() {
let x = 8;
let y = 9;
if (x > 7 && y < 13) || (x + y) % 2 == 1 {
+ //~^ ERROR: all if blocks contain the same code at both the start and the end
let a = 0xcafe;
let b = 0xffff00ff;
let e_id = gen_id(a, b);
@@ -93,6 +96,7 @@ fn added_note_for_expression_use() -> u32 {
let x = 9;
let _ = if x == 7 {
+ //~^ ERROR: all if blocks contain the same code at both the start and the end
let _ = 19;
let _splitter = 6;
@@ -105,6 +109,7 @@ fn added_note_for_expression_use() -> u32 {
};
if x == 9 {
+ //~^ ERROR: all if blocks contain the same code at both the start and the end
let _ = 17;
let _splitter = 6;
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
index ccd697a42..74495fca8 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
@@ -2,13 +2,14 @@ error: all if blocks contain the same code at both the start and the end
--> $DIR/shared_at_top_and_bottom.rs:17:5
|
LL | / if x == 7 {
+LL | |
LL | | let t = 7;
LL | | let _overlap_start = t * 2;
LL | | let _overlap_end = 2 * t;
| |_________________________________^
|
note: this code is shared at the end
- --> $DIR/shared_at_top_and_bottom.rs:29:5
+ --> $DIR/shared_at_top_and_bottom.rs:30:5
|
LL | / let _u = 9;
LL | | }
@@ -32,16 +33,17 @@ LL + let _u = 9;
|
error: all if blocks contain the same code at both the start and the end
- --> $DIR/shared_at_top_and_bottom.rs:33:5
+ --> $DIR/shared_at_top_and_bottom.rs:34:5
|
LL | / if x == 99 {
+LL | |
LL | | let r = 7;
LL | | let _overlap_start = r;
LL | | let _overlap_middle = r * r;
| |____________________________________^
|
note: this code is shared at the end
- --> $DIR/shared_at_top_and_bottom.rs:44:5
+ --> $DIR/shared_at_top_and_bottom.rs:46:5
|
LL | / let _overlap_end = r * r * r;
LL | | let z = "end";
@@ -63,16 +65,17 @@ LL + let z = "end";
|
error: all if blocks contain the same code at both the start and the end
- --> $DIR/shared_at_top_and_bottom.rs:62:5
+ --> $DIR/shared_at_top_and_bottom.rs:64:5
|
LL | / if (x > 7 && y < 13) || (x + y) % 2 == 1 {
+LL | |
LL | | let a = 0xcafe;
LL | | let b = 0xffff00ff;
LL | | let e_id = gen_id(a, b);
| |________________________________^
|
note: this code is shared at the end
- --> $DIR/shared_at_top_and_bottom.rs:82:5
+ --> $DIR/shared_at_top_and_bottom.rs:85:5
|
LL | / let pack = DataPack {
LL | | id: e_id,
@@ -102,14 +105,15 @@ LL + process_data(pack);
|
error: all if blocks contain the same code at both the start and the end
- --> $DIR/shared_at_top_and_bottom.rs:95:5
+ --> $DIR/shared_at_top_and_bottom.rs:98:5
|
LL | / let _ = if x == 7 {
+LL | |
LL | | let _ = 19;
| |___________________^
|
note: this code is shared at the end
- --> $DIR/shared_at_top_and_bottom.rs:104:5
+ --> $DIR/shared_at_top_and_bottom.rs:108:5
|
LL | / x << 2
LL | | };
@@ -127,14 +131,15 @@ LL ~ x << 2;
|
error: all if blocks contain the same code at both the start and the end
- --> $DIR/shared_at_top_and_bottom.rs:107:5
+ --> $DIR/shared_at_top_and_bottom.rs:111:5
|
LL | / if x == 9 {
+LL | |
LL | | let _ = 17;
| |___________________^
|
note: this code is shared at the end
- --> $DIR/shared_at_top_and_bottom.rs:116:5
+ --> $DIR/shared_at_top_and_bottom.rs:121:5
|
LL | / x * 4
LL | | }
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs
index 5780ea089..2aeacb89c 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs
@@ -107,6 +107,7 @@ fn valid_examples() {
// Let's test empty blocks
if false {
+ //~^ ERROR: this `if` has identical blocks
} else {
}
}
@@ -118,6 +119,7 @@ fn trigger_other_lint() {
// Same block
if x == 0 {
+ //~^ ERROR: this `if` has identical blocks
let u = 19;
println!("How are u today?");
let _ = "This is a string";
@@ -129,12 +131,14 @@ fn trigger_other_lint() {
// Only same expression
let _ = if x == 6 { 7 } else { 7 };
+ //~^ ERROR: this `if` has identical blocks
// Same in else if block
let _ = if x == 67 {
println!("Well I'm the most important block");
"I'm a pretty string"
} else if x == 68 {
+ //~^ ERROR: this `if` has identical blocks
println!("I'm a doppelgänger");
// Don't listen to my clone below
@@ -149,6 +153,7 @@ fn trigger_other_lint() {
if x == 0 {
println!("I'm single");
} else if x == 68 {
+ //~^ ERROR: this `if` has identical blocks
println!("I'm a doppelgänger");
// Don't listen to my clone below
} else {
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr
index a7e72b780..fcbf12235 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr
@@ -3,11 +3,12 @@ error: this `if` has identical blocks
|
LL | if false {
| ______________^
+LL | |
LL | | } else {
| |_____^
|
note: same as this
- --> $DIR/valid_if_blocks.rs:110:12
+ --> $DIR/valid_if_blocks.rs:111:12
|
LL | } else {
| ____________^
@@ -20,10 +21,11 @@ LL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `if` has identical blocks
- --> $DIR/valid_if_blocks.rs:120:15
+ --> $DIR/valid_if_blocks.rs:121:15
|
LL | if x == 0 {
| _______________^
+LL | |
LL | | let u = 19;
LL | | println!("How are u today?");
LL | | let _ = "This is a string";
@@ -31,7 +33,7 @@ LL | | } else {
| |_____^
|
note: same as this
- --> $DIR/valid_if_blocks.rs:124:12
+ --> $DIR/valid_if_blocks.rs:126:12
|
LL | } else {
| ____________^
@@ -42,22 +44,23 @@ LL | | }
| |_____^
error: this `if` has identical blocks
- --> $DIR/valid_if_blocks.rs:131:23
+ --> $DIR/valid_if_blocks.rs:133:23
|
LL | let _ = if x == 6 { 7 } else { 7 };
| ^^^^^
|
note: same as this
- --> $DIR/valid_if_blocks.rs:131:34
+ --> $DIR/valid_if_blocks.rs:133:34
|
LL | let _ = if x == 6 { 7 } else { 7 };
| ^^^^^
error: this `if` has identical blocks
- --> $DIR/valid_if_blocks.rs:137:23
+ --> $DIR/valid_if_blocks.rs:140:23
|
LL | } else if x == 68 {
| _______________________^
+LL | |
LL | | println!("I'm a doppelgänger");
LL | | // Don't listen to my clone below
LL | |
@@ -66,7 +69,7 @@ LL | | } else {
| |_____^
|
note: same as this
- --> $DIR/valid_if_blocks.rs:142:12
+ --> $DIR/valid_if_blocks.rs:146:12
|
LL | } else {
| ____________^
@@ -78,17 +81,18 @@ LL | | };
| |_____^
error: this `if` has identical blocks
- --> $DIR/valid_if_blocks.rs:151:23
+ --> $DIR/valid_if_blocks.rs:155:23
|
LL | } else if x == 68 {
| _______________________^
+LL | |
LL | | println!("I'm a doppelgänger");
LL | | // Don't listen to my clone below
LL | | } else {
| |_____^
|
note: same as this
- --> $DIR/valid_if_blocks.rs:154:12
+ --> $DIR/valid_if_blocks.rs:159:12
|
LL | } else {
| ____________^
diff --git a/src/tools/clippy/tests/ui/builtin_type_shadow.stderr b/src/tools/clippy/tests/ui/builtin_type_shadow.stderr
index 47a8a1e62..cb8462182 100644
--- a/src/tools/clippy/tests/ui/builtin_type_shadow.stderr
+++ b/src/tools/clippy/tests/ui/builtin_type_shadow.stderr
@@ -5,6 +5,7 @@ LL | fn foo<u32>(a: u32) -> u32 {
| ^^^
|
= note: `-D clippy::builtin-type-shadow` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::builtin_type_shadow)]`
error[E0308]: mismatched types
--> $DIR/builtin_type_shadow.rs:5:5
diff --git a/src/tools/clippy/tests/ui/bytecount.rs b/src/tools/clippy/tests/ui/bytecount.rs
index 4d168bfea..3794fc5d4 100644
--- a/src/tools/clippy/tests/ui/bytecount.rs
+++ b/src/tools/clippy/tests/ui/bytecount.rs
@@ -1,26 +1,39 @@
+//@no-rustfix
+
#![allow(clippy::needless_borrow, clippy::useless_vec)]
#[deny(clippy::naive_bytecount)]
fn main() {
let x = vec![0_u8; 16];
- let _ = x.iter().filter(|&&a| a == 0).count(); // naive byte count
+ // naive byte count
+ let _ = x.iter().filter(|&&a| a == 0).count();
+ //~^ ERROR: you appear to be counting bytes the naive way
- let _ = (&x[..]).iter().filter(|&a| *a == 0).count(); // naive byte count
+ // naive byte count
+ let _ = (&x[..]).iter().filter(|&a| *a == 0).count();
+ //~^ ERROR: you appear to be counting bytes the naive way
- let _ = x.iter().filter(|a| **a > 0).count(); // not an equality count, OK.
+ // not an equality count, OK.
+ let _ = x.iter().filter(|a| **a > 0).count();
- let _ = x.iter().map(|a| a + 1).filter(|&a| a < 15).count(); // not a slice
+ // not a slice
+ let _ = x.iter().map(|a| a + 1).filter(|&a| a < 15).count();
let b = 0;
- let _ = x.iter().filter(|_| b > 0).count(); // woah there
+ // woah there
+ let _ = x.iter().filter(|_| b > 0).count();
- let _ = x.iter().filter(|_a| b == b + 1).count(); // nothing to see here, move along
+ // nothing to see here, move along
+ let _ = x.iter().filter(|_a| b == b + 1).count();
- let _ = x.iter().filter(|a| b + 1 == **a).count(); // naive byte count
+ // naive byte count
+ let _ = x.iter().filter(|a| b + 1 == **a).count();
+ //~^ ERROR: you appear to be counting bytes the naive way
let y = vec![0_u16; 3];
- let _ = y.iter().filter(|&&a| a == 0).count(); // naive count, but not bytes
+ // naive count, but not bytes
+ let _ = y.iter().filter(|&&a| a == 0).count();
}
diff --git a/src/tools/clippy/tests/ui/bytecount.stderr b/src/tools/clippy/tests/ui/bytecount.stderr
index 68d838c1f..39007f9d1 100644
--- a/src/tools/clippy/tests/ui/bytecount.stderr
+++ b/src/tools/clippy/tests/ui/bytecount.stderr
@@ -1,25 +1,25 @@
error: you appear to be counting bytes the naive way
- --> $DIR/bytecount.rs:7:13
+ --> $DIR/bytecount.rs:10:13
|
-LL | let _ = x.iter().filter(|&&a| a == 0).count(); // naive byte count
+LL | let _ = x.iter().filter(|&&a| a == 0).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, 0)`
|
note: the lint level is defined here
- --> $DIR/bytecount.rs:3:8
+ --> $DIR/bytecount.rs:5:8
|
LL | #[deny(clippy::naive_bytecount)]
| ^^^^^^^^^^^^^^^^^^^^^^^
error: you appear to be counting bytes the naive way
- --> $DIR/bytecount.rs:9:13
+ --> $DIR/bytecount.rs:14:13
|
-LL | let _ = (&x[..]).iter().filter(|&a| *a == 0).count(); // naive byte count
+LL | let _ = (&x[..]).iter().filter(|&a| *a == 0).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count((&x[..]), 0)`
error: you appear to be counting bytes the naive way
- --> $DIR/bytecount.rs:21:13
+ --> $DIR/bytecount.rs:32:13
|
-LL | let _ = x.iter().filter(|a| b + 1 == **a).count(); // naive byte count
+LL | let _ = x.iter().filter(|a| b + 1 == **a).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, b + 1)`
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.fixed b/src/tools/clippy/tests/ui/bytes_count_to_len.fixed
index fb3d521ba..d20af2253 100644
--- a/src/tools/clippy/tests/ui/bytes_count_to_len.fixed
+++ b/src/tools/clippy/tests/ui/bytes_count_to_len.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::bytes_count_to_len)]
use std::fs::File;
use std::io::Read;
diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.rs b/src/tools/clippy/tests/ui/bytes_count_to_len.rs
index 8e256b8f0..340e6b412 100644
--- a/src/tools/clippy/tests/ui/bytes_count_to_len.rs
+++ b/src/tools/clippy/tests/ui/bytes_count_to_len.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::bytes_count_to_len)]
use std::fs::File;
use std::io::Read;
diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.stderr b/src/tools/clippy/tests/ui/bytes_count_to_len.stderr
index 224deb779..db0bb4099 100644
--- a/src/tools/clippy/tests/ui/bytes_count_to_len.stderr
+++ b/src/tools/clippy/tests/ui/bytes_count_to_len.stderr
@@ -1,25 +1,26 @@
error: using long and hard to read `.bytes().count()`
- --> $DIR/bytes_count_to_len.rs:8:13
+ --> $DIR/bytes_count_to_len.rs:7:13
|
LL | let _ = String::from("foo").bytes().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `String::from("foo").len()`
|
= note: `-D clippy::bytes-count-to-len` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::bytes_count_to_len)]`
error: using long and hard to read `.bytes().count()`
- --> $DIR/bytes_count_to_len.rs:11:13
+ --> $DIR/bytes_count_to_len.rs:10:13
|
LL | let _ = s1.bytes().count();
| ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s1.len()`
error: using long and hard to read `.bytes().count()`
- --> $DIR/bytes_count_to_len.rs:14:13
+ --> $DIR/bytes_count_to_len.rs:13:13
|
LL | let _ = "foo".bytes().count();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `"foo".len()`
error: using long and hard to read `.bytes().count()`
- --> $DIR/bytes_count_to_len.rs:17:13
+ --> $DIR/bytes_count_to_len.rs:16:13
|
LL | let _ = s2.bytes().count();
| ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s2.len()`
diff --git a/src/tools/clippy/tests/ui/bytes_nth.fixed b/src/tools/clippy/tests/ui/bytes_nth.fixed
index d3e0f676b..11deb2390 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.fixed
+++ b/src/tools/clippy/tests/ui/bytes_nth.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::unnecessary_operation)]
#![warn(clippy::bytes_nth)]
diff --git a/src/tools/clippy/tests/ui/bytes_nth.rs b/src/tools/clippy/tests/ui/bytes_nth.rs
index b7d813fe2..62d9c7a5e 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.rs
+++ b/src/tools/clippy/tests/ui/bytes_nth.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::unnecessary_operation)]
#![warn(clippy::bytes_nth)]
diff --git a/src/tools/clippy/tests/ui/bytes_nth.stderr b/src/tools/clippy/tests/ui/bytes_nth.stderr
index e8b150278..574bfaac1 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.stderr
+++ b/src/tools/clippy/tests/ui/bytes_nth.stderr
@@ -1,19 +1,20 @@
error: called `.bytes().nth()` on a `String`
- --> $DIR/bytes_nth.rs:8:13
+ --> $DIR/bytes_nth.rs:6:13
|
LL | let _ = s.bytes().nth(3);
| ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3).copied()`
|
= note: `-D clippy::bytes-nth` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::bytes_nth)]`
error: called `.bytes().nth().unwrap()` on a `String`
- --> $DIR/bytes_nth.rs:9:14
+ --> $DIR/bytes_nth.rs:7:14
|
LL | let _ = &s.bytes().nth(3).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.as_bytes()[3]`
error: called `.bytes().nth()` on a `str`
- --> $DIR/bytes_nth.rs:10:13
+ --> $DIR/bytes_nth.rs:8:13
|
LL | let _ = s[..].bytes().nth(3);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3).copied()`
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed
index d5af22aef..a816224c9 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::case_sensitive_file_extension_comparisons)]
use std::string::String;
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
index f5f0a0022..994de2805 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::case_sensitive_file_extension_comparisons)]
use std::string::String;
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
index 44c8e3fdf..49c840bd7 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
@@ -1,11 +1,12 @@
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:14:5
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:13:5
|
LL | filename.ends_with(".rs")
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider using a case-insensitive comparison instead
= note: `-D clippy::case-sensitive-file-extension-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::case_sensitive_file_extension_comparisons)]`
help: use std::path::Path
|
LL ~ std::path::Path::new(filename)
@@ -14,7 +15,7 @@ LL + .map_or(false, |ext| ext.eq_ignore_ascii_case("rs"))
|
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:19:13
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:18:13
|
LL | let _ = String::new().ends_with(".ext12");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -28,7 +29,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12"));
|
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:20:13
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:19:13
|
LL | let _ = "str".ends_with(".ext12");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +43,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12"));
|
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:24:17
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:23:17
|
LL | let _ = "str".ends_with(".ext12");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12"));
|
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:31:13
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:30:13
|
LL | let _ = String::new().ends_with(".EXT12");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +71,7 @@ LL ~ .map_or(false, |ext| ext.eq_ignore_ascii_case("EXT12"));
|
error: case-sensitive file extension comparison
- --> $DIR/case_sensitive_file_extension_comparisons.rs:32:13
+ --> $DIR/case_sensitive_file_extension_comparisons.rs:31:13
|
LL | let _ = "str".ends_with(".EXT12");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index 60a0eabf5..1ca18170f 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -1,3 +1,5 @@
+//@no-rustfix
+
#![feature(repr128)]
#![allow(incomplete_features)]
#![warn(
@@ -12,48 +14,101 @@ fn main() {
// Test clippy::cast_precision_loss
let x0 = 1i32;
x0 as f32;
+ //~^ ERROR: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide,
+ //~| NOTE: `-D clippy::cast-precision-loss` implied by `-D warnings`
let x1 = 1i64;
x1 as f32;
+ //~^ ERROR: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide,
x1 as f64;
+ //~^ ERROR: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide,
let x2 = 1u32;
x2 as f32;
+ //~^ ERROR: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide,
let x3 = 1u64;
x3 as f32;
+ //~^ ERROR: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide,
x3 as f64;
+ //~^ ERROR: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide,
// Test clippy::cast_possible_truncation
1f32 as i32;
+ //~^ ERROR: casting `f32` to `i32` may truncate the value
1f32 as u32;
+ //~^ ERROR: casting `f32` to `u32` may truncate the value
+ //~| ERROR: casting `f32` to `u32` may lose the sign of the value
+ //~| NOTE: `-D clippy::cast-sign-loss` implied by `-D warnings`
1f64 as f32;
+ //~^ ERROR: casting `f64` to `f32` may truncate the value
1i32 as i8;
+ //~^ ERROR: casting `i32` to `i8` may truncate the value
1i32 as u8;
+ //~^ ERROR: casting `i32` to `u8` may truncate the value
1f64 as isize;
+ //~^ ERROR: casting `f64` to `isize` may truncate the value
1f64 as usize;
+ //~^ ERROR: casting `f64` to `usize` may truncate the value
+ //~| ERROR: casting `f64` to `usize` may lose the sign of the value
1f32 as u32 as u16;
+ //~^ ERROR: casting `u32` to `u16` may truncate the value
+ //~| ERROR: casting `f32` to `u32` may truncate the value
+ //~| ERROR: casting `f32` to `u32` may lose the sign of the value
{
let _x: i8 = 1i32 as _;
+ //~^ ERROR: casting `i32` to `i8` may truncate the value
1f32 as i32;
+ //~^ ERROR: casting `f32` to `i32` may truncate the value
1f64 as i32;
+ //~^ ERROR: casting `f64` to `i32` may truncate the value
1f32 as u8;
+ //~^ ERROR: casting `f32` to `u8` may truncate the value
+ //~| ERROR: casting `f32` to `u8` may lose the sign of the value
}
// Test clippy::cast_possible_wrap
1u8 as i8;
+ //~^ ERROR: casting `u8` to `i8` may wrap around the value
+ //~| NOTE: `-D clippy::cast-possible-wrap` implied by `-D warnings`
1u16 as i16;
+ //~^ ERROR: casting `u16` to `i16` may wrap around the value
1u32 as i32;
+ //~^ ERROR: casting `u32` to `i32` may wrap around the value
1u64 as i64;
+ //~^ ERROR: casting `u64` to `i64` may wrap around the value
1usize as isize;
- 1usize as i8; // should not wrap, usize is never 8 bits
- 1usize as i16; // wraps on 16 bit ptr size
- 1usize as i32; // wraps on 32 bit ptr size
- 1usize as i64; // wraps on 64 bit ptr size
- 1u8 as isize; // should not wrap, isize is never 8 bits
- 1u16 as isize; // wraps on 16 bit ptr size
- 1u32 as isize; // wraps on 32 bit ptr size
- 1u64 as isize; // wraps on 64 bit ptr size
+ //~^ ERROR: casting `usize` to `isize` may wrap around the value
+ // should not wrap, usize is never 8 bits
+ 1usize as i8;
+ //~^ ERROR: casting `usize` to `i8` may truncate the value
+ // wraps on 16 bit ptr size
+ 1usize as i16;
+ //~^ ERROR: casting `usize` to `i16` may truncate the value
+ //~| ERROR: casting `usize` to `i16` may wrap around the value on targets with 16-bit
+ //~| NOTE: `usize` and `isize` may be as small as 16 bits on some platforms
+ // wraps on 32 bit ptr size
+ 1usize as i32;
+ //~^ ERROR: casting `usize` to `i32` may truncate the value on targets with 64-bit wid
+ //~| ERROR: casting `usize` to `i32` may wrap around the value on targets with 32-bit
+ // wraps on 64 bit ptr size
+ 1usize as i64;
+ //~^ ERROR: casting `usize` to `i64` may wrap around the value on targets with 64-bit
+ // should not wrap, isize is never 8 bits
+ 1u8 as isize;
+ // wraps on 16 bit ptr size
+ 1u16 as isize;
+ //~^ ERROR: casting `u16` to `isize` may wrap around the value on targets with 16-bit
+ //~| NOTE: `usize` and `isize` may be as small as 16 bits on some platforms
+ // wraps on 32 bit ptr size
+ 1u32 as isize;
+ //~^ ERROR: casting `u32` to `isize` may wrap around the value on targets with 32-bit
+ // wraps on 64 bit ptr size
+ 1u64 as isize;
+ //~^ ERROR: casting `u64` to `isize` may truncate the value on targets with 32-bit wid
+ //~| ERROR: casting `u64` to `isize` may wrap around the value on targets with 64-bit
// Test clippy::cast_sign_loss
1i32 as u32;
-1i32 as u32;
+ //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
1isize as usize;
-1isize as usize;
+ //~^ ERROR: casting `isize` to `usize` may lose the sign of the value
0i8 as u8;
i8::MAX as u8;
i16::MAX as u16;
@@ -120,7 +175,9 @@ fn main() {
let _ = s as i32;
// Test for signed min
- (-99999999999i64).min(1) as i8; // should be linted because signed
+ // should be linted because signed
+ (-99999999999i64).min(1) as i8;
+ //~^ ERROR: casting `i64` to `i8` may truncate the value
// Test for various operations that remove enough bits for the result to fit
(999999u64 & 1) as u8;
@@ -132,7 +189,9 @@ fn main() {
x.min(1)
}) as u8;
999999u64.clamp(0, 255) as u8;
- 999999u64.clamp(0, 256) as u8; // should still be linted
+ // should still be linted
+ 999999u64.clamp(0, 256) as u8;
+ //~^ ERROR: casting `u64` to `u8` may truncate the value
#[derive(Clone, Copy)]
enum E1 {
@@ -142,7 +201,8 @@ fn main() {
}
impl E1 {
fn test(self) {
- let _ = self as u8; // Don't lint. `0..=2` fits in u8
+ // Don't lint. `0..=2` fits in u8
+ let _ = self as u8;
}
}
@@ -154,9 +214,14 @@ fn main() {
impl E2 {
fn test(self) {
let _ = self as u8;
+ //~^ ERROR: casting `main::E2` to `u8` may truncate the value
let _ = Self::B as u8;
- let _ = self as i16; // Don't lint. `255..=256` fits in i16
- let _ = Self::A as u8; // Don't lint.
+ //~^ ERROR: casting `main::E2::B` to `u8` will truncate the value
+ //~| NOTE: `-D clippy::cast-enum-truncation` implied by `-D warnings`
+ // Don't lint. `255..=256` fits in i16
+ let _ = self as i16;
+ // Don't lint.
+ let _ = Self::A as u8;
}
}
@@ -168,7 +233,8 @@ fn main() {
}
impl E3 {
fn test(self) {
- let _ = self as i8; // Don't lint. `-1..=50` fits in i8
+ // Don't lint. `-1..=50` fits in i8
+ let _ = self as i8;
}
}
@@ -179,7 +245,8 @@ fn main() {
}
impl E4 {
fn test(self) {
- let _ = self as i8; // Don't lint. `-128..=-127` fits in i8
+ // Don't lint. `-128..=-127` fits in i8
+ let _ = self as i8;
}
}
@@ -191,9 +258,13 @@ fn main() {
impl E5 {
fn test(self) {
let _ = self as i8;
+ //~^ ERROR: casting `main::E5` to `i8` may truncate the value
let _ = Self::A as i8;
- let _ = self as i16; // Don't lint. `-129..=127` fits in i16
- let _ = Self::B as u8; // Don't lint.
+ //~^ ERROR: casting `main::E5::A` to `i8` will truncate the value
+ // Don't lint. `-129..=127` fits in i16
+ let _ = self as i16;
+ // Don't lint.
+ let _ = Self::B as u8;
}
}
@@ -206,9 +277,13 @@ fn main() {
impl E6 {
fn test(self) {
let _ = self as i16;
- let _ = Self::A as u16; // Don't lint. `2^16-1` fits in u16
- let _ = self as u32; // Don't lint. `2^16-1..=2^16` fits in u32
- let _ = Self::A as u16; // Don't lint.
+ //~^ ERROR: casting `main::E6` to `i16` may truncate the value
+ // Don't lint. `2^16-1` fits in u16
+ let _ = Self::A as u16;
+ // Don't lint. `2^16-1..=2^16` fits in u32
+ let _ = self as u32;
+ // Don't lint.
+ let _ = Self::A as u16;
}
}
@@ -221,8 +296,11 @@ fn main() {
impl E7 {
fn test(self) {
let _ = self as usize;
- let _ = Self::A as usize; // Don't lint.
- let _ = self as u64; // Don't lint. `2^32-1..=2^32` fits in u64
+ //~^ ERROR: casting `main::E7` to `usize` may truncate the value on targets wi
+ // Don't lint.
+ let _ = Self::A as usize;
+ // Don't lint. `2^32-1..=2^32` fits in u64
+ let _ = self as u64;
}
}
@@ -236,7 +314,8 @@ fn main() {
}
impl E8 {
fn test(self) {
- let _ = self as i128; // Don't lint. `-(2^127)..=2^127-1` fits it i128
+ // Don't lint. `-(2^127)..=2^127-1` fits it i128
+ let _ = self as i128;
}
}
@@ -248,8 +327,10 @@ fn main() {
}
impl E9 {
fn test(self) {
- let _ = Self::A as u8; // Don't lint.
- let _ = self as u128; // Don't lint. `0..=2^128-1` fits in u128
+ // Don't lint.
+ let _ = Self::A as u8;
+ // Don't lint. `0..=2^128-1` fits in u128
+ let _ = self as u128;
}
}
@@ -262,16 +343,25 @@ fn main() {
impl E10 {
fn test(self) {
let _ = self as u16;
- let _ = Self::B as u32; // Don't lint.
- let _ = self as u64; // Don't lint.
+ //~^ ERROR: casting `main::E10` to `u16` may truncate the value
+ // Don't lint.
+ let _ = Self::B as u32;
+ // Don't lint.
+ let _ = self as u64;
}
}
}
fn avoid_subtract_overflow(q: u32) {
let c = (q >> 16) as u8;
+ //~^ ERROR: casting `u32` to `u8` may truncate the value
c as usize;
let c = (q / 1000) as u8;
+ //~^ ERROR: casting `u32` to `u8` may truncate the value
c as usize;
}
+
+fn issue11426() {
+ (&42u8 >> 0xa9008fb6c9d81e42_0e25730562a601c8_u128) as usize;
+}
diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr
index de29af78e..bc74f7b72 100644
--- a/src/tools/clippy/tests/ui/cast.stderr
+++ b/src/tools/clippy/tests/ui/cast.stderr
@@ -1,52 +1,54 @@
error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast.rs:14:5
+ --> $DIR/cast.rs:16:5
|
LL | x0 as f32;
| ^^^^^^^^^
|
= note: `-D clippy::cast-precision-loss` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`
error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast.rs:16:5
+ --> $DIR/cast.rs:20:5
|
LL | x1 as f32;
| ^^^^^^^^^
error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
- --> $DIR/cast.rs:17:5
+ --> $DIR/cast.rs:22:5
|
LL | x1 as f64;
| ^^^^^^^^^
error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast.rs:19:5
+ --> $DIR/cast.rs:25:5
|
LL | x2 as f32;
| ^^^^^^^^^
error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast.rs:21:5
+ --> $DIR/cast.rs:28:5
|
LL | x3 as f32;
| ^^^^^^^^^
error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
- --> $DIR/cast.rs:22:5
+ --> $DIR/cast.rs:30:5
|
LL | x3 as f64;
| ^^^^^^^^^
error: casting `f32` to `i32` may truncate the value
- --> $DIR/cast.rs:24:5
+ --> $DIR/cast.rs:33:5
|
LL | 1f32 as i32;
| ^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
error: casting `f32` to `u32` may truncate the value
- --> $DIR/cast.rs:25:5
+ --> $DIR/cast.rs:35:5
|
LL | 1f32 as u32;
| ^^^^^^^^^^^
@@ -54,15 +56,16 @@ LL | 1f32 as u32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u32` may lose the sign of the value
- --> $DIR/cast.rs:25:5
+ --> $DIR/cast.rs:35:5
|
LL | 1f32 as u32;
| ^^^^^^^^^^^
|
= note: `-D clippy::cast-sign-loss` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]`
error: casting `f64` to `f32` may truncate the value
- --> $DIR/cast.rs:26:5
+ --> $DIR/cast.rs:39:5
|
LL | 1f64 as f32;
| ^^^^^^^^^^^
@@ -70,7 +73,7 @@ LL | 1f64 as f32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `i32` to `i8` may truncate the value
- --> $DIR/cast.rs:27:5
+ --> $DIR/cast.rs:41:5
|
LL | 1i32 as i8;
| ^^^^^^^^^^
@@ -82,7 +85,7 @@ LL | i8::try_from(1i32);
| ~~~~~~~~~~~~~~~~~~
error: casting `i32` to `u8` may truncate the value
- --> $DIR/cast.rs:28:5
+ --> $DIR/cast.rs:43:5
|
LL | 1i32 as u8;
| ^^^^^^^^^^
@@ -94,7 +97,7 @@ LL | u8::try_from(1i32);
| ~~~~~~~~~~~~~~~~~~
error: casting `f64` to `isize` may truncate the value
- --> $DIR/cast.rs:29:5
+ --> $DIR/cast.rs:45:5
|
LL | 1f64 as isize;
| ^^^^^^^^^^^^^
@@ -102,7 +105,7 @@ LL | 1f64 as isize;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f64` to `usize` may truncate the value
- --> $DIR/cast.rs:30:5
+ --> $DIR/cast.rs:47:5
|
LL | 1f64 as usize;
| ^^^^^^^^^^^^^
@@ -110,13 +113,13 @@ LL | 1f64 as usize;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f64` to `usize` may lose the sign of the value
- --> $DIR/cast.rs:30:5
+ --> $DIR/cast.rs:47:5
|
LL | 1f64 as usize;
| ^^^^^^^^^^^^^
error: casting `u32` to `u16` may truncate the value
- --> $DIR/cast.rs:31:5
+ --> $DIR/cast.rs:50:5
|
LL | 1f32 as u32 as u16;
| ^^^^^^^^^^^^^^^^^^
@@ -128,7 +131,7 @@ LL | u16::try_from(1f32 as u32);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
error: casting `f32` to `u32` may truncate the value
- --> $DIR/cast.rs:31:5
+ --> $DIR/cast.rs:50:5
|
LL | 1f32 as u32 as u16;
| ^^^^^^^^^^^
@@ -136,13 +139,13 @@ LL | 1f32 as u32 as u16;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u32` may lose the sign of the value
- --> $DIR/cast.rs:31:5
+ --> $DIR/cast.rs:50:5
|
LL | 1f32 as u32 as u16;
| ^^^^^^^^^^^
error: casting `i32` to `i8` may truncate the value
- --> $DIR/cast.rs:33:22
+ --> $DIR/cast.rs:55:22
|
LL | let _x: i8 = 1i32 as _;
| ^^^^^^^^^
@@ -154,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into();
| ~~~~~~~~~~~~~~~
error: casting `f32` to `i32` may truncate the value
- --> $DIR/cast.rs:34:9
+ --> $DIR/cast.rs:57:9
|
LL | 1f32 as i32;
| ^^^^^^^^^^^
@@ -162,7 +165,7 @@ LL | 1f32 as i32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f64` to `i32` may truncate the value
- --> $DIR/cast.rs:35:9
+ --> $DIR/cast.rs:59:9
|
LL | 1f64 as i32;
| ^^^^^^^^^^^
@@ -170,7 +173,7 @@ LL | 1f64 as i32;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u8` may truncate the value
- --> $DIR/cast.rs:36:9
+ --> $DIR/cast.rs:61:9
|
LL | 1f32 as u8;
| ^^^^^^^^^^
@@ -178,171 +181,172 @@ LL | 1f32 as u8;
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
error: casting `f32` to `u8` may lose the sign of the value
- --> $DIR/cast.rs:36:9
+ --> $DIR/cast.rs:61:9
|
LL | 1f32 as u8;
| ^^^^^^^^^^
error: casting `u8` to `i8` may wrap around the value
- --> $DIR/cast.rs:39:5
+ --> $DIR/cast.rs:66:5
|
LL | 1u8 as i8;
| ^^^^^^^^^
|
= note: `-D clippy::cast-possible-wrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`
error: casting `u16` to `i16` may wrap around the value
- --> $DIR/cast.rs:40:5
+ --> $DIR/cast.rs:69:5
|
LL | 1u16 as i16;
| ^^^^^^^^^^^
error: casting `u32` to `i32` may wrap around the value
- --> $DIR/cast.rs:41:5
+ --> $DIR/cast.rs:71:5
|
LL | 1u32 as i32;
| ^^^^^^^^^^^
error: casting `u64` to `i64` may wrap around the value
- --> $DIR/cast.rs:42:5
+ --> $DIR/cast.rs:73:5
|
LL | 1u64 as i64;
| ^^^^^^^^^^^
error: casting `usize` to `isize` may wrap around the value
- --> $DIR/cast.rs:43:5
+ --> $DIR/cast.rs:75:5
|
LL | 1usize as isize;
| ^^^^^^^^^^^^^^^
error: casting `usize` to `i8` may truncate the value
- --> $DIR/cast.rs:44:5
+ --> $DIR/cast.rs:78:5
|
-LL | 1usize as i8; // should not wrap, usize is never 8 bits
+LL | 1usize as i8;
| ^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
help: ... or use `try_from` and handle the error accordingly
|
-LL | i8::try_from(1usize); // should not wrap, usize is never 8 bits
+LL | i8::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i16` may truncate the value
- --> $DIR/cast.rs:45:5
+ --> $DIR/cast.rs:81:5
|
-LL | 1usize as i16; // wraps on 16 bit ptr size
+LL | 1usize as i16;
| ^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
help: ... or use `try_from` and handle the error accordingly
|
-LL | i16::try_from(1usize); // wraps on 16 bit ptr size
+LL | i16::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers
- --> $DIR/cast.rs:45:5
+ --> $DIR/cast.rs:81:5
|
-LL | 1usize as i16; // wraps on 16 bit ptr size
+LL | 1usize as i16;
| ^^^^^^^^^^^^^
|
= note: `usize` and `isize` may be as small as 16 bits on some platforms
= note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast.rs:46:5
+ --> $DIR/cast.rs:86:5
|
-LL | 1usize as i32; // wraps on 32 bit ptr size
+LL | 1usize as i32;
| ^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
help: ... or use `try_from` and handle the error accordingly
|
-LL | i32::try_from(1usize); // wraps on 32 bit ptr size
+LL | i32::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
- --> $DIR/cast.rs:46:5
+ --> $DIR/cast.rs:86:5
|
-LL | 1usize as i32; // wraps on 32 bit ptr size
+LL | 1usize as i32;
| ^^^^^^^^^^^^^
error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers
- --> $DIR/cast.rs:47:5
+ --> $DIR/cast.rs:90:5
|
-LL | 1usize as i64; // wraps on 64 bit ptr size
+LL | 1usize as i64;
| ^^^^^^^^^^^^^
error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers
- --> $DIR/cast.rs:49:5
+ --> $DIR/cast.rs:95:5
|
-LL | 1u16 as isize; // wraps on 16 bit ptr size
+LL | 1u16 as isize;
| ^^^^^^^^^^^^^
|
= note: `usize` and `isize` may be as small as 16 bits on some platforms
= note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
- --> $DIR/cast.rs:50:5
+ --> $DIR/cast.rs:99:5
|
-LL | 1u32 as isize; // wraps on 32 bit ptr size
+LL | 1u32 as isize;
| ^^^^^^^^^^^^^
error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast.rs:51:5
+ --> $DIR/cast.rs:102:5
|
-LL | 1u64 as isize; // wraps on 64 bit ptr size
+LL | 1u64 as isize;
| ^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
help: ... or use `try_from` and handle the error accordingly
|
-LL | isize::try_from(1u64); // wraps on 64 bit ptr size
+LL | isize::try_from(1u64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
- --> $DIR/cast.rs:51:5
+ --> $DIR/cast.rs:102:5
|
-LL | 1u64 as isize; // wraps on 64 bit ptr size
+LL | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting `i32` to `u32` may lose the sign of the value
- --> $DIR/cast.rs:54:5
+ --> $DIR/cast.rs:107:5
|
LL | -1i32 as u32;
| ^^^^^^^^^^^^
error: casting `isize` to `usize` may lose the sign of the value
- --> $DIR/cast.rs:56:5
+ --> $DIR/cast.rs:110:5
|
LL | -1isize as usize;
| ^^^^^^^^^^^^^^^^
error: casting `i64` to `i8` may truncate the value
- --> $DIR/cast.rs:123:5
+ --> $DIR/cast.rs:179:5
|
-LL | (-99999999999i64).min(1) as i8; // should be linted because signed
+LL | (-99999999999i64).min(1) as i8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
help: ... or use `try_from` and handle the error accordingly
|
-LL | i8::try_from((-99999999999i64).min(1)); // should be linted because signed
+LL | i8::try_from((-99999999999i64).min(1));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `u8` may truncate the value
- --> $DIR/cast.rs:135:5
+ --> $DIR/cast.rs:193:5
|
-LL | 999999u64.clamp(0, 256) as u8; // should still be linted
+LL | 999999u64.clamp(0, 256) as u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
help: ... or use `try_from` and handle the error accordingly
|
-LL | u8::try_from(999999u64.clamp(0, 256)); // should still be linted
+LL | u8::try_from(999999u64.clamp(0, 256));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: casting `main::E2` to `u8` may truncate the value
- --> $DIR/cast.rs:156:21
+ --> $DIR/cast.rs:216:21
|
LL | let _ = self as u8;
| ^^^^^^^^^^
@@ -354,15 +358,16 @@ LL | let _ = u8::try_from(self);
| ~~~~~~~~~~~~~~~~~~
error: casting `main::E2::B` to `u8` will truncate the value
- --> $DIR/cast.rs:157:21
+ --> $DIR/cast.rs:218:21
|
LL | let _ = Self::B as u8;
| ^^^^^^^^^^^^^
|
= note: `-D clippy::cast-enum-truncation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]`
error: casting `main::E5` to `i8` may truncate the value
- --> $DIR/cast.rs:193:21
+ --> $DIR/cast.rs:260:21
|
LL | let _ = self as i8;
| ^^^^^^^^^^
@@ -374,13 +379,13 @@ LL | let _ = i8::try_from(self);
| ~~~~~~~~~~~~~~~~~~
error: casting `main::E5::A` to `i8` will truncate the value
- --> $DIR/cast.rs:194:21
+ --> $DIR/cast.rs:262:21
|
LL | let _ = Self::A as i8;
| ^^^^^^^^^^^^^
error: casting `main::E6` to `i16` may truncate the value
- --> $DIR/cast.rs:208:21
+ --> $DIR/cast.rs:279:21
|
LL | let _ = self as i16;
| ^^^^^^^^^^^
@@ -392,7 +397,7 @@ LL | let _ = i16::try_from(self);
| ~~~~~~~~~~~~~~~~~~~
error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast.rs:223:21
+ --> $DIR/cast.rs:298:21
|
LL | let _ = self as usize;
| ^^^^^^^^^^^^^
@@ -404,7 +409,7 @@ LL | let _ = usize::try_from(self);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `main::E10` to `u16` may truncate the value
- --> $DIR/cast.rs:264:21
+ --> $DIR/cast.rs:345:21
|
LL | let _ = self as u16;
| ^^^^^^^^^^^
@@ -416,7 +421,7 @@ LL | let _ = u16::try_from(self);
| ~~~~~~~~~~~~~~~~~~~
error: casting `u32` to `u8` may truncate the value
- --> $DIR/cast.rs:272:13
+ --> $DIR/cast.rs:356:13
|
LL | let c = (q >> 16) as u8;
| ^^^^^^^^^^^^^^^
@@ -428,7 +433,7 @@ LL | let c = u8::try_from(q >> 16);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u32` to `u8` may truncate the value
- --> $DIR/cast.rs:275:13
+ --> $DIR/cast.rs:360:13
|
LL | let c = (q / 1000) as u8;
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
index ef0a93b01..6ca01b7cc 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::cast_abs_to_unsigned)]
#![allow(clippy::uninlined_format_args, unused)]
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
index 96ced670a..190a77c10 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::cast_abs_to_unsigned)]
#![allow(clippy::uninlined_format_args, unused)]
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
index 4668554f4..fbdb559fc 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
@@ -1,109 +1,110 @@
error: casting the result of `i32::abs()` to u32
- --> $DIR/cast_abs_to_unsigned.rs:8:18
+ --> $DIR/cast_abs_to_unsigned.rs:6:18
|
LL | let y: u32 = x.abs() as u32;
| ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`
|
= note: `-D clippy::cast-abs-to-unsigned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_abs_to_unsigned)]`
error: casting the result of `i32::abs()` to usize
- --> $DIR/cast_abs_to_unsigned.rs:12:20
+ --> $DIR/cast_abs_to_unsigned.rs:10:20
|
LL | let _: usize = a.abs() as usize;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i32::abs()` to usize
- --> $DIR/cast_abs_to_unsigned.rs:13:20
+ --> $DIR/cast_abs_to_unsigned.rs:11:20
|
LL | let _: usize = a.abs() as _;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i32::abs()` to usize
- --> $DIR/cast_abs_to_unsigned.rs:14:13
+ --> $DIR/cast_abs_to_unsigned.rs:12:13
|
LL | let _ = a.abs() as usize;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i64::abs()` to usize
- --> $DIR/cast_abs_to_unsigned.rs:17:13
+ --> $DIR/cast_abs_to_unsigned.rs:15:13
|
LL | let _ = a.abs() as usize;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i64::abs()` to u8
- --> $DIR/cast_abs_to_unsigned.rs:18:13
+ --> $DIR/cast_abs_to_unsigned.rs:16:13
|
LL | let _ = a.abs() as u8;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i64::abs()` to u16
- --> $DIR/cast_abs_to_unsigned.rs:19:13
+ --> $DIR/cast_abs_to_unsigned.rs:17:13
|
LL | let _ = a.abs() as u16;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i64::abs()` to u32
- --> $DIR/cast_abs_to_unsigned.rs:20:13
+ --> $DIR/cast_abs_to_unsigned.rs:18:13
|
LL | let _ = a.abs() as u32;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i64::abs()` to u64
- --> $DIR/cast_abs_to_unsigned.rs:21:13
+ --> $DIR/cast_abs_to_unsigned.rs:19:13
|
LL | let _ = a.abs() as u64;
| ^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i64::abs()` to u128
- --> $DIR/cast_abs_to_unsigned.rs:22:13
+ --> $DIR/cast_abs_to_unsigned.rs:20:13
|
LL | let _ = a.abs() as u128;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `isize::abs()` to usize
- --> $DIR/cast_abs_to_unsigned.rs:25:13
+ --> $DIR/cast_abs_to_unsigned.rs:23:13
|
LL | let _ = a.abs() as usize;
| ^^^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `isize::abs()` to u8
- --> $DIR/cast_abs_to_unsigned.rs:26:13
+ --> $DIR/cast_abs_to_unsigned.rs:24:13
|
LL | let _ = a.abs() as u8;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `isize::abs()` to u16
- --> $DIR/cast_abs_to_unsigned.rs:27:13
+ --> $DIR/cast_abs_to_unsigned.rs:25:13
|
LL | let _ = a.abs() as u16;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `isize::abs()` to u32
- --> $DIR/cast_abs_to_unsigned.rs:28:13
+ --> $DIR/cast_abs_to_unsigned.rs:26:13
|
LL | let _ = a.abs() as u32;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `isize::abs()` to u64
- --> $DIR/cast_abs_to_unsigned.rs:29:13
+ --> $DIR/cast_abs_to_unsigned.rs:27:13
|
LL | let _ = a.abs() as u64;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `isize::abs()` to u128
- --> $DIR/cast_abs_to_unsigned.rs:30:13
+ --> $DIR/cast_abs_to_unsigned.rs:28:13
|
LL | let _ = a.abs() as u128;
| ^^^^^^^ help: replace with: `a.unsigned_abs()`
error: casting the result of `i64::abs()` to u32
- --> $DIR/cast_abs_to_unsigned.rs:32:13
+ --> $DIR/cast_abs_to_unsigned.rs:30:13
|
LL | let _ = (x as i64 - y as i64).abs() as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(x as i64 - y as i64).unsigned_abs()`
error: casting the result of `i32::abs()` to u32
- --> $DIR/cast_abs_to_unsigned.rs:44:23
+ --> $DIR/cast_abs_to_unsigned.rs:42:23
|
LL | assert_eq!(10u32, x.abs() as u32);
| ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`
diff --git a/src/tools/clippy/tests/ui/cast_alignment.rs b/src/tools/clippy/tests/ui/cast_alignment.rs
index 95bb883df..98ef5e36f 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.rs
+++ b/src/tools/clippy/tests/ui/cast_alignment.rs
@@ -17,11 +17,16 @@ fn main() {
// cast to more-strictly-aligned type
(&1u8 as *const u8) as *const u16;
+ //~^ ERROR: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`)
+ //~| NOTE: `-D clippy::cast-ptr-alignment` implied by `-D warnings`
(&mut 1u8 as *mut u8) as *mut u16;
+ //~^ ERROR: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1
// cast to more-strictly-aligned type, but with the `pointer::cast` function.
(&1u8 as *const u8).cast::<u16>();
+ //~^ ERROR: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`)
(&mut 1u8 as *mut u8).cast::<u16>();
+ //~^ ERROR: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1
/* These should be ok */
diff --git a/src/tools/clippy/tests/ui/cast_alignment.stderr b/src/tools/clippy/tests/ui/cast_alignment.stderr
index 5df2b5b10..49bd8dad9 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.stderr
+++ b/src/tools/clippy/tests/ui/cast_alignment.stderr
@@ -5,21 +5,22 @@ LL | (&1u8 as *const u8) as *const u16;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::cast-ptr-alignment` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_ptr_alignment)]`
error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
- --> $DIR/cast_alignment.rs:20:5
+ --> $DIR/cast_alignment.rs:22:5
|
LL | (&mut 1u8 as *mut u8) as *mut u16;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
- --> $DIR/cast_alignment.rs:23:5
+ --> $DIR/cast_alignment.rs:26:5
|
LL | (&1u8 as *const u8).cast::<u16>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
- --> $DIR/cast_alignment.rs:24:5
+ --> $DIR/cast_alignment.rs:28:5
|
LL | (&mut 1u8 as *mut u8).cast::<u16>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cast_enum_constructor.rs b/src/tools/clippy/tests/ui/cast_enum_constructor.rs
index 0193454ad..3226f487b 100644
--- a/src/tools/clippy/tests/ui/cast_enum_constructor.rs
+++ b/src/tools/clippy/tests/ui/cast_enum_constructor.rs
@@ -11,7 +11,10 @@ fn main() {
}
let _ = Foo::Y as usize;
+ //~^ ERROR: cast of an enum tuple constructor to an integer
+ //~| NOTE: `-D clippy::cast-enum-constructor` implied by `-D warnings`
let _ = Foo::Y as isize;
+ //~^ ERROR: cast of an enum tuple constructor to an integer
let _ = Foo::Y as fn(u32) -> Foo;
let _ = Bar::X as usize;
}
diff --git a/src/tools/clippy/tests/ui/cast_enum_constructor.stderr b/src/tools/clippy/tests/ui/cast_enum_constructor.stderr
index 710909dd2..b1bf61ede 100644
--- a/src/tools/clippy/tests/ui/cast_enum_constructor.stderr
+++ b/src/tools/clippy/tests/ui/cast_enum_constructor.stderr
@@ -5,9 +5,10 @@ LL | let _ = Foo::Y as usize;
| ^^^^^^^^^^^^^^^
|
= note: `-D clippy::cast-enum-constructor` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_enum_constructor)]`
error: cast of an enum tuple constructor to an integer
- --> $DIR/cast_enum_constructor.rs:14:13
+ --> $DIR/cast_enum_constructor.rs:16:13
|
LL | let _ = Foo::Y as isize;
| ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.fixed b/src/tools/clippy/tests/ui/cast_lossless_bool.fixed
index c321cc644..a4ce1c6f9 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_bool.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_bool.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
#![warn(clippy::cast_lossless)]
diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.rs b/src/tools/clippy/tests/ui/cast_lossless_bool.rs
index 632a71892..e5b1c30c1 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_bool.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_bool.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
#![warn(clippy::cast_lossless)]
diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
index ce240b70f..e4a5b2e80 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
@@ -1,85 +1,86 @@
error: casting `bool` to `u8` is more cleanly stated with `u8::from(_)`
- --> $DIR/cast_lossless_bool.rs:8:13
+ --> $DIR/cast_lossless_bool.rs:6:13
|
LL | let _ = true as u8;
| ^^^^^^^^^^ help: try: `u8::from(true)`
|
= note: `-D clippy::cast-lossless` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
error: casting `bool` to `u16` is more cleanly stated with `u16::from(_)`
- --> $DIR/cast_lossless_bool.rs:9:13
+ --> $DIR/cast_lossless_bool.rs:7:13
|
LL | let _ = true as u16;
| ^^^^^^^^^^^ help: try: `u16::from(true)`
error: casting `bool` to `u32` is more cleanly stated with `u32::from(_)`
- --> $DIR/cast_lossless_bool.rs:10:13
+ --> $DIR/cast_lossless_bool.rs:8:13
|
LL | let _ = true as u32;
| ^^^^^^^^^^^ help: try: `u32::from(true)`
error: casting `bool` to `u64` is more cleanly stated with `u64::from(_)`
- --> $DIR/cast_lossless_bool.rs:11:13
+ --> $DIR/cast_lossless_bool.rs:9:13
|
LL | let _ = true as u64;
| ^^^^^^^^^^^ help: try: `u64::from(true)`
error: casting `bool` to `u128` is more cleanly stated with `u128::from(_)`
- --> $DIR/cast_lossless_bool.rs:12:13
+ --> $DIR/cast_lossless_bool.rs:10:13
|
LL | let _ = true as u128;
| ^^^^^^^^^^^^ help: try: `u128::from(true)`
error: casting `bool` to `usize` is more cleanly stated with `usize::from(_)`
- --> $DIR/cast_lossless_bool.rs:13:13
+ --> $DIR/cast_lossless_bool.rs:11:13
|
LL | let _ = true as usize;
| ^^^^^^^^^^^^^ help: try: `usize::from(true)`
error: casting `bool` to `i8` is more cleanly stated with `i8::from(_)`
- --> $DIR/cast_lossless_bool.rs:15:13
+ --> $DIR/cast_lossless_bool.rs:13:13
|
LL | let _ = true as i8;
| ^^^^^^^^^^ help: try: `i8::from(true)`
error: casting `bool` to `i16` is more cleanly stated with `i16::from(_)`
- --> $DIR/cast_lossless_bool.rs:16:13
+ --> $DIR/cast_lossless_bool.rs:14:13
|
LL | let _ = true as i16;
| ^^^^^^^^^^^ help: try: `i16::from(true)`
error: casting `bool` to `i32` is more cleanly stated with `i32::from(_)`
- --> $DIR/cast_lossless_bool.rs:17:13
+ --> $DIR/cast_lossless_bool.rs:15:13
|
LL | let _ = true as i32;
| ^^^^^^^^^^^ help: try: `i32::from(true)`
error: casting `bool` to `i64` is more cleanly stated with `i64::from(_)`
- --> $DIR/cast_lossless_bool.rs:18:13
+ --> $DIR/cast_lossless_bool.rs:16:13
|
LL | let _ = true as i64;
| ^^^^^^^^^^^ help: try: `i64::from(true)`
error: casting `bool` to `i128` is more cleanly stated with `i128::from(_)`
- --> $DIR/cast_lossless_bool.rs:19:13
+ --> $DIR/cast_lossless_bool.rs:17:13
|
LL | let _ = true as i128;
| ^^^^^^^^^^^^ help: try: `i128::from(true)`
error: casting `bool` to `isize` is more cleanly stated with `isize::from(_)`
- --> $DIR/cast_lossless_bool.rs:20:13
+ --> $DIR/cast_lossless_bool.rs:18:13
|
LL | let _ = true as isize;
| ^^^^^^^^^^^^^ help: try: `isize::from(true)`
error: casting `bool` to `u16` is more cleanly stated with `u16::from(_)`
- --> $DIR/cast_lossless_bool.rs:23:13
+ --> $DIR/cast_lossless_bool.rs:21:13
|
LL | let _ = (true | false) as u16;
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::from(true | false)`
error: casting `bool` to `u8` is more cleanly stated with `u8::from(_)`
- --> $DIR/cast_lossless_bool.rs:51:13
+ --> $DIR/cast_lossless_bool.rs:49:13
|
LL | let _ = true as u8;
| ^^^^^^^^^^ help: try: `u8::from(true)`
diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.fixed b/src/tools/clippy/tests/ui/cast_lossless_float.fixed
index e72a0096a..f4f2e4773 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_float.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_float.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]
#![warn(clippy::cast_lossless)]
diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.rs b/src/tools/clippy/tests/ui/cast_lossless_float.rs
index dbcbaa9b8..fdd88ed36 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_float.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_float.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]
#![warn(clippy::cast_lossless)]
diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.stderr b/src/tools/clippy/tests/ui/cast_lossless_float.stderr
index 8326d40be..95e80b4e4 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_float.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_float.stderr
@@ -1,67 +1,68 @@
error: casting `i8` to `f32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:9:13
+ --> $DIR/cast_lossless_float.rs:7:13
|
LL | let _ = x0 as f32;
| ^^^^^^^^^ help: try: `f32::from(x0)`
|
= note: `-D clippy::cast-lossless` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
error: casting `i8` to `f64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:10:13
+ --> $DIR/cast_lossless_float.rs:8:13
|
LL | let _ = x0 as f64;
| ^^^^^^^^^ help: try: `f64::from(x0)`
error: casting `u8` to `f32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:12:13
+ --> $DIR/cast_lossless_float.rs:10:13
|
LL | let _ = x1 as f32;
| ^^^^^^^^^ help: try: `f32::from(x1)`
error: casting `u8` to `f64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:13:13
+ --> $DIR/cast_lossless_float.rs:11:13
|
LL | let _ = x1 as f64;
| ^^^^^^^^^ help: try: `f64::from(x1)`
error: casting `i16` to `f32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:15:13
+ --> $DIR/cast_lossless_float.rs:13:13
|
LL | let _ = x2 as f32;
| ^^^^^^^^^ help: try: `f32::from(x2)`
error: casting `i16` to `f64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:16:13
+ --> $DIR/cast_lossless_float.rs:14:13
|
LL | let _ = x2 as f64;
| ^^^^^^^^^ help: try: `f64::from(x2)`
error: casting `u16` to `f32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:18:13
+ --> $DIR/cast_lossless_float.rs:16:13
|
LL | let _ = x3 as f32;
| ^^^^^^^^^ help: try: `f32::from(x3)`
error: casting `u16` to `f64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:19:13
+ --> $DIR/cast_lossless_float.rs:17:13
|
LL | let _ = x3 as f64;
| ^^^^^^^^^ help: try: `f64::from(x3)`
error: casting `i32` to `f64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:21:13
+ --> $DIR/cast_lossless_float.rs:19:13
|
LL | let _ = x4 as f64;
| ^^^^^^^^^ help: try: `f64::from(x4)`
error: casting `u32` to `f64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:23:13
+ --> $DIR/cast_lossless_float.rs:21:13
|
LL | let _ = x5 as f64;
| ^^^^^^^^^ help: try: `f64::from(x5)`
error: casting `f32` to `f64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_float.rs:26:13
+ --> $DIR/cast_lossless_float.rs:24:13
|
LL | let _ = 1.0f32 as f64;
| ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)`
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
index 7dab02084..5e7e545e7 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]
#![warn(clippy::cast_lossless)]
@@ -51,3 +49,14 @@ mod cast_lossless_in_impl {
enum Test {
A = u32::MAX as i64 + 1,
}
+
+fn issue11458() {
+ macro_rules! sign_cast {
+ ($var: ident, $src: ty, $dest: ty) => {
+ <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())
+ };
+ }
+ let x = 10_u128;
+ let _ = i32::from(sign_cast!(x, u8, i8));
+ let _ = i32::from(sign_cast!(x, u8, i8) + 1);
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.rs b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
index c24f73960..0d69ddbd5 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]
#![warn(clippy::cast_lossless)]
@@ -51,3 +49,14 @@ mod cast_lossless_in_impl {
enum Test {
A = u32::MAX as i64 + 1,
}
+
+fn issue11458() {
+ macro_rules! sign_cast {
+ ($var: ident, $src: ty, $dest: ty) => {
+ <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())
+ };
+ }
+ let x = 10_u128;
+ let _ = sign_cast!(x, u8, i8) as i32;
+ let _ = (sign_cast!(x, u8, i8) + 1) as i32;
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
index 721b94876..f9f111a7c 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
@@ -1,118 +1,131 @@
error: casting `i8` to `i16` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:8:13
+ --> $DIR/cast_lossless_integer.rs:6:13
|
LL | let _ = 1i8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1i8)`
|
= note: `-D clippy::cast-lossless` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
error: casting `i8` to `i32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:9:13
+ --> $DIR/cast_lossless_integer.rs:7:13
|
LL | let _ = 1i8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1i8)`
error: casting `i8` to `i64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:10:13
+ --> $DIR/cast_lossless_integer.rs:8:13
|
LL | let _ = 1i8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1i8)`
error: casting `u8` to `i16` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:11:13
+ --> $DIR/cast_lossless_integer.rs:9:13
|
LL | let _ = 1u8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1u8)`
error: casting `u8` to `i32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:12:13
+ --> $DIR/cast_lossless_integer.rs:10:13
|
LL | let _ = 1u8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1u8)`
error: casting `u8` to `i64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:13:13
+ --> $DIR/cast_lossless_integer.rs:11:13
|
LL | let _ = 1u8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1u8)`
error: casting `u8` to `u16` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:14:13
+ --> $DIR/cast_lossless_integer.rs:12:13
|
LL | let _ = 1u8 as u16;
| ^^^^^^^^^^ help: try: `u16::from(1u8)`
error: casting `u8` to `u32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:15:13
+ --> $DIR/cast_lossless_integer.rs:13:13
|
LL | let _ = 1u8 as u32;
| ^^^^^^^^^^ help: try: `u32::from(1u8)`
error: casting `u8` to `u64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:16:13
+ --> $DIR/cast_lossless_integer.rs:14:13
|
LL | let _ = 1u8 as u64;
| ^^^^^^^^^^ help: try: `u64::from(1u8)`
error: casting `i16` to `i32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:17:13
+ --> $DIR/cast_lossless_integer.rs:15:13
|
LL | let _ = 1i16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1i16)`
error: casting `i16` to `i64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:18:13
+ --> $DIR/cast_lossless_integer.rs:16:13
|
LL | let _ = 1i16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i16)`
error: casting `u16` to `i32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:19:13
+ --> $DIR/cast_lossless_integer.rs:17:13
|
LL | let _ = 1u16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1u16)`
error: casting `u16` to `i64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:20:13
+ --> $DIR/cast_lossless_integer.rs:18:13
|
LL | let _ = 1u16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u16)`
error: casting `u16` to `u32` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:21:13
+ --> $DIR/cast_lossless_integer.rs:19:13
|
LL | let _ = 1u16 as u32;
| ^^^^^^^^^^^ help: try: `u32::from(1u16)`
error: casting `u16` to `u64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:22:13
+ --> $DIR/cast_lossless_integer.rs:20:13
|
LL | let _ = 1u16 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u16)`
error: casting `i32` to `i64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:23:13
+ --> $DIR/cast_lossless_integer.rs:21:13
|
LL | let _ = 1i32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i32)`
error: casting `u32` to `i64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:24:13
+ --> $DIR/cast_lossless_integer.rs:22:13
|
LL | let _ = 1u32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u32)`
error: casting `u32` to `u64` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:25:13
+ --> $DIR/cast_lossless_integer.rs:23:13
|
LL | let _ = 1u32 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u32)`
error: casting `u8` to `u16` may become silently lossy if you later change the type
- --> $DIR/cast_lossless_integer.rs:28:13
+ --> $DIR/cast_lossless_integer.rs:26:13
|
LL | let _ = (1u8 + 1u8) as u16;
| ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
-error: aborting due to 19 previous errors
+error: casting `i8` to `i32` may become silently lossy if you later change the type
+ --> $DIR/cast_lossless_integer.rs:60:13
+ |
+LL | let _ = sign_cast!(x, u8, i8) as i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8))`
+
+error: casting `i8` to `i32` may become silently lossy if you later change the type
+ --> $DIR/cast_lossless_integer.rs:61:13
+ |
+LL | let _ = (sign_cast!(x, u8, i8) + 1) as i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8) + 1)`
+
+error: aborting due to 21 previous errors
diff --git a/src/tools/clippy/tests/ui/cast_nan_to_int.rs b/src/tools/clippy/tests/ui/cast_nan_to_int.rs
index 287c5aa21..2d7467ff0 100644
--- a/src/tools/clippy/tests/ui/cast_nan_to_int.rs
+++ b/src/tools/clippy/tests/ui/cast_nan_to_int.rs
@@ -3,12 +3,24 @@
fn main() {
let _ = (0.0_f32 / -0.0) as usize;
+ //~^ ERROR: casting a known NaN to usize
+ //~| NOTE: this always evaluates to 0
let _ = (f64::INFINITY * -0.0) as usize;
+ //~^ ERROR: casting a known NaN to usize
+ //~| NOTE: this always evaluates to 0
let _ = (0.0 * f32::INFINITY) as usize;
+ //~^ ERROR: casting a known NaN to usize
+ //~| NOTE: this always evaluates to 0
let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize;
+ //~^ ERROR: casting a known NaN to usize
+ //~| NOTE: this always evaluates to 0
let _ = (f32::INFINITY - f32::INFINITY) as usize;
+ //~^ ERROR: casting a known NaN to usize
+ //~| NOTE: this always evaluates to 0
let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize;
+ //~^ ERROR: casting a known NaN to usize
+ //~| NOTE: this always evaluates to 0
// those won't be linted:
let _ = (1.0_f32 / 0.0) as usize;
diff --git a/src/tools/clippy/tests/ui/cast_nan_to_int.stderr b/src/tools/clippy/tests/ui/cast_nan_to_int.stderr
index 3539be75a..c0bb29448 100644
--- a/src/tools/clippy/tests/ui/cast_nan_to_int.stderr
+++ b/src/tools/clippy/tests/ui/cast_nan_to_int.stderr
@@ -6,9 +6,10 @@ LL | let _ = (0.0_f32 / -0.0) as usize;
|
= note: this always evaluates to 0
= note: `-D clippy::cast-nan-to-int` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_nan_to_int)]`
error: casting a known NaN to usize
- --> $DIR/cast_nan_to_int.rs:6:13
+ --> $DIR/cast_nan_to_int.rs:8:13
|
LL | let _ = (f64::INFINITY * -0.0) as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let _ = (f64::INFINITY * -0.0) as usize;
= note: this always evaluates to 0
error: casting a known NaN to usize
- --> $DIR/cast_nan_to_int.rs:7:13
+ --> $DIR/cast_nan_to_int.rs:11:13
|
LL | let _ = (0.0 * f32::INFINITY) as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let _ = (0.0 * f32::INFINITY) as usize;
= note: this always evaluates to 0
error: casting a known NaN to usize
- --> $DIR/cast_nan_to_int.rs:9:13
+ --> $DIR/cast_nan_to_int.rs:15:13
|
LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize;
= note: this always evaluates to 0
error: casting a known NaN to usize
- --> $DIR/cast_nan_to_int.rs:10:13
+ --> $DIR/cast_nan_to_int.rs:18:13
|
LL | let _ = (f32::INFINITY - f32::INFINITY) as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | let _ = (f32::INFINITY - f32::INFINITY) as usize;
= note: this always evaluates to 0
error: casting a known NaN to usize
- --> $DIR/cast_nan_to_int.rs:11:13
+ --> $DIR/cast_nan_to_int.rs:21:13
|
LL | let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
index 9b6fee270..e78bd66c3 100644
--- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::cast_slice_from_raw_parts)]
#[allow(unused_imports, unused_unsafe)]
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
index c0bb81379..c3d8c7bee 100644
--- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::cast_slice_from_raw_parts)]
#[allow(unused_imports, unused_unsafe)]
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
index f07801c19..47dc39a30 100644
--- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
@@ -1,43 +1,44 @@
error: casting the result of `from_raw_parts` to *const [u8]
- --> $DIR/cast_raw_slice_pointer_cast.rs:9:35
+ --> $DIR/cast_raw_slice_pointer_cast.rs:8:35
|
LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
|
= note: `-D clippy::cast-slice-from-raw-parts` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_slice_from_raw_parts)]`
error: casting the result of `from_raw_parts_mut` to *mut [u8]
- --> $DIR/cast_raw_slice_pointer_cast.rs:10:35
+ --> $DIR/cast_raw_slice_pointer_cast.rs:9:35
|
LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)`
error: casting the result of `from_raw_parts` to *const [u8]
- --> $DIR/cast_raw_slice_pointer_cast.rs:11:26
+ --> $DIR/cast_raw_slice_pointer_cast.rs:10:26
|
LL | let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
error: casting the result of `from_raw_parts` to *const [u8]
- --> $DIR/cast_raw_slice_pointer_cast.rs:14:30
+ --> $DIR/cast_raw_slice_pointer_cast.rs:13:30
|
LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
error: casting the result of `from_raw_parts` to *const [u8]
- --> $DIR/cast_raw_slice_pointer_cast.rs:16:30
+ --> $DIR/cast_raw_slice_pointer_cast.rs:15:30
|
LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
error: casting the result of `from_raw_parts` to *const [u8]
- --> $DIR/cast_raw_slice_pointer_cast.rs:20:30
+ --> $DIR/cast_raw_slice_pointer_cast.rs:19:30
|
LL | let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
error: casting the result of `from_raw_parts` to *const [u8]
- --> $DIR/cast_raw_slice_pointer_cast.rs:22:30
+ --> $DIR/cast_raw_slice_pointer_cast.rs:21:30
|
LL | let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
diff --git a/src/tools/clippy/tests/ui/cast_size_32bit.stderr b/src/tools/clippy/tests/ui/cast_size.32bit.stderr
index fb51783a4..379ca6086 100644
--- a/src/tools/clippy/tests/ui/cast_size_32bit.stderr
+++ b/src/tools/clippy/tests/ui/cast_size.32bit.stderr
@@ -1,44 +1,46 @@
error: casting `isize` to `i8` may truncate the value
- --> $DIR/cast_size_32bit.rs:12:5
+ --> $DIR/cast_size.rs:15:5
|
LL | 1isize as i8;
| ^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
help: ... or use `try_from` and handle the error accordingly
|
LL | i8::try_from(1isize);
| ~~~~~~~~~~~~~~~~~~~~
error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
- --> $DIR/cast_size_32bit.rs:15:5
+ --> $DIR/cast_size.rs:18:5
|
LL | x0 as f64;
| ^^^^^^^^^
|
= note: `-D clippy::cast-precision-loss` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`
error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
- --> $DIR/cast_size_32bit.rs:16:5
+ --> $DIR/cast_size.rs:19:5
|
LL | x1 as f64;
| ^^^^^^^^^
error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast_size_32bit.rs:17:5
+ --> $DIR/cast_size.rs:20:5
|
LL | x0 as f32;
| ^^^^^^^^^
error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast_size_32bit.rs:18:5
+ --> $DIR/cast_size.rs:21:5
|
LL | x1 as f32;
| ^^^^^^^^^
error: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size_32bit.rs:19:5
+ --> $DIR/cast_size.rs:22:5
|
LL | 1isize as i32;
| ^^^^^^^^^^^^^
@@ -50,7 +52,7 @@ LL | i32::try_from(1isize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size_32bit.rs:20:5
+ --> $DIR/cast_size.rs:23:5
|
LL | 1isize as u32;
| ^^^^^^^^^^^^^
@@ -62,7 +64,7 @@ LL | u32::try_from(1isize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size_32bit.rs:21:5
+ --> $DIR/cast_size.rs:24:5
|
LL | 1usize as u32;
| ^^^^^^^^^^^^^
@@ -74,7 +76,7 @@ LL | u32::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size_32bit.rs:22:5
+ --> $DIR/cast_size.rs:25:5
|
LL | 1usize as i32;
| ^^^^^^^^^^^^^
@@ -86,15 +88,16 @@ LL | i32::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
- --> $DIR/cast_size_32bit.rs:22:5
+ --> $DIR/cast_size.rs:25:5
|
LL | 1usize as i32;
| ^^^^^^^^^^^^^
|
= note: `-D clippy::cast-possible-wrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`
error: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size_32bit.rs:24:5
+ --> $DIR/cast_size.rs:26:5
|
LL | 1i64 as isize;
| ^^^^^^^^^^^^^
@@ -106,7 +109,7 @@ LL | isize::try_from(1i64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size_32bit.rs:25:5
+ --> $DIR/cast_size.rs:27:5
|
LL | 1i64 as usize;
| ^^^^^^^^^^^^^
@@ -118,7 +121,7 @@ LL | usize::try_from(1i64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size_32bit.rs:26:5
+ --> $DIR/cast_size.rs:28:5
|
LL | 1u64 as isize;
| ^^^^^^^^^^^^^
@@ -130,13 +133,13 @@ LL | isize::try_from(1u64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
- --> $DIR/cast_size_32bit.rs:26:5
+ --> $DIR/cast_size.rs:28:5
|
LL | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size_32bit.rs:27:5
+ --> $DIR/cast_size.rs:29:5
|
LL | 1u64 as usize;
| ^^^^^^^^^^^^^
@@ -148,24 +151,31 @@ LL | usize::try_from(1u64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
- --> $DIR/cast_size_32bit.rs:28:5
+ --> $DIR/cast_size.rs:30:5
|
LL | 1u32 as isize;
| ^^^^^^^^^^^^^
error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast_size_32bit.rs:33:5
+ --> $DIR/cast_size.rs:35:5
|
LL | 999_999_999 as f32;
| ^^^^^^^^^^^^^^^^^^
-error: casting integer literal to `f64` is unnecessary
- --> $DIR/cast_size_32bit.rs:34:5
+error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
+ --> $DIR/cast_size.rs:36:5
+ |
+LL | 9_999_999_999_999_999usize as f64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: literal out of range for `usize`
+ --> $DIR/cast_size.rs:36:5
|
-LL | 3_999_999_999usize as f64;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `3_999_999_999_f64`
+LL | 9_999_999_999_999_999usize as f64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
+ = note: the literal `9_999_999_999_999_999usize` does not fit into the type `usize` whose range is `0..=4294967295`
+ = note: `#[deny(overflowing_literals)]` on by default
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors
diff --git a/src/tools/clippy/tests/ui/cast_size.stderr b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
index 6d2d49d9e..7fae92b12 100644
--- a/src/tools/clippy/tests/ui/cast_size.stderr
+++ b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
@@ -1,44 +1,46 @@
error: casting `isize` to `i8` may truncate the value
- --> $DIR/cast_size.rs:12:5
+ --> $DIR/cast_size.rs:15:5
|
LL | 1isize as i8;
| ^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
help: ... or use `try_from` and handle the error accordingly
|
LL | i8::try_from(1isize);
| ~~~~~~~~~~~~~~~~~~~~
error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
- --> $DIR/cast_size.rs:15:5
+ --> $DIR/cast_size.rs:18:5
|
LL | x0 as f64;
| ^^^^^^^^^
|
= note: `-D clippy::cast-precision-loss` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`
error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
- --> $DIR/cast_size.rs:16:5
+ --> $DIR/cast_size.rs:19:5
|
LL | x1 as f64;
| ^^^^^^^^^
error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast_size.rs:17:5
+ --> $DIR/cast_size.rs:20:5
|
LL | x0 as f32;
| ^^^^^^^^^
error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast_size.rs:18:5
+ --> $DIR/cast_size.rs:21:5
|
LL | x1 as f32;
| ^^^^^^^^^
error: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size.rs:19:5
+ --> $DIR/cast_size.rs:22:5
|
LL | 1isize as i32;
| ^^^^^^^^^^^^^
@@ -50,7 +52,7 @@ LL | i32::try_from(1isize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size.rs:20:5
+ --> $DIR/cast_size.rs:23:5
|
LL | 1isize as u32;
| ^^^^^^^^^^^^^
@@ -62,7 +64,7 @@ LL | u32::try_from(1isize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size.rs:21:5
+ --> $DIR/cast_size.rs:24:5
|
LL | 1usize as u32;
| ^^^^^^^^^^^^^
@@ -74,7 +76,7 @@ LL | u32::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
- --> $DIR/cast_size.rs:22:5
+ --> $DIR/cast_size.rs:25:5
|
LL | 1usize as i32;
| ^^^^^^^^^^^^^
@@ -86,15 +88,16 @@ LL | i32::try_from(1usize);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
- --> $DIR/cast_size.rs:22:5
+ --> $DIR/cast_size.rs:25:5
|
LL | 1usize as i32;
| ^^^^^^^^^^^^^
|
= note: `-D clippy::cast-possible-wrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`
error: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size.rs:24:5
+ --> $DIR/cast_size.rs:26:5
|
LL | 1i64 as isize;
| ^^^^^^^^^^^^^
@@ -106,7 +109,7 @@ LL | isize::try_from(1i64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size.rs:25:5
+ --> $DIR/cast_size.rs:27:5
|
LL | 1i64 as usize;
| ^^^^^^^^^^^^^
@@ -118,7 +121,7 @@ LL | usize::try_from(1i64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size.rs:26:5
+ --> $DIR/cast_size.rs:28:5
|
LL | 1u64 as isize;
| ^^^^^^^^^^^^^
@@ -130,13 +133,13 @@ LL | isize::try_from(1u64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
- --> $DIR/cast_size.rs:26:5
+ --> $DIR/cast_size.rs:28:5
|
LL | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers
- --> $DIR/cast_size.rs:27:5
+ --> $DIR/cast_size.rs:29:5
|
LL | 1u64 as usize;
| ^^^^^^^^^^^^^
@@ -148,19 +151,19 @@ LL | usize::try_from(1u64);
| ~~~~~~~~~~~~~~~~~~~~~
error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
- --> $DIR/cast_size.rs:28:5
+ --> $DIR/cast_size.rs:30:5
|
LL | 1u32 as isize;
| ^^^^^^^^^^^^^
error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
- --> $DIR/cast_size.rs:33:5
+ --> $DIR/cast_size.rs:35:5
|
LL | 999_999_999 as f32;
| ^^^^^^^^^^^^^^^^^^
error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
- --> $DIR/cast_size.rs:34:5
+ --> $DIR/cast_size.rs:36:5
|
LL | 9_999_999_999_999_999usize as f64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cast_size.rs b/src/tools/clippy/tests/ui/cast_size.rs
index cd2184aea..d063a70cc 100644
--- a/src/tools/clippy/tests/ui/cast_size.rs
+++ b/src/tools/clippy/tests/ui/cast_size.rs
@@ -1,12 +1,15 @@
-//@ignore-32bit
-#[warn(
+//@stderr-per-bitwidth
+//@no-rustfix
+
+#![warn(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::cast_possible_wrap,
clippy::cast_lossless
)]
-#[allow(clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(clippy::no_effect, clippy::unnecessary_operation)]
+
fn main() {
// Casting from *size
1isize as i8;
@@ -20,7 +23,6 @@ fn main() {
1isize as u32;
1usize as u32;
1usize as i32;
- // Casting to *size
1i64 as isize;
1i64 as usize;
1u64 as isize;
diff --git a/src/tools/clippy/tests/ui/cast_size_32bit.rs b/src/tools/clippy/tests/ui/cast_size_32bit.rs
deleted file mode 100644
index 7ca20d3ca..000000000
--- a/src/tools/clippy/tests/ui/cast_size_32bit.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-//@ignore-64bit
-#[warn(
- clippy::cast_precision_loss,
- clippy::cast_possible_truncation,
- clippy::cast_sign_loss,
- clippy::cast_possible_wrap,
- clippy::cast_lossless
-)]
-#[allow(clippy::no_effect, clippy::unnecessary_operation)]
-fn main() {
- // Casting from *size
- 1isize as i8;
- let x0 = 1isize;
- let x1 = 1usize;
- x0 as f64;
- x1 as f64;
- x0 as f32;
- x1 as f32;
- 1isize as i32;
- 1isize as u32;
- 1usize as u32;
- 1usize as i32;
- // Casting to *size
- 1i64 as isize;
- 1i64 as usize;
- 1u64 as isize;
- 1u64 as usize;
- 1u32 as isize;
- 1u32 as usize; // Should not trigger any lint
- 1i32 as isize; // Neither should this
- 1i32 as usize;
- // Big integer literal to float
- 999_999_999 as f32;
- 3_999_999_999usize as f64;
-}
diff --git a/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs b/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs
index 27e03ebb7..d8101030a 100644
--- a/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![allow(clippy::let_unit_value, clippy::unnecessary_cast)]
fn main() {
@@ -7,10 +8,14 @@ fn main() {
// Because it's separate, it does not check the cast back to something of the same size
let a = r_x as *const [i32];
let b = a as *const [u8];
+ //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme
+ //~| NOTE: `#[deny(clippy::cast_slice_different_sizes)]` on by default
let c = b as *const [u32];
+ //~^ ERROR: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (eleme
// loses data
let loss = r_x as *const [i32] as *const [u8];
+ //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme
// Cast back to same size but different type loses no data, just type conversion
// This is weird code but there's no reason for this lint specifically to fire *twice* on it
@@ -18,7 +23,9 @@ fn main() {
// Check casting through blocks is detected
let loss_block_1 = { r_x as *const [i32] } as *const [u8];
+ //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme
let loss_block_2 = {
+ //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme
let _ = ();
r_x as *const [i32]
} as *const [u8];
@@ -36,6 +43,7 @@ fn main() {
// Check that the result of a long chain of casts is detected
let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8];
+ //~^ ERROR: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (eleme
let long_chain_restore =
r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8] as *const [u32];
}
@@ -51,32 +59,40 @@ fn foo2(x: *mut [u8]) -> *mut [u8] {
// Test that casts as part of function returns work
fn bar(x: *mut [u16]) -> *mut [u8] {
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s
x as *mut [u8]
}
fn uwu(x: *mut [u16]) -> *mut [u8] {
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s
x as *mut _
}
fn bar2(x: *mut [u16]) -> *mut [u8] {
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s
x as _
}
// constify
fn bar3(x: *mut [u16]) -> *const [u8] {
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s
x as _
}
// unconstify
fn bar4(x: *const [u16]) -> *mut [u8] {
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s
x as _
}
// function returns plus blocks
fn blocks(x: *mut [u16]) -> *mut [u8] {
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s
({ x }) as _
}
fn more_blocks(x: *mut [u16]) -> *mut [u8] {
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element s
{ ({ x }) as _ }
+ //~^ ERROR: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (eleme
}
diff --git a/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr b/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr
index 40721dcd0..a5c38e310 100644
--- a/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr
+++ b/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr
@@ -1,5 +1,5 @@
error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:9:13
+ --> $DIR/cast_slice_different_sizes.rs:10:13
|
LL | let b = a as *const [u8];
| ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(a as *const u8, ..)`
@@ -7,28 +7,29 @@ LL | let b = a as *const [u8];
= note: `#[deny(clippy::cast_slice_different_sizes)]` on by default
error: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (element size 4) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:10:13
+ --> $DIR/cast_slice_different_sizes.rs:13:13
|
LL | let c = b as *const [u32];
| ^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(b as *const u32, ..)`
error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:13:16
+ --> $DIR/cast_slice_different_sizes.rs:17:16
|
LL | let loss = r_x as *const [i32] as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)`
error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:20:24
+ --> $DIR/cast_slice_different_sizes.rs:25:24
|
LL | let loss_block_1 = { r_x as *const [i32] } as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts({ r_x as *const [i32] } as *const u8, ..)`
error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:21:24
+ --> $DIR/cast_slice_different_sizes.rs:27:24
|
LL | let loss_block_2 = {
| ________________________^
+LL | |
LL | | let _ = ();
LL | | r_x as *const [i32]
LL | | } as *const [u8];
@@ -37,82 +38,91 @@ LL | | } as *const [u8];
help: replace with `ptr::slice_from_raw_parts`
|
LL ~ let loss_block_2 = core::ptr::slice_from_raw_parts({
+LL +
LL + let _ = ();
LL + r_x as *const [i32]
LL ~ } as *const u8, ..);
|
error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:38:27
+ --> $DIR/cast_slice_different_sizes.rs:45:27
|
LL | let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:53:36
+ --> $DIR/cast_slice_different_sizes.rs:61:36
|
LL | fn bar(x: *mut [u16]) -> *mut [u8] {
| ____________________________________^
+LL | |
LL | | x as *mut [u8]
LL | | }
| |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:57:36
+ --> $DIR/cast_slice_different_sizes.rs:66:36
|
LL | fn uwu(x: *mut [u16]) -> *mut [u8] {
| ____________________________________^
+LL | |
LL | | x as *mut _
LL | | }
| |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:61:37
+ --> $DIR/cast_slice_different_sizes.rs:71:37
|
LL | fn bar2(x: *mut [u16]) -> *mut [u8] {
| _____________________________________^
+LL | |
LL | | x as _
LL | | }
| |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:66:39
+ --> $DIR/cast_slice_different_sizes.rs:77:39
|
LL | fn bar3(x: *mut [u16]) -> *const [u8] {
| _______________________________________^
+LL | |
LL | | x as _
LL | | }
| |_^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(x as *const u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:71:39
+ --> $DIR/cast_slice_different_sizes.rs:83:39
|
LL | fn bar4(x: *const [u16]) -> *mut [u8] {
| _______________________________________^
+LL | |
LL | | x as _
LL | | }
| |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:76:39
+ --> $DIR/cast_slice_different_sizes.rs:89:39
|
LL | fn blocks(x: *mut [u16]) -> *mut [u8] {
| _______________________________________^
+LL | |
LL | | ({ x }) as _
LL | | }
| |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:80:44
+ --> $DIR/cast_slice_different_sizes.rs:94:44
|
LL | fn more_blocks(x: *mut [u16]) -> *mut [u8] {
| ____________________________________________^
+LL | |
LL | | { ({ x }) as _ }
+LL | |
LL | | }
| |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`
error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
- --> $DIR/cast_slice_different_sizes.rs:81:5
+ --> $DIR/cast_slice_different_sizes.rs:96:5
|
LL | { ({ x }) as _ }
| ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`
diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed
index 13aadb7d3..05d5b3d10 100644
--- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed
+++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed
@@ -1,4 +1,4 @@
-//@run-rustfix
+
#![feature(stmt_expr_attributes)]
#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]
diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs
index 769c5d22b..bc29e2021 100644
--- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs
+++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs
@@ -1,4 +1,4 @@
-//@run-rustfix
+
#![feature(stmt_expr_attributes)]
#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]
diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr
index 524a2bf72..8816ce2d8 100644
--- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr
+++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr
@@ -5,6 +5,7 @@ LL | #[cfg_attr(rustfmt, rustfmt::skip)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]`
|
= note: `-D clippy::deprecated-cfg-attr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::deprecated_cfg_attr)]`
error: `cfg_attr` is deprecated for rustfmt and got replaced by tool attributes
--> $DIR/cfg_attr_rustfmt.rs:22:1
diff --git a/src/tools/clippy/tests/ui/cfg_features.fixed b/src/tools/clippy/tests/ui/cfg_features.fixed
new file mode 100644
index 000000000..3d52f2382
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cfg_features.fixed
@@ -0,0 +1,17 @@
+#![warn(clippy::maybe_misused_cfg)]
+
+fn main() {
+ #[cfg(feature = "not-really-a-feature")]
+ //~^ ERROR: feature may misspelled as features
+ //~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings`
+ let _ = 1 + 2;
+
+ #[cfg(all(feature = "right", feature = "wrong"))]
+ //~^ ERROR: feature may misspelled as features
+ let _ = 1 + 2;
+
+ #[cfg(all(feature = "wrong1", any(feature = "right", feature = "wrong2", feature, features)))]
+ //~^ ERROR: feature may misspelled as features
+ //~| ERROR: feature may misspelled as features
+ let _ = 1 + 2;
+}
diff --git a/src/tools/clippy/tests/ui/cfg_features.rs b/src/tools/clippy/tests/ui/cfg_features.rs
index bc4109c2c..a0344a004 100644
--- a/src/tools/clippy/tests/ui/cfg_features.rs
+++ b/src/tools/clippy/tests/ui/cfg_features.rs
@@ -2,11 +2,16 @@
fn main() {
#[cfg(features = "not-really-a-feature")]
+ //~^ ERROR: feature may misspelled as features
+ //~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings`
let _ = 1 + 2;
#[cfg(all(feature = "right", features = "wrong"))]
+ //~^ ERROR: feature may misspelled as features
let _ = 1 + 2;
#[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))]
+ //~^ ERROR: feature may misspelled as features
+ //~| ERROR: feature may misspelled as features
let _ = 1 + 2;
}
diff --git a/src/tools/clippy/tests/ui/cfg_features.stderr b/src/tools/clippy/tests/ui/cfg_features.stderr
index 00405985d..401c3e92e 100644
--- a/src/tools/clippy/tests/ui/cfg_features.stderr
+++ b/src/tools/clippy/tests/ui/cfg_features.stderr
@@ -5,21 +5,22 @@ LL | #[cfg(features = "not-really-a-feature")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `feature = "not-really-a-feature"`
|
= note: `-D clippy::maybe-misused-cfg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::maybe_misused_cfg)]`
error: feature may misspelled as features
- --> $DIR/cfg_features.rs:7:34
+ --> $DIR/cfg_features.rs:9:34
|
LL | #[cfg(all(feature = "right", features = "wrong"))]
| ^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong"`
error: feature may misspelled as features
- --> $DIR/cfg_features.rs:10:15
+ --> $DIR/cfg_features.rs:13:15
|
LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))]
| ^^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong1"`
error: feature may misspelled as features
- --> $DIR/cfg_features.rs:10:59
+ --> $DIR/cfg_features.rs:13:59
|
LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))]
| ^^^^^^^^^^^^^^^^^^^ help: use: `feature = "wrong2"`
diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8.rs b/src/tools/clippy/tests/ui/char_lit_as_u8.rs
index 0a53a3d64..7bb3daf0f 100644
--- a/src/tools/clippy/tests/ui/char_lit_as_u8.rs
+++ b/src/tools/clippy/tests/ui/char_lit_as_u8.rs
@@ -1,5 +1,8 @@
#![warn(clippy::char_lit_as_u8)]
fn main() {
- let _ = '❤' as u8; // no suggestion, since a byte literal won't work.
+ // no suggestion, since a byte literal won't work.
+ let _ = '❤' as u8;
+ //~^ ERROR: casting a character literal to `u8` truncates
+ //~| NOTE: `char` is four bytes wide, but `u8` is a single byte
}
diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr
index 39fc9d6dd..ce1f2f829 100644
--- a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr
+++ b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr
@@ -1,11 +1,12 @@
error: casting a character literal to `u8` truncates
- --> $DIR/char_lit_as_u8.rs:4:13
+ --> $DIR/char_lit_as_u8.rs:5:13
|
-LL | let _ = '❤' as u8; // no suggestion, since a byte literal won't work.
+LL | let _ = '❤' as u8;
| ^^^^^^^^^
|
= note: `char` is four bytes wide, but `u8` is a single byte
= note: `-D clippy::char-lit-as-u8` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::char_lit_as_u8)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed
index ce2f149dc..6f13078a3 100644
--- a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed
+++ b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::char_lit_as_u8)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs
index ffad12fc6..7737eb513 100644
--- a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs
+++ b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::char_lit_as_u8)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr
index 586174c50..359857119 100644
--- a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr
+++ b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr
@@ -1,33 +1,34 @@
error: casting a character literal to `u8` truncates
- --> $DIR/char_lit_as_u8_suggestions.rs:6:13
+ --> $DIR/char_lit_as_u8_suggestions.rs:4:13
|
LL | let _ = 'a' as u8;
| ^^^^^^^^^ help: use a byte literal instead: `b'a'`
|
= note: `char` is four bytes wide, but `u8` is a single byte
= note: `-D clippy::char-lit-as-u8` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::char_lit_as_u8)]`
error: casting a character literal to `u8` truncates
- --> $DIR/char_lit_as_u8_suggestions.rs:7:13
+ --> $DIR/char_lit_as_u8_suggestions.rs:5:13
|
-LL | let _ = '/n' as u8;
- | ^^^^^^^^^^ help: use a byte literal instead: `b'/n'`
+LL | let _ = '\n' as u8;
+ | ^^^^^^^^^^ help: use a byte literal instead: `b'\n'`
|
= note: `char` is four bytes wide, but `u8` is a single byte
error: casting a character literal to `u8` truncates
- --> $DIR/char_lit_as_u8_suggestions.rs:8:13
+ --> $DIR/char_lit_as_u8_suggestions.rs:6:13
|
-LL | let _ = '/0' as u8;
- | ^^^^^^^^^^ help: use a byte literal instead: `b'/0'`
+LL | let _ = '\0' as u8;
+ | ^^^^^^^^^^ help: use a byte literal instead: `b'\0'`
|
= note: `char` is four bytes wide, but `u8` is a single byte
error: casting a character literal to `u8` truncates
- --> $DIR/char_lit_as_u8_suggestions.rs:9:13
+ --> $DIR/char_lit_as_u8_suggestions.rs:7:13
|
-LL | let _ = '/x01' as u8;
- | ^^^^^^^^^^^^ help: use a byte literal instead: `b'/x01'`
+LL | let _ = '\x01' as u8;
+ | ^^^^^^^^^^^^ help: use a byte literal instead: `b'\x01'`
|
= note: `char` is four bytes wide, but `u8` is a single byte
diff --git a/src/tools/clippy/tests/ui/checked_conversions.fixed b/src/tools/clippy/tests/ui/checked_conversions.fixed
index 188e6d975..0e05a2742 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.fixed
+++ b/src/tools/clippy/tests/ui/checked_conversions.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
clippy::cast_lossless,
unused,
diff --git a/src/tools/clippy/tests/ui/checked_conversions.rs b/src/tools/clippy/tests/ui/checked_conversions.rs
index 70f0f0975..ac7826992 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.rs
+++ b/src/tools/clippy/tests/ui/checked_conversions.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
clippy::cast_lossless,
unused,
diff --git a/src/tools/clippy/tests/ui/checked_conversions.stderr b/src/tools/clippy/tests/ui/checked_conversions.stderr
index 273ead73b..3e0169b74 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.stderr
+++ b/src/tools/clippy/tests/ui/checked_conversions.stderr
@@ -1,103 +1,104 @@
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:16:13
+ --> $DIR/checked_conversions.rs:14:13
|
LL | let _ = value <= (u32::max_value() as i64) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
|
= note: `-D clippy::checked-conversions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::checked_conversions)]`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:17:13
+ --> $DIR/checked_conversions.rs:15:13
|
LL | let _ = value <= (u32::MAX as i64) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:21:13
+ --> $DIR/checked_conversions.rs:19:13
|
LL | let _ = value <= i64::from(u16::max_value()) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:22:13
+ --> $DIR/checked_conversions.rs:20:13
|
LL | let _ = value <= i64::from(u16::MAX) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:26:13
+ --> $DIR/checked_conversions.rs:24:13
|
LL | let _ = value <= (u8::max_value() as isize) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:27:13
+ --> $DIR/checked_conversions.rs:25:13
|
LL | let _ = value <= (u8::MAX as isize) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:33:13
+ --> $DIR/checked_conversions.rs:31:13
|
LL | let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:34:13
+ --> $DIR/checked_conversions.rs:32:13
|
LL | let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:38:13
+ --> $DIR/checked_conversions.rs:36:13
|
LL | let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:39:13
+ --> $DIR/checked_conversions.rs:37:13
|
LL | let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:45:13
+ --> $DIR/checked_conversions.rs:43:13
|
LL | let _ = value <= i32::max_value() as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:46:13
+ --> $DIR/checked_conversions.rs:44:13
|
LL | let _ = value <= i32::MAX as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:50:13
+ --> $DIR/checked_conversions.rs:48:13
|
LL | let _ = value <= isize::max_value() as usize && value as i32 == 5;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:51:13
+ --> $DIR/checked_conversions.rs:49:13
|
LL | let _ = value <= isize::MAX as usize && value as i32 == 5;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:55:13
+ --> $DIR/checked_conversions.rs:53:13
|
LL | let _ = value <= u16::max_value() as u32 && value as i32 == 5;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:56:13
+ --> $DIR/checked_conversions.rs:54:13
|
LL | let _ = value <= u16::MAX as u32 && value as i32 == 5;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:89:13
+ --> $DIR/checked_conversions.rs:87:13
|
LL | let _ = value <= (u32::MAX as i64) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.rs b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.rs
index 16e54a7d9..323dae380 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.rs
+++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.rs
@@ -9,10 +9,18 @@ fn test_complex_conditions() {
let x: Result<(), ()> = Ok(());
let y: Result<(), ()> = Ok(());
if x.is_ok() && y.is_err() {
- x.unwrap(); // unnecessary
- x.unwrap_err(); // will panic
- y.unwrap(); // will panic
- y.unwrap_err(); // unnecessary
+ // unnecessary
+ x.unwrap();
+ //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_ok`
+ // will panic
+ x.unwrap_err();
+ //~^ ERROR: this call to `unwrap_err()` will always panic
+ // will panic
+ y.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // unnecessary
+ y.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `y` after checking its variant with `is_err`
} else {
// not statically determinable whether any of the following will always succeed or always fail:
x.unwrap();
@@ -26,19 +34,39 @@ fn test_complex_conditions() {
x.unwrap();
y.unwrap();
} else {
- x.unwrap(); // will panic
- x.unwrap_err(); // unnecessary
- y.unwrap(); // will panic
- y.unwrap_err(); // unnecessary
+ // will panic
+ x.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // unnecessary
+ x.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_ok`
+ // will panic
+ y.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // unnecessary
+ y.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `y` after checking its variant with `is_ok`
}
let z: Result<(), ()> = Ok(());
if x.is_ok() && !(y.is_ok() || z.is_err()) {
- x.unwrap(); // unnecessary
- x.unwrap_err(); // will panic
- y.unwrap(); // will panic
- y.unwrap_err(); // unnecessary
- z.unwrap(); // unnecessary
- z.unwrap_err(); // will panic
+ // unnecessary
+ x.unwrap();
+ //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_ok`
+ // will panic
+ x.unwrap_err();
+ //~^ ERROR: this call to `unwrap_err()` will always panic
+ // will panic
+ y.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // unnecessary
+ y.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `y` after checking its variant with `is_ok`
+ // unnecessary
+ z.unwrap();
+ //~^ ERROR: called `unwrap` on `z` after checking its variant with `is_err`
+ // will panic
+ z.unwrap_err();
+ //~^ ERROR: this call to `unwrap_err()` will always panic
}
if x.is_ok() || !(y.is_ok() && z.is_err()) {
// not statically determinable whether any of the following will always succeed or always fail:
@@ -46,12 +74,24 @@ fn test_complex_conditions() {
y.unwrap();
z.unwrap();
} else {
- x.unwrap(); // will panic
- x.unwrap_err(); // unnecessary
- y.unwrap(); // unnecessary
- y.unwrap_err(); // will panic
- z.unwrap(); // will panic
- z.unwrap_err(); // unnecessary
+ // will panic
+ x.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // unnecessary
+ x.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_ok`
+ // unnecessary
+ y.unwrap();
+ //~^ ERROR: called `unwrap` on `y` after checking its variant with `is_ok`
+ // will panic
+ y.unwrap_err();
+ //~^ ERROR: this call to `unwrap_err()` will always panic
+ // will panic
+ z.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // unnecessary
+ z.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `z` after checking its variant with `is_err`
}
}
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr
index c395c5ba0..73c074a93 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr
@@ -1,9 +1,10 @@
error: called `unwrap` on `x` after checking its variant with `is_ok`
- --> $DIR/complex_conditionals.rs:12:9
+ --> $DIR/complex_conditionals.rs:13:9
|
LL | if x.is_ok() && y.is_err() {
| --------- the check is happening here
-LL | x.unwrap(); // unnecessary
+LL | // unnecessary
+LL | x.unwrap();
| ^^^^^^^^^^
|
= help: try using `if let` or `match`
@@ -14,12 +15,12 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap_err()` will always panic
- --> $DIR/complex_conditionals.rs:13:9
+ --> $DIR/complex_conditionals.rs:16:9
|
LL | if x.is_ok() && y.is_err() {
| --------- because of this check
-LL | x.unwrap(); // unnecessary
-LL | x.unwrap_err(); // will panic
+...
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
|
note: the lint level is defined here
@@ -29,180 +30,181 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/complex_conditionals.rs:14:9
+ --> $DIR/complex_conditionals.rs:19:9
|
LL | if x.is_ok() && y.is_err() {
| ---------- because of this check
...
-LL | y.unwrap(); // will panic
+LL | y.unwrap();
| ^^^^^^^^^^
error: called `unwrap_err` on `y` after checking its variant with `is_err`
- --> $DIR/complex_conditionals.rs:15:9
+ --> $DIR/complex_conditionals.rs:22:9
|
LL | if x.is_ok() && y.is_err() {
| ---------- the check is happening here
...
-LL | y.unwrap_err(); // unnecessary
+LL | y.unwrap_err();
| ^^^^^^^^^^^^^^
|
= help: try using `if let` or `match`
error: this call to `unwrap()` will always panic
- --> $DIR/complex_conditionals.rs:29:9
+ --> $DIR/complex_conditionals.rs:38:9
|
LL | if x.is_ok() || y.is_ok() {
| --------- because of this check
...
-LL | x.unwrap(); // will panic
+LL | x.unwrap();
| ^^^^^^^^^^
error: called `unwrap_err` on `x` after checking its variant with `is_ok`
- --> $DIR/complex_conditionals.rs:30:9
+ --> $DIR/complex_conditionals.rs:41:9
|
LL | if x.is_ok() || y.is_ok() {
| --------- the check is happening here
...
-LL | x.unwrap_err(); // unnecessary
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
|
= help: try using `if let` or `match`
error: this call to `unwrap()` will always panic
- --> $DIR/complex_conditionals.rs:31:9
+ --> $DIR/complex_conditionals.rs:44:9
|
LL | if x.is_ok() || y.is_ok() {
| --------- because of this check
...
-LL | y.unwrap(); // will panic
+LL | y.unwrap();
| ^^^^^^^^^^
error: called `unwrap_err` on `y` after checking its variant with `is_ok`
- --> $DIR/complex_conditionals.rs:32:9
+ --> $DIR/complex_conditionals.rs:47:9
|
LL | if x.is_ok() || y.is_ok() {
| --------- the check is happening here
...
-LL | y.unwrap_err(); // unnecessary
+LL | y.unwrap_err();
| ^^^^^^^^^^^^^^
|
= help: try using `if let` or `match`
error: called `unwrap` on `x` after checking its variant with `is_ok`
- --> $DIR/complex_conditionals.rs:36:9
+ --> $DIR/complex_conditionals.rs:53:9
|
LL | if x.is_ok() && !(y.is_ok() || z.is_err()) {
| --------- the check is happening here
-LL | x.unwrap(); // unnecessary
+LL | // unnecessary
+LL | x.unwrap();
| ^^^^^^^^^^
|
= help: try using `if let` or `match`
error: this call to `unwrap_err()` will always panic
- --> $DIR/complex_conditionals.rs:37:9
+ --> $DIR/complex_conditionals.rs:56:9
|
LL | if x.is_ok() && !(y.is_ok() || z.is_err()) {
| --------- because of this check
-LL | x.unwrap(); // unnecessary
-LL | x.unwrap_err(); // will panic
+...
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/complex_conditionals.rs:38:9
+ --> $DIR/complex_conditionals.rs:59:9
|
LL | if x.is_ok() && !(y.is_ok() || z.is_err()) {
| --------- because of this check
...
-LL | y.unwrap(); // will panic
+LL | y.unwrap();
| ^^^^^^^^^^
error: called `unwrap_err` on `y` after checking its variant with `is_ok`
- --> $DIR/complex_conditionals.rs:39:9
+ --> $DIR/complex_conditionals.rs:62:9
|
LL | if x.is_ok() && !(y.is_ok() || z.is_err()) {
| --------- the check is happening here
...
-LL | y.unwrap_err(); // unnecessary
+LL | y.unwrap_err();
| ^^^^^^^^^^^^^^
|
= help: try using `if let` or `match`
error: called `unwrap` on `z` after checking its variant with `is_err`
- --> $DIR/complex_conditionals.rs:40:9
+ --> $DIR/complex_conditionals.rs:65:9
|
LL | if x.is_ok() && !(y.is_ok() || z.is_err()) {
| ---------- the check is happening here
...
-LL | z.unwrap(); // unnecessary
+LL | z.unwrap();
| ^^^^^^^^^^
|
= help: try using `if let` or `match`
error: this call to `unwrap_err()` will always panic
- --> $DIR/complex_conditionals.rs:41:9
+ --> $DIR/complex_conditionals.rs:68:9
|
LL | if x.is_ok() && !(y.is_ok() || z.is_err()) {
| ---------- because of this check
...
-LL | z.unwrap_err(); // will panic
+LL | z.unwrap_err();
| ^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/complex_conditionals.rs:49:9
+ --> $DIR/complex_conditionals.rs:78:9
|
LL | if x.is_ok() || !(y.is_ok() && z.is_err()) {
| --------- because of this check
...
-LL | x.unwrap(); // will panic
+LL | x.unwrap();
| ^^^^^^^^^^
error: called `unwrap_err` on `x` after checking its variant with `is_ok`
- --> $DIR/complex_conditionals.rs:50:9
+ --> $DIR/complex_conditionals.rs:81:9
|
LL | if x.is_ok() || !(y.is_ok() && z.is_err()) {
| --------- the check is happening here
...
-LL | x.unwrap_err(); // unnecessary
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
|
= help: try using `if let` or `match`
error: called `unwrap` on `y` after checking its variant with `is_ok`
- --> $DIR/complex_conditionals.rs:51:9
+ --> $DIR/complex_conditionals.rs:84:9
|
LL | if x.is_ok() || !(y.is_ok() && z.is_err()) {
| --------- the check is happening here
...
-LL | y.unwrap(); // unnecessary
+LL | y.unwrap();
| ^^^^^^^^^^
|
= help: try using `if let` or `match`
error: this call to `unwrap_err()` will always panic
- --> $DIR/complex_conditionals.rs:52:9
+ --> $DIR/complex_conditionals.rs:87:9
|
LL | if x.is_ok() || !(y.is_ok() && z.is_err()) {
| --------- because of this check
...
-LL | y.unwrap_err(); // will panic
+LL | y.unwrap_err();
| ^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/complex_conditionals.rs:53:9
+ --> $DIR/complex_conditionals.rs:90:9
|
LL | if x.is_ok() || !(y.is_ok() && z.is_err()) {
| ---------- because of this check
...
-LL | z.unwrap(); // will panic
+LL | z.unwrap();
| ^^^^^^^^^^
error: called `unwrap_err` on `z` after checking its variant with `is_err`
- --> $DIR/complex_conditionals.rs:54:9
+ --> $DIR/complex_conditionals.rs:93:9
|
LL | if x.is_ok() || !(y.is_ok() && z.is_err()) {
| ---------- the check is happening here
...
-LL | z.unwrap_err(); // unnecessary
+LL | z.unwrap_err();
| ^^^^^^^^^^^^^^
|
= help: try using `if let` or `match`
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.rs b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.rs
index e417cf833..68923793d 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.rs
+++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.rs
@@ -4,14 +4,18 @@
clippy::branches_sharing_code,
clippy::unnecessary_literal_unwrap
)]
-
+//@no-rustfix
fn test_nested() {
fn nested() {
let x = Some(());
if x.is_some() {
- x.unwrap(); // unnecessary
+ // unnecessary
+ x.unwrap();
+ //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_some`
} else {
- x.unwrap(); // will panic
+ // will panic
+ x.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
}
}
}
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
index 049a69d93..d9f701a5b 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
@@ -1,9 +1,10 @@
error: called `unwrap` on `x` after checking its variant with `is_some`
- --> $DIR/complex_conditionals_nested.rs:12:13
+ --> $DIR/complex_conditionals_nested.rs:13:13
|
LL | if x.is_some() {
| -------------- help: try: `if let Some(..) = x`
-LL | x.unwrap(); // unnecessary
+LL | // unnecessary
+LL | x.unwrap();
| ^^^^^^^^^^
|
note: the lint level is defined here
@@ -13,12 +14,12 @@ LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/complex_conditionals_nested.rs:14:13
+ --> $DIR/complex_conditionals_nested.rs:17:13
|
LL | if x.is_some() {
| ----------- because of this check
...
-LL | x.unwrap(); // will panic
+LL | x.unwrap();
| ^^^^^^^^^^
|
note: the lint level is defined here
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.rs b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.rs
index 61042bb90..02f80cc52 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.rs
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![feature(lint_reasons)]
#![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
#![allow(
@@ -9,7 +10,8 @@
macro_rules! m {
($a:expr) => {
if $a.is_some() {
- $a.unwrap(); // unnecessary
+ // unnecessary
+ $a.unwrap();
}
};
}
@@ -41,37 +43,72 @@ macro_rules! checks_some {
fn main() {
let x = Some(());
if x.is_some() {
- x.unwrap(); // unnecessary
- x.expect("an error message"); // unnecessary
+ // unnecessary
+ x.unwrap();
+ //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_some`
+ // unnecessary
+ x.expect("an error message");
+ //~^ ERROR: called `expect` on `x` after checking its variant with `is_some`
} else {
- x.unwrap(); // will panic
- x.expect("an error message"); // will panic
+ // will panic
+ x.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // will panic
+ x.expect("an error message");
+ //~^ ERROR: this call to `expect()` will always panic
}
if x.is_none() {
- x.unwrap(); // will panic
+ // will panic
+ x.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
} else {
- x.unwrap(); // unnecessary
+ // unnecessary
+ x.unwrap();
+ //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_none`
}
m!(x);
- checks_in_param!(x.is_some(), x.unwrap()); // ok
- checks_unwrap!(x, x.unwrap()); // ok
- checks_some!(x.is_some(), x); // ok
+ // ok
+ checks_in_param!(x.is_some(), x.unwrap());
+ // ok
+ checks_unwrap!(x, x.unwrap());
+ // ok
+ checks_some!(x.is_some(), x);
let mut x: Result<(), ()> = Ok(());
if x.is_ok() {
- x.unwrap(); // unnecessary
- x.expect("an error message"); // unnecessary
- x.unwrap_err(); // will panic
+ // unnecessary
+ x.unwrap();
+ //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_ok`
+ // unnecessary
+ x.expect("an error message");
+ //~^ ERROR: called `expect` on `x` after checking its variant with `is_ok`
+ // will panic
+ x.unwrap_err();
+ //~^ ERROR: this call to `unwrap_err()` will always panic
} else {
- x.unwrap(); // will panic
- x.expect("an error message"); // will panic
- x.unwrap_err(); // unnecessary
+ // will panic
+ x.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // will panic
+ x.expect("an error message");
+ //~^ ERROR: this call to `expect()` will always panic
+ // unnecessary
+ x.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_ok`
}
if x.is_err() {
- x.unwrap(); // will panic
- x.unwrap_err(); // unnecessary
+ // will panic
+ x.unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ // unnecessary
+ x.unwrap_err();
+ //~^ ERROR: called `unwrap_err` on `x` after checking its variant with `is_err`
} else {
- x.unwrap(); // unnecessary
- x.unwrap_err(); // will panic
+ // unnecessary
+ x.unwrap();
+ //~^ ERROR: called `unwrap` on `x` after checking its variant with `is_err`
+ // will panic
+ x.unwrap_err();
+ //~^ ERROR: this call to `unwrap_err()` will always panic
}
if x.is_ok() {
x = Err(());
@@ -87,20 +124,76 @@ fn main() {
x.unwrap_err();
}
- assert!(x.is_ok(), "{:?}", x.unwrap_err()); // ok, it's a common test pattern
+ // ok, it's a common test pattern
+ assert!(x.is_ok(), "{:?}", x.unwrap_err());
+}
+
+fn issue11371() {
+ let option = Some(());
+
+ if option.is_some() {
+ option.as_ref().unwrap();
+ //~^ ERROR: called `unwrap` on `option` after checking its variant with `is_some`
+ } else {
+ option.as_ref().unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ }
+
+ let result = Ok::<(), ()>(());
+
+ if result.is_ok() {
+ result.as_ref().unwrap();
+ //~^ ERROR: called `unwrap` on `result` after checking its variant with `is_ok`
+ } else {
+ result.as_ref().unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ }
+
+ let mut option = Some(());
+ if option.is_some() {
+ option.as_mut().unwrap();
+ //~^ ERROR: called `unwrap` on `option` after checking its variant with `is_some`
+ } else {
+ option.as_mut().unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ }
+
+ let mut result = Ok::<(), ()>(());
+ if result.is_ok() {
+ result.as_mut().unwrap();
+ //~^ ERROR: called `unwrap` on `result` after checking its variant with `is_ok`
+ } else {
+ result.as_mut().unwrap();
+ //~^ ERROR: this call to `unwrap()` will always panic
+ }
+
+ // This should not lint. Statics are, at the time of writing, not linted on anyway,
+ // but if at some point they are supported by this lint, it should correctly see that
+ // `X` is being mutated and not suggest `if let Some(..) = X {}`
+ static mut X: Option<i32> = Some(123);
+ unsafe {
+ if X.is_some() {
+ X = None;
+ X.unwrap();
+ }
+ }
}
fn check_expect() {
let x = Some(());
if x.is_some() {
#[expect(clippy::unnecessary_unwrap)]
- x.unwrap(); // unnecessary
+ // unnecessary
+ x.unwrap();
#[expect(clippy::unnecessary_unwrap)]
- x.expect("an error message"); // unnecessary
+ // unnecessary
+ x.expect("an error message");
} else {
#[expect(clippy::panicking_unwrap)]
- x.unwrap(); // will panic
+ // will panic
+ x.unwrap();
#[expect(clippy::panicking_unwrap)]
- x.expect("an error message"); // will panic
+ // will panic
+ x.expect("an error message");
}
}
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
index 93809f655..a5afbba73 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
@@ -1,73 +1,76 @@
error: called `unwrap` on `x` after checking its variant with `is_some`
- --> $DIR/simple_conditionals.rs:44:9
+ --> $DIR/simple_conditionals.rs:47:9
|
LL | if x.is_some() {
| -------------- help: try: `if let Some(..) = x`
-LL | x.unwrap(); // unnecessary
+LL | // unnecessary
+LL | x.unwrap();
| ^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/simple_conditionals.rs:2:35
+ --> $DIR/simple_conditionals.rs:3:35
|
LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `expect` on `x` after checking its variant with `is_some`
- --> $DIR/simple_conditionals.rs:45:9
+ --> $DIR/simple_conditionals.rs:50:9
|
LL | if x.is_some() {
| -------------- help: try: `if let Some(..) = x`
-LL | x.unwrap(); // unnecessary
-LL | x.expect("an error message"); // unnecessary
+...
+LL | x.expect("an error message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/simple_conditionals.rs:47:9
+ --> $DIR/simple_conditionals.rs:54:9
|
LL | if x.is_some() {
| ----------- because of this check
...
-LL | x.unwrap(); // will panic
+LL | x.unwrap();
| ^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/simple_conditionals.rs:2:9
+ --> $DIR/simple_conditionals.rs:3:9
|
LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `expect()` will always panic
- --> $DIR/simple_conditionals.rs:48:9
+ --> $DIR/simple_conditionals.rs:57:9
|
LL | if x.is_some() {
| ----------- because of this check
...
-LL | x.expect("an error message"); // will panic
+LL | x.expect("an error message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/simple_conditionals.rs:51:9
+ --> $DIR/simple_conditionals.rs:62:9
|
LL | if x.is_none() {
| ----------- because of this check
-LL | x.unwrap(); // will panic
+LL | // will panic
+LL | x.unwrap();
| ^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_none`
- --> $DIR/simple_conditionals.rs:53:9
+ --> $DIR/simple_conditionals.rs:66:9
|
LL | if x.is_none() {
| -------------- help: try: `if let Some(..) = x`
...
-LL | x.unwrap(); // unnecessary
+LL | x.unwrap();
| ^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_some`
- --> $DIR/simple_conditionals.rs:12:13
+ --> $DIR/simple_conditionals.rs:14:13
|
LL | if $a.is_some() {
| --------------- help: try: `if let Some(..) = x`
-LL | $a.unwrap(); // unnecessary
+LL | // unnecessary
+LL | $a.unwrap();
| ^^^^^^^^^^^
...
LL | m!(x);
@@ -76,92 +79,162 @@ LL | m!(x);
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
error: called `unwrap` on `x` after checking its variant with `is_ok`
- --> $DIR/simple_conditionals.rs:61:9
+ --> $DIR/simple_conditionals.rs:79:9
|
LL | if x.is_ok() {
| ------------ help: try: `if let Ok(..) = x`
-LL | x.unwrap(); // unnecessary
+LL | // unnecessary
+LL | x.unwrap();
| ^^^^^^^^^^
error: called `expect` on `x` after checking its variant with `is_ok`
- --> $DIR/simple_conditionals.rs:62:9
+ --> $DIR/simple_conditionals.rs:82:9
|
LL | if x.is_ok() {
| ------------ help: try: `if let Ok(..) = x`
-LL | x.unwrap(); // unnecessary
-LL | x.expect("an error message"); // unnecessary
+...
+LL | x.expect("an error message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call to `unwrap_err()` will always panic
- --> $DIR/simple_conditionals.rs:63:9
+ --> $DIR/simple_conditionals.rs:85:9
|
LL | if x.is_ok() {
| --------- because of this check
...
-LL | x.unwrap_err(); // will panic
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/simple_conditionals.rs:65:9
+ --> $DIR/simple_conditionals.rs:89:9
|
LL | if x.is_ok() {
| --------- because of this check
...
-LL | x.unwrap(); // will panic
+LL | x.unwrap();
| ^^^^^^^^^^
error: this call to `expect()` will always panic
- --> $DIR/simple_conditionals.rs:66:9
+ --> $DIR/simple_conditionals.rs:92:9
|
LL | if x.is_ok() {
| --------- because of this check
...
-LL | x.expect("an error message"); // will panic
+LL | x.expect("an error message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `unwrap_err` on `x` after checking its variant with `is_ok`
- --> $DIR/simple_conditionals.rs:67:9
+ --> $DIR/simple_conditionals.rs:95:9
|
LL | if x.is_ok() {
| ------------ help: try: `if let Err(..) = x`
...
-LL | x.unwrap_err(); // unnecessary
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
error: this call to `unwrap()` will always panic
- --> $DIR/simple_conditionals.rs:70:9
+ --> $DIR/simple_conditionals.rs:100:9
|
LL | if x.is_err() {
| ---------- because of this check
-LL | x.unwrap(); // will panic
+LL | // will panic
+LL | x.unwrap();
| ^^^^^^^^^^
error: called `unwrap_err` on `x` after checking its variant with `is_err`
- --> $DIR/simple_conditionals.rs:71:9
+ --> $DIR/simple_conditionals.rs:103:9
|
LL | if x.is_err() {
| ------------- help: try: `if let Err(..) = x`
-LL | x.unwrap(); // will panic
-LL | x.unwrap_err(); // unnecessary
+...
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
error: called `unwrap` on `x` after checking its variant with `is_err`
- --> $DIR/simple_conditionals.rs:73:9
+ --> $DIR/simple_conditionals.rs:107:9
|
LL | if x.is_err() {
| ------------- help: try: `if let Ok(..) = x`
...
-LL | x.unwrap(); // unnecessary
+LL | x.unwrap();
| ^^^^^^^^^^
error: this call to `unwrap_err()` will always panic
- --> $DIR/simple_conditionals.rs:74:9
+ --> $DIR/simple_conditionals.rs:110:9
|
LL | if x.is_err() {
| ---------- because of this check
...
-LL | x.unwrap_err(); // will panic
+LL | x.unwrap_err();
| ^^^^^^^^^^^^^^
-error: aborting due to 17 previous errors
+error: called `unwrap` on `option` after checking its variant with `is_some`
+ --> $DIR/simple_conditionals.rs:135:9
+ |
+LL | if option.is_some() {
+ | ------------------- help: try: `if let Some(..) = &option`
+LL | option.as_ref().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: this call to `unwrap()` will always panic
+ --> $DIR/simple_conditionals.rs:138:9
+ |
+LL | if option.is_some() {
+ | ---------------- because of this check
+...
+LL | option.as_ref().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: called `unwrap` on `result` after checking its variant with `is_ok`
+ --> $DIR/simple_conditionals.rs:145:9
+ |
+LL | if result.is_ok() {
+ | ----------------- help: try: `if let Ok(..) = &result`
+LL | result.as_ref().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: this call to `unwrap()` will always panic
+ --> $DIR/simple_conditionals.rs:148:9
+ |
+LL | if result.is_ok() {
+ | -------------- because of this check
+...
+LL | result.as_ref().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: called `unwrap` on `option` after checking its variant with `is_some`
+ --> $DIR/simple_conditionals.rs:154:9
+ |
+LL | if option.is_some() {
+ | ------------------- help: try: `if let Some(..) = &mut option`
+LL | option.as_mut().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: this call to `unwrap()` will always panic
+ --> $DIR/simple_conditionals.rs:157:9
+ |
+LL | if option.is_some() {
+ | ---------------- because of this check
+...
+LL | option.as_mut().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: called `unwrap` on `result` after checking its variant with `is_ok`
+ --> $DIR/simple_conditionals.rs:163:9
+ |
+LL | if result.is_ok() {
+ | ----------------- help: try: `if let Ok(..) = &mut result`
+LL | result.as_mut().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: this call to `unwrap()` will always panic
+ --> $DIR/simple_conditionals.rs:166:9
+ |
+LL | if result.is_ok() {
+ | -------------- because of this check
+...
+LL | result.as_mut().unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 25 previous errors
diff --git a/src/tools/clippy/tests/ui/clear_with_drain.fixed b/src/tools/clippy/tests/ui/clear_with_drain.fixed
index b68c7d867..15777a4ea 100644
--- a/src/tools/clippy/tests/ui/clear_with_drain.fixed
+++ b/src/tools/clippy/tests/ui/clear_with_drain.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::clear_with_drain)]
diff --git a/src/tools/clippy/tests/ui/clear_with_drain.rs b/src/tools/clippy/tests/ui/clear_with_drain.rs
index 0f6562eca..1dea7235e 100644
--- a/src/tools/clippy/tests/ui/clear_with_drain.rs
+++ b/src/tools/clippy/tests/ui/clear_with_drain.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::clear_with_drain)]
diff --git a/src/tools/clippy/tests/ui/clear_with_drain.stderr b/src/tools/clippy/tests/ui/clear_with_drain.stderr
index 20158da11..b1a381256 100644
--- a/src/tools/clippy/tests/ui/clear_with_drain.stderr
+++ b/src/tools/clippy/tests/ui/clear_with_drain.stderr
@@ -1,127 +1,128 @@
error: `drain` used to clear a `Vec`
- --> $DIR/clear_with_drain.rs:23:7
+ --> $DIR/clear_with_drain.rs:22:7
|
LL | v.drain(0..v.len());
| ^^^^^^^^^^^^^^^^^ help: try: `clear()`
|
= note: `-D clippy::clear-with-drain` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::clear_with_drain)]`
error: `drain` used to clear a `Vec`
- --> $DIR/clear_with_drain.rs:27:7
+ --> $DIR/clear_with_drain.rs:26:7
|
LL | v.drain(usize::MIN..v.len());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `Vec`
- --> $DIR/clear_with_drain.rs:46:7
+ --> $DIR/clear_with_drain.rs:45:7
|
LL | v.drain(0..);
| ^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `Vec`
- --> $DIR/clear_with_drain.rs:50:7
+ --> $DIR/clear_with_drain.rs:49:7
|
LL | v.drain(usize::MIN..);
| ^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `Vec`
- --> $DIR/clear_with_drain.rs:66:7
+ --> $DIR/clear_with_drain.rs:65:7
|
LL | v.drain(..);
| ^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `Vec`
- --> $DIR/clear_with_drain.rs:83:7
+ --> $DIR/clear_with_drain.rs:82:7
|
LL | v.drain(..v.len());
| ^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `VecDeque`
- --> $DIR/clear_with_drain.rs:121:11
+ --> $DIR/clear_with_drain.rs:120:11
|
LL | deque.drain(0..deque.len());
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `VecDeque`
- --> $DIR/clear_with_drain.rs:125:11
+ --> $DIR/clear_with_drain.rs:124:11
|
LL | deque.drain(usize::MIN..deque.len());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `VecDeque`
- --> $DIR/clear_with_drain.rs:144:11
+ --> $DIR/clear_with_drain.rs:143:11
|
LL | deque.drain(0..);
| ^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `VecDeque`
- --> $DIR/clear_with_drain.rs:148:11
+ --> $DIR/clear_with_drain.rs:147:11
|
LL | deque.drain(usize::MIN..);
| ^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `VecDeque`
- --> $DIR/clear_with_drain.rs:164:11
+ --> $DIR/clear_with_drain.rs:163:11
|
LL | deque.drain(..);
| ^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `VecDeque`
- --> $DIR/clear_with_drain.rs:181:11
+ --> $DIR/clear_with_drain.rs:180:11
|
LL | deque.drain(..deque.len());
| ^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `String`
- --> $DIR/clear_with_drain.rs:219:7
+ --> $DIR/clear_with_drain.rs:218:7
|
LL | s.drain(0..s.len());
| ^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `String`
- --> $DIR/clear_with_drain.rs:223:7
+ --> $DIR/clear_with_drain.rs:222:7
|
LL | s.drain(usize::MIN..s.len());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `String`
- --> $DIR/clear_with_drain.rs:242:7
+ --> $DIR/clear_with_drain.rs:241:7
|
LL | s.drain(0..);
| ^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `String`
- --> $DIR/clear_with_drain.rs:246:7
+ --> $DIR/clear_with_drain.rs:245:7
|
LL | s.drain(usize::MIN..);
| ^^^^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `String`
- --> $DIR/clear_with_drain.rs:262:7
+ --> $DIR/clear_with_drain.rs:261:7
|
LL | s.drain(..);
| ^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `String`
- --> $DIR/clear_with_drain.rs:279:7
+ --> $DIR/clear_with_drain.rs:278:7
|
LL | s.drain(..s.len());
| ^^^^^^^^^^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `HashSet`
- --> $DIR/clear_with_drain.rs:317:9
+ --> $DIR/clear_with_drain.rs:316:9
|
LL | set.drain();
| ^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `HashMap`
- --> $DIR/clear_with_drain.rs:336:9
+ --> $DIR/clear_with_drain.rs:335:9
|
LL | map.drain();
| ^^^^^^^ help: try: `clear()`
error: `drain` used to clear a `BinaryHeap`
- --> $DIR/clear_with_drain.rs:355:10
+ --> $DIR/clear_with_drain.rs:354:10
|
LL | heap.drain();
| ^^^^^^^ help: try: `clear()`
diff --git a/src/tools/clippy/tests/ui/clone_on_copy.fixed b/src/tools/clippy/tests/ui/clone_on_copy.fixed
index a72071158..9d9a5bf20 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy.fixed
+++ b/src/tools/clippy/tests/ui/clone_on_copy.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
unused,
clippy::redundant_clone,
diff --git a/src/tools/clippy/tests/ui/clone_on_copy.rs b/src/tools/clippy/tests/ui/clone_on_copy.rs
index 2c5fac8fa..305bc6816 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy.rs
+++ b/src/tools/clippy/tests/ui/clone_on_copy.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
unused,
clippy::redundant_clone,
diff --git a/src/tools/clippy/tests/ui/clone_on_copy.stderr b/src/tools/clippy/tests/ui/clone_on_copy.stderr
index 862234d20..0526c2f5a 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy.stderr
+++ b/src/tools/clippy/tests/ui/clone_on_copy.stderr
@@ -1,55 +1,56 @@
error: using `clone` on type `i32` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:25:5
+ --> $DIR/clone_on_copy.rs:23:5
|
LL | 42.clone();
| ^^^^^^^^^^ help: try removing the `clone` call: `42`
|
= note: `-D clippy::clone-on-copy` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::clone_on_copy)]`
error: using `clone` on type `i32` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:29:5
+ --> $DIR/clone_on_copy.rs:27:5
|
LL | (&42).clone();
| ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)`
error: using `clone` on type `i32` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:32:5
+ --> $DIR/clone_on_copy.rs:30:5
|
LL | rc.borrow().clone();
| ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()`
error: using `clone` on type `u32` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:35:5
+ --> $DIR/clone_on_copy.rs:33:5
|
LL | x.clone().rotate_left(1);
| ^^^^^^^^^ help: try removing the `clone` call: `x`
error: using `clone` on type `i32` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:49:5
+ --> $DIR/clone_on_copy.rs:47:5
|
LL | m!(42).clone();
| ^^^^^^^^^^^^^^ help: try removing the `clone` call: `m!(42)`
error: using `clone` on type `[u32; 2]` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:59:5
+ --> $DIR/clone_on_copy.rs:57:5
|
LL | x.clone()[0];
| ^^^^^^^^^ help: try dereferencing it: `(*x)`
error: using `clone` on type `char` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:69:14
+ --> $DIR/clone_on_copy.rs:67:14
|
LL | is_ascii('z'.clone());
| ^^^^^^^^^^^ help: try removing the `clone` call: `'z'`
error: using `clone` on type `i32` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:73:14
+ --> $DIR/clone_on_copy.rs:71:14
|
LL | vec.push(42.clone());
| ^^^^^^^^^^ help: try removing the `clone` call: `42`
error: using `clone` on type `Option<i32>` which implements the `Copy` trait
- --> $DIR/clone_on_copy.rs:77:17
+ --> $DIR/clone_on_copy.rs:75:17
|
LL | let value = opt.clone()?; // operator precedence needed (*opt)?
| ^^^^^^^^^^^ help: try dereferencing it: `(*opt)`
diff --git a/src/tools/clippy/tests/ui/clone_on_copy_impl.rs b/src/tools/clippy/tests/ui/clone_on_copy_impl.rs
index b7c186bef..2d03544ad 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy_impl.rs
+++ b/src/tools/clippy/tests/ui/clone_on_copy_impl.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::incorrect_clone_impl_on_copy_type)]
+#![allow(clippy::non_canonical_clone_impl)]
use std::fmt;
use std::marker::PhantomData;
diff --git a/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed b/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed
index 34bd22334..bc939bb3d 100644
--- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed
+++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::cloned_instead_of_copied)]
#![allow(unused)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs b/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs
index fa8444937..27346adbf 100644
--- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs
+++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::cloned_instead_of_copied)]
#![allow(unused)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr b/src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr
index 3ce482006..69a3738dd 100644
--- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr
+++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr
@@ -1,49 +1,50 @@
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:9:24
+ --> $DIR/cloned_instead_of_copied.rs:7:24
|
LL | let _ = [1].iter().cloned();
| ^^^^^^ help: try: `copied`
|
= note: `-D clippy::cloned-instead-of-copied` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cloned_instead_of_copied)]`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:10:31
+ --> $DIR/cloned_instead_of_copied.rs:8:31
|
LL | let _ = vec!["hi"].iter().cloned();
| ^^^^^^ help: try: `copied`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:11:22
+ --> $DIR/cloned_instead_of_copied.rs:9:22
|
LL | let _ = Some(&1).cloned();
| ^^^^^^ help: try: `copied`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:12:34
+ --> $DIR/cloned_instead_of_copied.rs:10:34
|
LL | let _ = Box::new([1].iter()).cloned();
| ^^^^^^ help: try: `copied`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:13:32
+ --> $DIR/cloned_instead_of_copied.rs:11:32
|
LL | let _ = Box::new(Some(&1)).cloned();
| ^^^^^^ help: try: `copied`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:29:22
+ --> $DIR/cloned_instead_of_copied.rs:27:22
|
LL | let _ = Some(&1).cloned(); // Option::copied needs 1.35
| ^^^^^^ help: try: `copied`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:34:24
+ --> $DIR/cloned_instead_of_copied.rs:32:24
|
LL | let _ = [1].iter().cloned(); // Iterator::copied needs 1.36
| ^^^^^^ help: try: `copied`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:35:22
+ --> $DIR/cloned_instead_of_copied.rs:33:22
|
LL | let _ = Some(&1).cloned();
| ^^^^^^ help: try: `copied`
diff --git a/src/tools/clippy/tests/ui/cmp_null.rs b/src/tools/clippy/tests/ui/cmp_null.rs
index 2d2d04178..ef1d93940 100644
--- a/src/tools/clippy/tests/ui/cmp_null.rs
+++ b/src/tools/clippy/tests/ui/cmp_null.rs
@@ -7,11 +7,14 @@ fn main() {
let x = 0;
let p: *const usize = &x;
if p == ptr::null() {
+ //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+ //~| NOTE: `-D clippy::cmp-null` implied by `-D warnings`
println!("This is surprising!");
}
let mut y = 0;
let mut m: *mut usize = &mut y;
if m == ptr::null_mut() {
+ //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
println!("This is surprising, too!");
}
}
diff --git a/src/tools/clippy/tests/ui/cmp_null.stderr b/src/tools/clippy/tests/ui/cmp_null.stderr
index a1f4c70fb..d3b7c85b2 100644
--- a/src/tools/clippy/tests/ui/cmp_null.stderr
+++ b/src/tools/clippy/tests/ui/cmp_null.stderr
@@ -5,9 +5,10 @@ LL | if p == ptr::null() {
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::cmp-null` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cmp_null)]`
error: comparing with null is better expressed by the `.is_null()` method
- --> $DIR/cmp_null.rs:14:8
+ --> $DIR/cmp_null.rs:16:8
|
LL | if m == ptr::null_mut() {
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed
index 118346348..9fc70ab6f 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed
+++ b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::needless_if,
diff --git a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs
index 3a25d53a5..5cd43ea1d 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs
+++ b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::needless_if,
diff --git a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.stderr b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.stderr
index 4714a0daa..6431b3619 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.stderr
+++ b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.stderr
@@ -1,13 +1,14 @@
error: this creates an owned instance just for comparison
- --> $DIR/asymmetric_partial_eq.rs:47:12
+ --> $DIR/asymmetric_partial_eq.rs:46:12
|
LL | if borrowed.to_owned() == owned {}
| ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed`
|
= note: `-D clippy::cmp-owned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`
error: this creates an owned instance just for comparison
- --> $DIR/asymmetric_partial_eq.rs:48:21
+ --> $DIR/asymmetric_partial_eq.rs:47:21
|
LL | if owned == borrowed.to_owned() {}
| ---------^^^^^^^^^^^^^^^^^^^
@@ -15,13 +16,13 @@ LL | if owned == borrowed.to_owned() {}
| help: try: `borrowed == owned`
error: this creates an owned instance just for comparison
- --> $DIR/asymmetric_partial_eq.rs:66:21
+ --> $DIR/asymmetric_partial_eq.rs:65:21
|
LL | if owned == borrowed.to_owned() {}
| ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed`
error: this creates an owned instance just for comparison
- --> $DIR/asymmetric_partial_eq.rs:67:12
+ --> $DIR/asymmetric_partial_eq.rs:66:12
|
LL | if borrowed.to_owned() == owned {}
| ^^^^^^^^^^^^^^^^^^^---------
@@ -29,7 +30,7 @@ LL | if borrowed.to_owned() == owned {}
| help: try: `owned == borrowed`
error: this creates an owned instance just for comparison
- --> $DIR/asymmetric_partial_eq.rs:93:20
+ --> $DIR/asymmetric_partial_eq.rs:92:20
|
LL | if "Hi" == borrowed.to_string() {}
| --------^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +38,7 @@ LL | if "Hi" == borrowed.to_string() {}
| help: try: `borrowed == "Hi"`
error: this creates an owned instance just for comparison
- --> $DIR/asymmetric_partial_eq.rs:94:12
+ --> $DIR/asymmetric_partial_eq.rs:93:12
|
LL | if borrowed.to_string() == "Hi" {}
| ^^^^^^^^^^^^^^^^^^^^ help: try: `borrowed`
diff --git a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed
index b1133f2a5..40d7b5e49 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed
+++ b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
use std::fmt::{self, Display};
fn main() {
diff --git a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs
index 091a9aa65..59a945668 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs
+++ b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
use std::fmt::{self, Display};
fn main() {
diff --git a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.stderr b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.stderr
index e4d0d822b..09a495996 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.stderr
+++ b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.stderr
@@ -1,13 +1,14 @@
error: this creates an owned instance just for comparison
- --> $DIR/comparison_flip.rs:8:8
+ --> $DIR/comparison_flip.rs:6:8
|
LL | if a.to_string() != "bar" {
| ^^^^^^^^^^^^^ help: try: `a`
|
= note: `-D clippy::cmp-owned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`
error: this creates an owned instance just for comparison
- --> $DIR/comparison_flip.rs:12:17
+ --> $DIR/comparison_flip.rs:10:17
|
LL | if "bar" != a.to_string() {
| ---------^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed
index bf1a58588..8846092fe 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed
+++ b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[warn(clippy::cmp_owned)]
#[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs
index f3f663670..cb5268734 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs
+++ b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[warn(clippy::cmp_owned)]
#[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.stderr b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.stderr
index 2f333e6ea..0b1127c1a 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.stderr
+++ b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.stderr
@@ -1,37 +1,38 @@
error: this creates an owned instance just for comparison
- --> $DIR/with_suggestion.rs:7:14
+ --> $DIR/with_suggestion.rs:5:14
|
LL | x != "foo".to_string();
| ^^^^^^^^^^^^^^^^^ help: try: `"foo"`
|
= note: `-D clippy::cmp-owned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`
error: this creates an owned instance just for comparison
- --> $DIR/with_suggestion.rs:9:9
+ --> $DIR/with_suggestion.rs:7:9
|
LL | "foo".to_string() != x;
| ^^^^^^^^^^^^^^^^^ help: try: `"foo"`
error: this creates an owned instance just for comparison
- --> $DIR/with_suggestion.rs:16:10
+ --> $DIR/with_suggestion.rs:14:10
|
LL | x != "foo".to_owned();
| ^^^^^^^^^^^^^^^^ help: try: `"foo"`
error: this creates an owned instance just for comparison
- --> $DIR/with_suggestion.rs:18:10
+ --> $DIR/with_suggestion.rs:16:10
|
LL | x != String::from("foo");
| ^^^^^^^^^^^^^^^^^^^ help: try: `"foo"`
error: this creates an owned instance just for comparison
- --> $DIR/with_suggestion.rs:22:5
+ --> $DIR/with_suggestion.rs:20:5
|
LL | Foo.to_owned() == Foo;
| ^^^^^^^^^^^^^^ help: try: `Foo`
error: this creates an owned instance just for comparison
- --> $DIR/with_suggestion.rs:24:30
+ --> $DIR/with_suggestion.rs:22:30
|
LL | "abc".chars().filter(|c| c.to_owned() != 'X');
| ^^^^^^^^^^^^ help: try: `*c`
diff --git a/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs b/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs
index d8a202cb6..ec45d635c 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs
+++ b/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs
@@ -5,10 +5,13 @@ fn main() {
let x = &Baz;
let y = &Baz;
y.to_owned() == *x;
+ //~^ ERROR: this creates an owned instance just for comparison
+ //~| NOTE: `-D clippy::cmp-owned` implied by `-D warnings`
let x = &&Baz;
let y = &Baz;
y.to_owned() == **x;
+ //~^ ERROR: this creates an owned instance just for comparison
let x = 0u32;
let y = U32Wrapper(x);
@@ -20,6 +23,7 @@ struct Foo;
impl PartialEq for Foo {
fn eq(&self, other: &Self) -> bool {
self.to_owned() == *other
+ //~^ ERROR: this creates an owned instance just for comparison
}
}
diff --git a/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.stderr b/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.stderr
index d2dd14d8e..c4f63bd09 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.stderr
+++ b/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.stderr
@@ -5,15 +5,16 @@ LL | y.to_owned() == *x;
| ^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
|
= note: `-D clippy::cmp-owned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`
error: this creates an owned instance just for comparison
- --> $DIR/without_suggestion.rs:11:5
+ --> $DIR/without_suggestion.rs:13:5
|
LL | y.to_owned() == **x;
| ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
error: this creates an owned instance just for comparison
- --> $DIR/without_suggestion.rs:22:9
+ --> $DIR/without_suggestion.rs:25:9
|
LL | self.to_owned() == *other
| ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
diff --git a/src/tools/clippy/tests/ui/cognitive_complexity.rs b/src/tools/clippy/tests/ui/cognitive_complexity.rs
index 07bdaff00..e8fd063a9 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity.rs
+++ b/src/tools/clippy/tests/ui/cognitive_complexity.rs
@@ -4,6 +4,7 @@
#[rustfmt::skip]
fn main() {
+//~^ ERROR: the function has a cognitive complexity of (28/25)
if true {
println!("a");
}
@@ -89,6 +90,7 @@ fn main() {
#[clippy::cognitive_complexity = "1"]
fn kaboom() {
+ //~^ ERROR: the function has a cognitive complexity of (7/1)
let n = 0;
'a: for i in 0..20 {
'b: for j in i..20 {
@@ -147,7 +149,9 @@ fn lots_of_short_circuits2() -> bool {
#[clippy::cognitive_complexity = "1"]
fn baa() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
let x = || match 99 {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
0 => 0,
1 => 1,
2 => 2,
@@ -165,6 +169,7 @@ fn baa() {
#[clippy::cognitive_complexity = "1"]
fn bar() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
match 99 {
0 => println!("hi"),
_ => println!("bye"),
@@ -176,6 +181,7 @@ fn bar() {
/// Tests are usually complex but simple at the same time. `clippy::cognitive_complexity` used to
/// give lots of false-positives in tests.
fn dont_warn_on_tests() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
match 99 {
0 => println!("hi"),
_ => println!("bye"),
@@ -184,6 +190,7 @@ fn dont_warn_on_tests() {
#[clippy::cognitive_complexity = "1"]
fn barr() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
match 99 {
0 => println!("hi"),
1 => println!("bla"),
@@ -194,6 +201,7 @@ fn barr() {
#[clippy::cognitive_complexity = "1"]
fn barr2() {
+ //~^ ERROR: the function has a cognitive complexity of (3/1)
match 99 {
0 => println!("hi"),
1 => println!("bla"),
@@ -210,6 +218,7 @@ fn barr2() {
#[clippy::cognitive_complexity = "1"]
fn barrr() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
match 99 {
0 => println!("hi"),
1 => panic!("bla"),
@@ -220,6 +229,7 @@ fn barrr() {
#[clippy::cognitive_complexity = "1"]
fn barrr2() {
+ //~^ ERROR: the function has a cognitive complexity of (3/1)
match 99 {
0 => println!("hi"),
1 => panic!("bla"),
@@ -236,6 +246,7 @@ fn barrr2() {
#[clippy::cognitive_complexity = "1"]
fn barrrr() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
match 99 {
0 => println!("hi"),
1 => println!("bla"),
@@ -246,6 +257,7 @@ fn barrrr() {
#[clippy::cognitive_complexity = "1"]
fn barrrr2() {
+ //~^ ERROR: the function has a cognitive complexity of (3/1)
match 99 {
0 => println!("hi"),
1 => println!("bla"),
@@ -262,6 +274,7 @@ fn barrrr2() {
#[clippy::cognitive_complexity = "1"]
fn cake() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
if 4 == 5 {
println!("yea");
} else {
@@ -272,6 +285,7 @@ fn cake() {
#[clippy::cognitive_complexity = "1"]
pub fn read_file(input_path: &str) -> String {
+ //~^ ERROR: the function has a cognitive complexity of (4/1)
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
@@ -303,6 +317,7 @@ enum Void {}
#[clippy::cognitive_complexity = "1"]
fn void(void: Void) {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
if true {
match void {}
}
@@ -354,6 +369,7 @@ fn early() -> Result<i32, &'static str> {
#[rustfmt::skip]
#[clippy::cognitive_complexity = "1"]
fn early_ret() -> i32 {
+//~^ ERROR: the function has a cognitive complexity of (8/1)
let a = if true { 42 } else { return 0; };
let a = if a < 99 { 42 } else { return 0; };
let a = if a < 99 { 42 } else { return 0; };
@@ -375,6 +391,7 @@ fn early_ret() -> i32 {
#[clippy::cognitive_complexity = "1"]
fn closures() {
let x = |a: i32, b: i32| -> i32 {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
if true {
println!("moo");
}
@@ -388,6 +405,7 @@ struct Moo;
#[clippy::cognitive_complexity = "1"]
impl Moo {
fn moo(&self) {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
if true {
println!("moo");
}
@@ -397,6 +415,7 @@ impl Moo {
#[clippy::cognitive_complexity = "1"]
mod issue9300 {
async fn a() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
let a = 0;
if a == 0 {}
}
@@ -404,6 +423,7 @@ mod issue9300 {
pub struct S;
impl S {
pub async fn async_method() {
+ //~^ ERROR: the function has a cognitive complexity of (2/1)
let a = 0;
if a == 0 {}
}
diff --git a/src/tools/clippy/tests/ui/cognitive_complexity.stderr b/src/tools/clippy/tests/ui/cognitive_complexity.stderr
index d86724630..58c7455d1 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity.stderr
+++ b/src/tools/clippy/tests/ui/cognitive_complexity.stderr
@@ -6,9 +6,10 @@ LL | fn main() {
|
= help: you could split it up into multiple smaller functions
= note: `-D clippy::cognitive-complexity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]`
error: the function has a cognitive complexity of (7/1)
- --> $DIR/cognitive_complexity.rs:91:4
+ --> $DIR/cognitive_complexity.rs:92:4
|
LL | fn kaboom() {
| ^^^^^^
@@ -16,7 +17,7 @@ LL | fn kaboom() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:149:4
+ --> $DIR/cognitive_complexity.rs:151:4
|
LL | fn baa() {
| ^^^
@@ -24,7 +25,7 @@ LL | fn baa() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:150:13
+ --> $DIR/cognitive_complexity.rs:153:13
|
LL | let x = || match 99 {
| ^^
@@ -32,7 +33,7 @@ LL | let x = || match 99 {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:167:4
+ --> $DIR/cognitive_complexity.rs:171:4
|
LL | fn bar() {
| ^^^
@@ -40,7 +41,7 @@ LL | fn bar() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:178:4
+ --> $DIR/cognitive_complexity.rs:183:4
|
LL | fn dont_warn_on_tests() {
| ^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | fn dont_warn_on_tests() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:186:4
+ --> $DIR/cognitive_complexity.rs:192:4
|
LL | fn barr() {
| ^^^^
@@ -56,7 +57,7 @@ LL | fn barr() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (3/1)
- --> $DIR/cognitive_complexity.rs:196:4
+ --> $DIR/cognitive_complexity.rs:203:4
|
LL | fn barr2() {
| ^^^^^
@@ -64,7 +65,7 @@ LL | fn barr2() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:212:4
+ --> $DIR/cognitive_complexity.rs:220:4
|
LL | fn barrr() {
| ^^^^^
@@ -72,7 +73,7 @@ LL | fn barrr() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (3/1)
- --> $DIR/cognitive_complexity.rs:222:4
+ --> $DIR/cognitive_complexity.rs:231:4
|
LL | fn barrr2() {
| ^^^^^^
@@ -80,7 +81,7 @@ LL | fn barrr2() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:238:4
+ --> $DIR/cognitive_complexity.rs:248:4
|
LL | fn barrrr() {
| ^^^^^^
@@ -88,7 +89,7 @@ LL | fn barrrr() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (3/1)
- --> $DIR/cognitive_complexity.rs:248:4
+ --> $DIR/cognitive_complexity.rs:259:4
|
LL | fn barrrr2() {
| ^^^^^^^
@@ -96,7 +97,7 @@ LL | fn barrrr2() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:264:4
+ --> $DIR/cognitive_complexity.rs:276:4
|
LL | fn cake() {
| ^^^^
@@ -104,7 +105,7 @@ LL | fn cake() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (4/1)
- --> $DIR/cognitive_complexity.rs:274:8
+ --> $DIR/cognitive_complexity.rs:287:8
|
LL | pub fn read_file(input_path: &str) -> String {
| ^^^^^^^^^
@@ -112,7 +113,7 @@ LL | pub fn read_file(input_path: &str) -> String {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:305:4
+ --> $DIR/cognitive_complexity.rs:319:4
|
LL | fn void(void: Void) {
| ^^^^
@@ -120,7 +121,7 @@ LL | fn void(void: Void) {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (8/1)
- --> $DIR/cognitive_complexity.rs:356:4
+ --> $DIR/cognitive_complexity.rs:371:4
|
LL | fn early_ret() -> i32 {
| ^^^^^^^^^
@@ -128,7 +129,7 @@ LL | fn early_ret() -> i32 {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:377:13
+ --> $DIR/cognitive_complexity.rs:393:13
|
LL | let x = |a: i32, b: i32| -> i32 {
| ^^^^^^^^^^^^^^^^
@@ -136,7 +137,7 @@ LL | let x = |a: i32, b: i32| -> i32 {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:390:8
+ --> $DIR/cognitive_complexity.rs:407:8
|
LL | fn moo(&self) {
| ^^^
@@ -144,7 +145,7 @@ LL | fn moo(&self) {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:399:14
+ --> $DIR/cognitive_complexity.rs:417:14
|
LL | async fn a() {
| ^
@@ -152,7 +153,7 @@ LL | async fn a() {
= help: you could split it up into multiple smaller functions
error: the function has a cognitive complexity of (2/1)
- --> $DIR/cognitive_complexity.rs:406:22
+ --> $DIR/cognitive_complexity.rs:425:22
|
LL | pub async fn async_method() {
| ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.rs b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.rs
index 771a26fc9..6f6e89983 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.rs
+++ b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.rs
@@ -7,6 +7,7 @@ fn main() {
#[clippy::cognitive_complexity = "0"]
fn kaboom() {
+ //~^ ERROR: the function has a cognitive complexity of (3/0)
if 42 == 43 {
panic!();
} else if "cake" == "lie" {
diff --git a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr
index bb48f3297..9cd25f6fd 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr
+++ b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr
@@ -6,6 +6,7 @@ LL | fn kaboom() {
|
= help: you could split it up into multiple smaller functions
= note: `-D clippy::cognitive-complexity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.fixed b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
index c4116cd85..3b410b2f1 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)]
#[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.rs b/src/tools/clippy/tests/ui/collapsible_else_if.rs
index 8f51d0ee5..772ef6f9f 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.rs
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)]
#[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.stderr b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
index 45b2094c9..f0f840653 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
@@ -1,5 +1,5 @@
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:14:12
+ --> $DIR/collapsible_else_if.rs:13:12
|
LL | } else {
| ____________^
@@ -10,6 +10,7 @@ LL | | }
| |_____^
|
= note: `-D clippy::collapsible-else-if` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::collapsible_else_if)]`
help: collapse nested if block
|
LL ~ } else if y == "world" {
@@ -18,7 +19,7 @@ LL + }
|
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:22:12
+ --> $DIR/collapsible_else_if.rs:21:12
|
LL | } else {
| ____________^
@@ -36,7 +37,7 @@ LL + }
|
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:30:12
+ --> $DIR/collapsible_else_if.rs:29:12
|
LL | } else {
| ____________^
@@ -59,7 +60,7 @@ LL + }
|
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:41:12
+ --> $DIR/collapsible_else_if.rs:40:12
|
LL | } else {
| ____________^
@@ -82,7 +83,7 @@ LL + }
|
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:52:12
+ --> $DIR/collapsible_else_if.rs:51:12
|
LL | } else {
| ____________^
@@ -105,7 +106,7 @@ LL + }
|
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:63:12
+ --> $DIR/collapsible_else_if.rs:62:12
|
LL | } else {
| ____________^
@@ -128,7 +129,7 @@ LL + }
|
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:74:12
+ --> $DIR/collapsible_else_if.rs:73:12
|
LL | } else {
| ____________^
@@ -151,7 +152,7 @@ LL + }
|
error: this `else { if .. }` block can be collapsed
- --> $DIR/collapsible_else_if.rs:97:10
+ --> $DIR/collapsible_else_if.rs:96:10
|
LL | }else{
| __________^
diff --git a/src/tools/clippy/tests/ui/collapsible_if.fixed b/src/tools/clippy/tests/ui/collapsible_if.fixed
index e305e1d7a..fff6bfcc7 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_if.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
clippy::assertions_on_constants,
clippy::equatable_if_let,
diff --git a/src/tools/clippy/tests/ui/collapsible_if.rs b/src/tools/clippy/tests/ui/collapsible_if.rs
index 7c52959d3..70bfea231 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.rs
+++ b/src/tools/clippy/tests/ui/collapsible_if.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
clippy::assertions_on_constants,
clippy::equatable_if_let,
diff --git a/src/tools/clippy/tests/ui/collapsible_if.stderr b/src/tools/clippy/tests/ui/collapsible_if.stderr
index 4a1a9e8a6..e8a36bf48 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_if.stderr
@@ -1,5 +1,5 @@
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:15:5
+ --> $DIR/collapsible_if.rs:14:5
|
LL | / if x == "hello" {
LL | | if y == "world" {
@@ -9,6 +9,7 @@ LL | | }
| |_____^
|
= note: `-D clippy::collapsible-if` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]`
help: collapse nested if block
|
LL ~ if x == "hello" && y == "world" {
@@ -17,7 +18,7 @@ LL + }
|
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:21:5
+ --> $DIR/collapsible_if.rs:20:5
|
LL | / if x == "hello" || x == "world" {
LL | | if y == "world" || y == "hello" {
@@ -34,7 +35,7 @@ LL + }
|
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:27:5
+ --> $DIR/collapsible_if.rs:26:5
|
LL | / if x == "hello" && x == "world" {
LL | | if y == "world" || y == "hello" {
@@ -51,7 +52,7 @@ LL + }
|
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:33:5
+ --> $DIR/collapsible_if.rs:32:5
|
LL | / if x == "hello" || x == "world" {
LL | | if y == "world" && y == "hello" {
@@ -68,7 +69,7 @@ LL + }
|
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:39:5
+ --> $DIR/collapsible_if.rs:38:5
|
LL | / if x == "hello" && x == "world" {
LL | | if y == "world" && y == "hello" {
@@ -85,7 +86,7 @@ LL + }
|
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:45:5
+ --> $DIR/collapsible_if.rs:44:5
|
LL | / if 42 == 1337 {
LL | | if 'a' != 'A' {
@@ -102,7 +103,7 @@ LL + }
|
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:101:5
+ --> $DIR/collapsible_if.rs:100:5
|
LL | / if x == "hello" {
LL | | if y == "world" { // Collapsible
@@ -119,7 +120,7 @@ LL + }
|
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:160:5
+ --> $DIR/collapsible_if.rs:159:5
|
LL | / if matches!(true, true) {
LL | | if matches!(true, true) {}
@@ -127,7 +128,7 @@ LL | | }
| |_____^ help: collapse nested if block: `if matches!(true, true) && matches!(true, true) {}`
error: this `if` statement can be collapsed
- --> $DIR/collapsible_if.rs:165:5
+ --> $DIR/collapsible_if.rs:164:5
|
LL | / if matches!(true, true) && truth() {
LL | | if matches!(true, true) {}
diff --git a/src/tools/clippy/tests/ui/collapsible_match.rs b/src/tools/clippy/tests/ui/collapsible_match.rs
index 1d7a72846..7501fd2b0 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.rs
+++ b/src/tools/clippy/tests/ui/collapsible_match.rs
@@ -11,6 +11,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// match without block
match res_opt {
Ok(val) => match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
Some(n) => foo(n),
_ => return,
},
@@ -20,6 +21,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// match with block
match res_opt {
Ok(val) => match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
Some(n) => foo(n),
_ => return,
},
@@ -29,6 +31,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// if let, if let
if let Ok(val) = res_opt {
if let Some(n) = val {
+ //~^ ERROR: this `if let` can be collapsed into the outer `if let`
take(n);
}
}
@@ -36,6 +39,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// if let else, if let else
if let Ok(val) = res_opt {
if let Some(n) = val {
+ //~^ ERROR: this `if let` can be collapsed into the outer `if let`
take(n);
} else {
return;
@@ -47,6 +51,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// if let, match
if let Ok(val) = res_opt {
match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `if let`
Some(n) => foo(n),
_ => (),
}
@@ -56,6 +61,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
match res_opt {
Ok(val) => {
if let Some(n) = val {
+ //~^ ERROR: this `if let` can be collapsed into the outer `match`
take(n);
}
},
@@ -65,6 +71,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// if let else, match
if let Ok(val) = res_opt {
match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `if let`
Some(n) => foo(n),
_ => return,
}
@@ -76,6 +83,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
match res_opt {
Ok(val) => {
if let Some(n) = val {
+ //~^ ERROR: this `if let` can be collapsed into the outer `match`
take(n);
} else {
return;
@@ -87,6 +95,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// None in inner match same as outer wild branch
match res_opt {
Ok(val) => match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
Some(n) => foo(n),
None => return,
},
@@ -96,6 +105,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// None in outer match same as inner wild branch
match opt_opt {
Some(val) => match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
Some(n) => foo(n),
_ => return,
},
@@ -261,6 +271,7 @@ pub enum Issue9647 {
pub fn test_1(x: Issue9647) {
if let Issue9647::A { a, .. } = x {
if let Some(u) = a {
+ //~^ ERROR: this `if let` can be collapsed into the outer `if let`
println!("{u:?}")
}
}
@@ -269,6 +280,7 @@ pub fn test_1(x: Issue9647) {
pub fn test_2(x: Issue9647) {
if let Issue9647::A { a: Some(a), .. } = x {
if let Some(u) = a {
+ //~^ ERROR: this `if let` can be collapsed into the outer `if let`
println!("{u}")
}
}
diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr
index 0294be60b..ce7da1c16 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match.stderr
@@ -3,6 +3,7 @@ error: this `match` can be collapsed into the outer `match`
|
LL | Ok(val) => match val {
| ____________________^
+LL | |
LL | | Some(n) => foo(n),
LL | | _ => return,
LL | | },
@@ -13,38 +14,43 @@ help: the outer pattern can be modified to include the inner pattern
|
LL | Ok(val) => match val {
| ^^^ replace this binding
+LL |
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
= note: `-D clippy::collapsible-match` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]`
error: this `match` can be collapsed into the outer `match`
- --> $DIR/collapsible_match.rs:22:20
+ --> $DIR/collapsible_match.rs:23:20
|
LL | Ok(val) => match val {
| ____________________^
+LL | |
LL | | Some(n) => foo(n),
LL | | _ => return,
LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:22:12
+ --> $DIR/collapsible_match.rs:23:12
|
LL | Ok(val) => match val {
| ^^^ replace this binding
+LL |
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `if let`
- --> $DIR/collapsible_match.rs:31:9
+ --> $DIR/collapsible_match.rs:33:9
|
LL | / if let Some(n) = val {
+LL | |
LL | | take(n);
LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:30:15
+ --> $DIR/collapsible_match.rs:32:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
@@ -52,9 +58,10 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `if let`
- --> $DIR/collapsible_match.rs:38:9
+ --> $DIR/collapsible_match.rs:41:9
|
LL | / if let Some(n) = val {
+LL | |
LL | | take(n);
LL | | } else {
LL | | return;
@@ -62,7 +69,7 @@ LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:37:15
+ --> $DIR/collapsible_match.rs:40:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
@@ -70,33 +77,35 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `if let`
- --> $DIR/collapsible_match.rs:49:9
+ --> $DIR/collapsible_match.rs:53:9
|
LL | / match val {
+LL | |
LL | | Some(n) => foo(n),
LL | | _ => (),
LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:48:15
+ --> $DIR/collapsible_match.rs:52:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
-LL | match val {
+...
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `match`
- --> $DIR/collapsible_match.rs:58:13
+ --> $DIR/collapsible_match.rs:63:13
|
LL | / if let Some(n) = val {
+LL | |
LL | | take(n);
LL | | }
| |_____________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:57:12
+ --> $DIR/collapsible_match.rs:62:12
|
LL | Ok(val) => {
| ^^^ replace this binding
@@ -104,27 +113,29 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `if let`
- --> $DIR/collapsible_match.rs:67:9
+ --> $DIR/collapsible_match.rs:73:9
|
LL | / match val {
+LL | |
LL | | Some(n) => foo(n),
LL | | _ => return,
LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:66:15
+ --> $DIR/collapsible_match.rs:72:15
|
LL | if let Ok(val) = res_opt {
| ^^^ replace this binding
-LL | match val {
+...
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `match`
- --> $DIR/collapsible_match.rs:78:13
+ --> $DIR/collapsible_match.rs:85:13
|
LL | / if let Some(n) = val {
+LL | |
LL | | take(n);
LL | | } else {
LL | | return;
@@ -132,7 +143,7 @@ LL | | }
| |_____________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:77:12
+ --> $DIR/collapsible_match.rs:84:12
|
LL | Ok(val) => {
| ^^^ replace this binding
@@ -140,51 +151,56 @@ LL | if let Some(n) = val {
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `match`
- --> $DIR/collapsible_match.rs:89:20
+ --> $DIR/collapsible_match.rs:97:20
|
LL | Ok(val) => match val {
| ____________________^
+LL | |
LL | | Some(n) => foo(n),
LL | | None => return,
LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:89:12
+ --> $DIR/collapsible_match.rs:97:12
|
LL | Ok(val) => match val {
| ^^^ replace this binding
+LL |
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `match`
- --> $DIR/collapsible_match.rs:98:22
+ --> $DIR/collapsible_match.rs:107:22
|
LL | Some(val) => match val {
| ______________________^
+LL | |
LL | | Some(n) => foo(n),
LL | | _ => return,
LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:98:14
+ --> $DIR/collapsible_match.rs:107:14
|
LL | Some(val) => match val {
| ^^^ replace this binding
+LL |
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `if let` can be collapsed into the outer `if let`
- --> $DIR/collapsible_match.rs:263:9
+ --> $DIR/collapsible_match.rs:273:9
|
LL | / if let Some(u) = a {
+LL | |
LL | | println!("{u:?}")
LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:262:27
+ --> $DIR/collapsible_match.rs:272:27
|
LL | if let Issue9647::A { a, .. } = x {
| ^ replace this binding
@@ -192,15 +208,16 @@ LL | if let Some(u) = a {
| ^^^^^^^ with this pattern, prefixed by a:
error: this `if let` can be collapsed into the outer `if let`
- --> $DIR/collapsible_match.rs:271:9
+ --> $DIR/collapsible_match.rs:282:9
|
LL | / if let Some(u) = a {
+LL | |
LL | | println!("{u}")
LL | | }
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match.rs:270:35
+ --> $DIR/collapsible_match.rs:281:35
|
LL | if let Issue9647::A { a: Some(a), .. } = x {
| ^ replace this binding
diff --git a/src/tools/clippy/tests/ui/collapsible_match2.rs b/src/tools/clippy/tests/ui/collapsible_match2.rs
index c8fb0a39e..56801f99e 100644
--- a/src/tools/clippy/tests/ui/collapsible_match2.rs
+++ b/src/tools/clippy/tests/ui/collapsible_match2.rs
@@ -11,6 +11,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
{
match res_opt {
Ok(val) if make() => match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
Some(n) => foo(n),
_ => return,
},
@@ -18,6 +19,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
}
match res_opt {
Ok(val) => match val {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
Some(n) => foo(n),
_ => return,
},
@@ -49,6 +51,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// deref reference value
match Some(&[1]) {
Some(s) => match *s {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
[n] => foo(n),
_ => (),
},
@@ -58,6 +61,7 @@ fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>
// ref pattern and deref
match Some(&[1]) {
Some(ref s) => match s {
+ //~^ ERROR: this `match` can be collapsed into the outer `match`
[n] => foo(n),
_ => (),
},
diff --git a/src/tools/clippy/tests/ui/collapsible_match2.stderr b/src/tools/clippy/tests/ui/collapsible_match2.stderr
index 144dbe40a..e008355be 100644
--- a/src/tools/clippy/tests/ui/collapsible_match2.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match2.stderr
@@ -3,6 +3,7 @@ error: this `match` can be collapsed into the outer `match`
|
LL | Ok(val) if make() => match val {
| __________________________________^
+LL | |
LL | | Some(n) => foo(n),
LL | | _ => return,
LL | | },
@@ -13,30 +14,34 @@ help: the outer pattern can be modified to include the inner pattern
|
LL | Ok(val) if make() => match val {
| ^^^ replace this binding
+LL |
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
= note: `-D clippy::collapsible-match` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]`
error: this `match` can be collapsed into the outer `match`
- --> $DIR/collapsible_match2.rs:20:24
+ --> $DIR/collapsible_match2.rs:21:24
|
LL | Ok(val) => match val {
| ________________________^
+LL | |
LL | | Some(n) => foo(n),
LL | | _ => return,
LL | | },
| |_____________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match2.rs:20:16
+ --> $DIR/collapsible_match2.rs:21:16
|
LL | Ok(val) => match val {
| ^^^ replace this binding
+LL |
LL | Some(n) => foo(n),
| ^^^^^^^ with this pattern
error: this `match` can be collapsed into the outer `match`
- --> $DIR/collapsible_match2.rs:34:29
+ --> $DIR/collapsible_match2.rs:36:29
|
LL | $pat => match $e {
| _____________________________^
@@ -49,7 +54,7 @@ LL | mac!(res_opt => Ok(val), val => Some(n), foo(n));
| ------------------------------------------------ in this macro invocation
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match2.rs:46:28
+ --> $DIR/collapsible_match2.rs:48:28
|
LL | mac!(res_opt => Ok(val), val => Some(n), foo(n));
| ^^^ ^^^^^^^ with this pattern
@@ -58,38 +63,42 @@ LL | mac!(res_opt => Ok(val), val => Some(n), foo(n));
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this `match` can be collapsed into the outer `match`
- --> $DIR/collapsible_match2.rs:51:20
+ --> $DIR/collapsible_match2.rs:53:20
|
LL | Some(s) => match *s {
| ____________________^
+LL | |
LL | | [n] => foo(n),
LL | | _ => (),
LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match2.rs:51:14
+ --> $DIR/collapsible_match2.rs:53:14
|
LL | Some(s) => match *s {
| ^ replace this binding
+LL |
LL | [n] => foo(n),
| ^^^ with this pattern
error: this `match` can be collapsed into the outer `match`
- --> $DIR/collapsible_match2.rs:60:24
+ --> $DIR/collapsible_match2.rs:63:24
|
LL | Some(ref s) => match s {
| ________________________^
+LL | |
LL | | [n] => foo(n),
LL | | _ => (),
LL | | },
| |_________^
|
help: the outer pattern can be modified to include the inner pattern
- --> $DIR/collapsible_match2.rs:60:14
+ --> $DIR/collapsible_match2.rs:63:14
|
LL | Some(ref s) => match s {
| ^^^^^ replace this binding
+LL |
LL | [n] => foo(n),
| ^^^ with this pattern
diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.fixed b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed
index ba6c1769a..03b393d5a 100644
--- a/src/tools/clippy/tests/ui/collapsible_str_replace.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::collapsible_str_replace)]
diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.rs b/src/tools/clippy/tests/ui/collapsible_str_replace.rs
index f5871be65..364e5493b 100644
--- a/src/tools/clippy/tests/ui/collapsible_str_replace.rs
+++ b/src/tools/clippy/tests/ui/collapsible_str_replace.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::collapsible_str_replace)]
diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.stderr b/src/tools/clippy/tests/ui/collapsible_str_replace.stderr
index 223358cf5..4b0bd818d 100644
--- a/src/tools/clippy/tests/ui/collapsible_str_replace.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_str_replace.stderr
@@ -1,25 +1,26 @@
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:20:27
+ --> $DIR/collapsible_str_replace.rs:18:27
|
LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], "l")`
|
= note: `-D clippy::collapsible-str-replace` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::collapsible_str_replace)]`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:22:27
+ --> $DIR/collapsible_str_replace.rs:20:27
|
LL | let _ = "hesuo worpd".replace('s', l).replace('u', l);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], l)`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:24:27
+ --> $DIR/collapsible_str_replace.rs:22:27
|
LL | let _ = "hesuo worpd".replace('s', "l").replace('u', "l").replace('p', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u', 'p'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:27:10
+ --> $DIR/collapsible_str_replace.rs:25:10
|
LL | .replace('s', "l")
| __________^
@@ -29,61 +30,61 @@ LL | | .replace('d', "l");
| |__________________________^ help: replace with: `replace(['s', 'u', 'p', 'd'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:32:27
+ --> $DIR/collapsible_str_replace.rs:30:27
|
LL | let _ = "hesuo world".replace(s, "l").replace('u', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:34:27
+ --> $DIR/collapsible_str_replace.rs:32:27
|
LL | let _ = "hesuo worpd".replace(s, "l").replace('u', "l").replace('p', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u', 'p'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:36:27
+ --> $DIR/collapsible_str_replace.rs:34:27
|
LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace('p', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, 'p'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:38:27
+ --> $DIR/collapsible_str_replace.rs:36:27
|
LL | let _ = "hesuo worpd".replace(s, "l").replace(u, "l").replace(p, "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, p], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:40:27
+ --> $DIR/collapsible_str_replace.rs:38:27
|
LL | let _ = "hesuo worlp".replace('s', "l").replace('u', "l").replace('p', "d");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:42:45
+ --> $DIR/collapsible_str_replace.rs:40:45
|
LL | let _ = "hesuo worpd".replace('s', "x").replace('u', "l").replace('p', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['u', 'p'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:45:47
+ --> $DIR/collapsible_str_replace.rs:43:47
|
LL | let _ = "hesudo worpd".replace("su", "l").replace('d', "l").replace('p', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['d', 'p'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:47:28
+ --> $DIR/collapsible_str_replace.rs:45:28
|
LL | let _ = "hesudo worpd".replace(d, "l").replace('p', "l").replace("su", "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([d, 'p'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:49:27
+ --> $DIR/collapsible_str_replace.rs:47:27
|
LL | let _ = "hesuo world".replace(get_filter(), "l").replace('s', "l");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([get_filter(), 's'], "l")`
error: used consecutive `str::replace` call
- --> $DIR/collapsible_str_replace.rs:86:16
+ --> $DIR/collapsible_str_replace.rs:84:16
|
LL | let _ = "".replace('a', "1.58").replace('b', "1.58");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['a', 'b'], "1.58")`
diff --git a/src/tools/clippy/tests/ui/collection_is_never_read.rs b/src/tools/clippy/tests/ui/collection_is_never_read.rs
index e02c1c572..bd281f787 100644
--- a/src/tools/clippy/tests/ui/collection_is_never_read.rs
+++ b/src/tools/clippy/tests/ui/collection_is_never_read.rs
@@ -18,7 +18,9 @@ fn no_access_at_all() {
fn write_without_read() {
// The main use case for `collection_is_never_read`.
- let mut x = HashMap::new(); // WARNING
+ let mut x = HashMap::new();
+ //~^ ERROR: collection is never read
+ //~| NOTE: `-D clippy::collection-is-never-read` implied by `-D warnings`
x.insert(1, 2);
}
@@ -57,7 +59,8 @@ fn read_in_closure() {
}
fn write_in_closure() {
- let mut x = vec![1, 2, 3]; // WARNING
+ let mut x = vec![1, 2, 3];
+ //~^ ERROR: collection is never read
let _ = || {
x.push(4);
};
@@ -72,12 +75,14 @@ fn read_in_format() {
fn shadowing_1() {
let x = HashMap::<usize, usize>::new(); // Ok
let _ = x.len();
- let mut x = HashMap::new(); // WARNING
+ let mut x = HashMap::new();
+ //~^ ERROR: collection is never read
x.insert(1, 2);
}
fn shadowing_2() {
- let mut x = HashMap::new(); // WARNING
+ let mut x = HashMap::new();
+ //~^ ERROR: collection is never read
x.insert(1, 2);
let x = HashMap::<usize, usize>::new(); // Ok
let _ = x.len();
@@ -85,26 +90,30 @@ fn shadowing_2() {
#[allow(clippy::let_unit_value)]
fn fake_read_1() {
- let mut x = vec![1, 2, 3]; // WARNING
+ let mut x = vec![1, 2, 3];
+ //~^ ERROR: collection is never read
x.reverse();
let _: () = x.clear();
}
fn fake_read_2() {
- let mut x = vec![1, 2, 3]; // WARNING
+ let mut x = vec![1, 2, 3];
+ //~^ ERROR: collection is never read
x.reverse();
println!("{:?}", x.push(5));
}
fn assignment() {
- let mut x = vec![1, 2, 3]; // WARNING
+ let mut x = vec![1, 2, 3];
+ //~^ ERROR: collection is never read
let y = vec![4, 5, 6]; // Ok
x = y;
}
#[allow(clippy::self_assignment)]
fn self_assignment() {
- let mut x = vec![1, 2, 3]; // WARNING
+ let mut x = vec![1, 2, 3];
+ //~^ ERROR: collection is never read
x = x;
}
@@ -121,7 +130,8 @@ fn method_argument_but_not_target() {
}
fn insert_is_not_a_read() {
- let mut x = HashSet::new(); // WARNING
+ let mut x = HashSet::new();
+ //~^ ERROR: collection is never read
x.insert(5);
}
@@ -135,7 +145,8 @@ fn insert_is_a_read() {
fn not_read_if_return_value_not_used() {
// `is_empty` does not modify the set, so it's a query. But since the return value is not used, the
// lint does not consider it a read here.
- let x = vec![1, 2, 3]; // WARNING
+ let x = vec![1, 2, 3];
+ //~^ ERROR: collection is never read
x.is_empty();
}
@@ -170,34 +181,44 @@ fn function_argument() {
}
fn supported_types() {
- let mut x = std::collections::BTreeMap::new(); // WARNING
+ let mut x = std::collections::BTreeMap::new();
+ //~^ ERROR: collection is never read
x.insert(true, 1);
- let mut x = std::collections::BTreeSet::new(); // WARNING
+ let mut x = std::collections::BTreeSet::new();
+ //~^ ERROR: collection is never read
x.insert(1);
- let mut x = std::collections::BinaryHeap::new(); // WARNING
+ let mut x = std::collections::BinaryHeap::new();
+ //~^ ERROR: collection is never read
x.push(1);
- let mut x = std::collections::HashMap::new(); // WARNING
+ let mut x = std::collections::HashMap::new();
+ //~^ ERROR: collection is never read
x.insert(1, 2);
- let mut x = std::collections::HashSet::new(); // WARNING
+ let mut x = std::collections::HashSet::new();
+ //~^ ERROR: collection is never read
x.insert(1);
- let mut x = std::collections::LinkedList::new(); // WARNING
+ let mut x = std::collections::LinkedList::new();
+ //~^ ERROR: collection is never read
x.push_front(1);
- let mut x = Some(true); // WARNING
+ let mut x = Some(true);
+ //~^ ERROR: collection is never read
x.insert(false);
- let mut x = String::from("hello"); // WARNING
+ let mut x = String::from("hello");
+ //~^ ERROR: collection is never read
x.push('!');
- let mut x = Vec::new(); // WARNING
+ let mut x = Vec::new();
+ //~^ ERROR: collection is never read
x.clear();
x.push(1);
- let mut x = std::collections::VecDeque::new(); // WARNING
+ let mut x = std::collections::VecDeque::new();
+ //~^ ERROR: collection is never read
x.push_front(1);
}
diff --git a/src/tools/clippy/tests/ui/collection_is_never_read.stderr b/src/tools/clippy/tests/ui/collection_is_never_read.stderr
index 982cb4455..acb9abff6 100644
--- a/src/tools/clippy/tests/ui/collection_is_never_read.stderr
+++ b/src/tools/clippy/tests/ui/collection_is_never_read.stderr
@@ -1,123 +1,124 @@
error: collection is never read
--> $DIR/collection_is_never_read.rs:21:5
|
-LL | let mut x = HashMap::new(); // WARNING
+LL | let mut x = HashMap::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::collection-is-never-read` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::collection_is_never_read)]`
error: collection is never read
- --> $DIR/collection_is_never_read.rs:60:5
+ --> $DIR/collection_is_never_read.rs:62:5
|
-LL | let mut x = vec![1, 2, 3]; // WARNING
+LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:75:5
+ --> $DIR/collection_is_never_read.rs:78:5
|
-LL | let mut x = HashMap::new(); // WARNING
+LL | let mut x = HashMap::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:80:5
+ --> $DIR/collection_is_never_read.rs:84:5
|
-LL | let mut x = HashMap::new(); // WARNING
+LL | let mut x = HashMap::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:88:5
+ --> $DIR/collection_is_never_read.rs:93:5
|
-LL | let mut x = vec![1, 2, 3]; // WARNING
+LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:94:5
+ --> $DIR/collection_is_never_read.rs:100:5
|
-LL | let mut x = vec![1, 2, 3]; // WARNING
+LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:100:5
+ --> $DIR/collection_is_never_read.rs:107:5
|
-LL | let mut x = vec![1, 2, 3]; // WARNING
+LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:107:5
+ --> $DIR/collection_is_never_read.rs:115:5
|
-LL | let mut x = vec![1, 2, 3]; // WARNING
+LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:124:5
+ --> $DIR/collection_is_never_read.rs:133:5
|
-LL | let mut x = HashSet::new(); // WARNING
+LL | let mut x = HashSet::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:138:5
+ --> $DIR/collection_is_never_read.rs:148:5
|
-LL | let x = vec![1, 2, 3]; // WARNING
+LL | let x = vec![1, 2, 3];
| ^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:173:5
+ --> $DIR/collection_is_never_read.rs:184:5
|
-LL | let mut x = std::collections::BTreeMap::new(); // WARNING
+LL | let mut x = std::collections::BTreeMap::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:176:5
+ --> $DIR/collection_is_never_read.rs:188:5
|
-LL | let mut x = std::collections::BTreeSet::new(); // WARNING
+LL | let mut x = std::collections::BTreeSet::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:179:5
+ --> $DIR/collection_is_never_read.rs:192:5
|
-LL | let mut x = std::collections::BinaryHeap::new(); // WARNING
+LL | let mut x = std::collections::BinaryHeap::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:182:5
+ --> $DIR/collection_is_never_read.rs:196:5
|
-LL | let mut x = std::collections::HashMap::new(); // WARNING
+LL | let mut x = std::collections::HashMap::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:185:5
+ --> $DIR/collection_is_never_read.rs:200:5
|
-LL | let mut x = std::collections::HashSet::new(); // WARNING
+LL | let mut x = std::collections::HashSet::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:188:5
+ --> $DIR/collection_is_never_read.rs:204:5
|
-LL | let mut x = std::collections::LinkedList::new(); // WARNING
+LL | let mut x = std::collections::LinkedList::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:191:5
+ --> $DIR/collection_is_never_read.rs:208:5
|
-LL | let mut x = Some(true); // WARNING
+LL | let mut x = Some(true);
| ^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:194:5
+ --> $DIR/collection_is_never_read.rs:212:5
|
-LL | let mut x = String::from("hello"); // WARNING
+LL | let mut x = String::from("hello");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:197:5
+ --> $DIR/collection_is_never_read.rs:216:5
|
-LL | let mut x = Vec::new(); // WARNING
+LL | let mut x = Vec::new();
| ^^^^^^^^^^^^^^^^^^^^^^^
error: collection is never read
- --> $DIR/collection_is_never_read.rs:201:5
+ --> $DIR/collection_is_never_read.rs:221:5
|
-LL | let mut x = std::collections::VecDeque::new(); // WARNING
+LL | let mut x = std::collections::VecDeque::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 20 previous errors
diff --git a/src/tools/clippy/tests/ui/comparison_chain.rs b/src/tools/clippy/tests/ui/comparison_chain.rs
index c12c6a310..266cee4c3 100644
--- a/src/tools/clippy/tests/ui/comparison_chain.rs
+++ b/src/tools/clippy/tests/ui/comparison_chain.rs
@@ -12,6 +12,7 @@ fn f(x: u8, y: u8, z: u8) {
}
if x > y {
+ //~^ ERROR: `if` chain can be rewritten with `match`
a()
} else if x < y {
b()
@@ -25,6 +26,7 @@ fn f(x: u8, y: u8, z: u8) {
}
if x > y {
+ //~^ ERROR: `if` chain can be rewritten with `match`
a()
} else if x < y {
b()
@@ -33,6 +35,7 @@ fn f(x: u8, y: u8, z: u8) {
}
if x > y {
+ //~^ ERROR: `if` chain can be rewritten with `match`
a()
} else if y > x {
b()
@@ -41,6 +44,7 @@ fn f(x: u8, y: u8, z: u8) {
}
if x > 1 {
+ //~^ ERROR: `if` chain can be rewritten with `match`
a()
} else if x < 1 {
b()
@@ -115,12 +119,14 @@ fn g(x: f64, y: f64, z: f64) {
fn h<T: Ord>(x: T, y: T, z: T) {
if x > y {
+ //~^ ERROR: `if` chain can be rewritten with `match`
a()
} else if x < y {
b()
}
if x > y {
+ //~^ ERROR: `if` chain can be rewritten with `match`
a()
} else if x < y {
b()
@@ -129,6 +135,7 @@ fn h<T: Ord>(x: T, y: T, z: T) {
}
if x > y {
+ //~^ ERROR: `if` chain can be rewritten with `match`
a()
} else if y > x {
b()
diff --git a/src/tools/clippy/tests/ui/comparison_chain.stderr b/src/tools/clippy/tests/ui/comparison_chain.stderr
index 2eeb50202..3b41dcf55 100644
--- a/src/tools/clippy/tests/ui/comparison_chain.stderr
+++ b/src/tools/clippy/tests/ui/comparison_chain.stderr
@@ -2,6 +2,7 @@ error: `if` chain can be rewritten with `match`
--> $DIR/comparison_chain.rs:14:5
|
LL | / if x > y {
+LL | |
LL | | a()
LL | | } else if x < y {
LL | | b()
@@ -10,15 +11,16 @@ LL | | }
|
= help: consider rewriting the `if` chain to use `cmp` and `match`
= note: `-D clippy::comparison-chain` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::comparison_chain)]`
error: `if` chain can be rewritten with `match`
- --> $DIR/comparison_chain.rs:27:5
+ --> $DIR/comparison_chain.rs:28:5
|
LL | / if x > y {
+LL | |
LL | | a()
LL | | } else if x < y {
-LL | | b()
-LL | | } else {
+... |
LL | | c()
LL | | }
| |_____^
@@ -26,13 +28,13 @@ LL | | }
= help: consider rewriting the `if` chain to use `cmp` and `match`
error: `if` chain can be rewritten with `match`
- --> $DIR/comparison_chain.rs:35:5
+ --> $DIR/comparison_chain.rs:37:5
|
LL | / if x > y {
+LL | |
LL | | a()
LL | | } else if y > x {
-LL | | b()
-LL | | } else {
+... |
LL | | c()
LL | | }
| |_____^
@@ -40,13 +42,13 @@ LL | | }
= help: consider rewriting the `if` chain to use `cmp` and `match`
error: `if` chain can be rewritten with `match`
- --> $DIR/comparison_chain.rs:43:5
+ --> $DIR/comparison_chain.rs:46:5
|
LL | / if x > 1 {
+LL | |
LL | | a()
LL | | } else if x < 1 {
-LL | | b()
-LL | | } else if x == 1 {
+... |
LL | | c()
LL | | }
| |_____^
@@ -54,9 +56,10 @@ LL | | }
= help: consider rewriting the `if` chain to use `cmp` and `match`
error: `if` chain can be rewritten with `match`
- --> $DIR/comparison_chain.rs:117:5
+ --> $DIR/comparison_chain.rs:121:5
|
LL | / if x > y {
+LL | |
LL | | a()
LL | | } else if x < y {
LL | | b()
@@ -66,13 +69,13 @@ LL | | }
= help: consider rewriting the `if` chain to use `cmp` and `match`
error: `if` chain can be rewritten with `match`
- --> $DIR/comparison_chain.rs:123:5
+ --> $DIR/comparison_chain.rs:128:5
|
LL | / if x > y {
+LL | |
LL | | a()
LL | | } else if x < y {
-LL | | b()
-LL | | } else {
+... |
LL | | c()
LL | | }
| |_____^
@@ -80,13 +83,13 @@ LL | | }
= help: consider rewriting the `if` chain to use `cmp` and `match`
error: `if` chain can be rewritten with `match`
- --> $DIR/comparison_chain.rs:131:5
+ --> $DIR/comparison_chain.rs:137:5
|
LL | / if x > y {
+LL | |
LL | | a()
LL | | } else if y > x {
-LL | | b()
-LL | | } else {
+... |
LL | | c()
LL | | }
| |_____^
diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.fixed b/src/tools/clippy/tests/ui/comparison_to_empty.fixed
index af219eed0..90eb50715 100644
--- a/src/tools/clippy/tests/ui/comparison_to_empty.fixed
+++ b/src/tools/clippy/tests/ui/comparison_to_empty.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::comparison_to_empty)]
#![allow(clippy::borrow_deref_ref, clippy::needless_if, clippy::useless_vec)]
#![feature(let_chains)]
diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.rs b/src/tools/clippy/tests/ui/comparison_to_empty.rs
index 21e65184d..0964c4a20 100644
--- a/src/tools/clippy/tests/ui/comparison_to_empty.rs
+++ b/src/tools/clippy/tests/ui/comparison_to_empty.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::comparison_to_empty)]
#![allow(clippy::borrow_deref_ref, clippy::needless_if, clippy::useless_vec)]
#![feature(let_chains)]
diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.stderr b/src/tools/clippy/tests/ui/comparison_to_empty.stderr
index f29782ed8..b97ab4c3c 100644
--- a/src/tools/clippy/tests/ui/comparison_to_empty.stderr
+++ b/src/tools/clippy/tests/ui/comparison_to_empty.stderr
@@ -1,55 +1,56 @@
error: comparison to empty slice
- --> $DIR/comparison_to_empty.rs:10:13
+ --> $DIR/comparison_to_empty.rs:8:13
|
LL | let _ = s == "";
| ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
|
= note: `-D clippy::comparison-to-empty` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::comparison_to_empty)]`
error: comparison to empty slice
- --> $DIR/comparison_to_empty.rs:11:13
+ --> $DIR/comparison_to_empty.rs:9:13
|
LL | let _ = s != "";
| ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()`
error: comparison to empty slice
- --> $DIR/comparison_to_empty.rs:14:13
+ --> $DIR/comparison_to_empty.rs:12:13
|
LL | let _ = v == [];
| ^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()`
error: comparison to empty slice
- --> $DIR/comparison_to_empty.rs:15:13
+ --> $DIR/comparison_to_empty.rs:13:13
|
LL | let _ = v != [];
| ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()`
error: comparison to empty slice using `if let`
- --> $DIR/comparison_to_empty.rs:16:8
+ --> $DIR/comparison_to_empty.rs:14:8
|
LL | if let [] = &*v {}
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(*v).is_empty()`
error: comparison to empty slice using `if let`
- --> $DIR/comparison_to_empty.rs:18:8
+ --> $DIR/comparison_to_empty.rs:16:8
|
LL | if let [] = s {}
| ^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice using `if let`
- --> $DIR/comparison_to_empty.rs:19:8
+ --> $DIR/comparison_to_empty.rs:17:8
|
LL | if let [] = &*s {}
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice using `if let`
- --> $DIR/comparison_to_empty.rs:20:8
+ --> $DIR/comparison_to_empty.rs:18:8
|
LL | if let [] = &*s && s == [] {}
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
error: comparison to empty slice
- --> $DIR/comparison_to_empty.rs:20:24
+ --> $DIR/comparison_to_empty.rs:18:24
|
LL | if let [] = &*s && s == [] {}
| ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
diff --git a/src/tools/clippy/tests/ui/const_comparisons.rs b/src/tools/clippy/tests/ui/const_comparisons.rs
index 8e265c914..0898b4ebd 100644
--- a/src/tools/clippy/tests/ui/const_comparisons.rs
+++ b/src/tools/clippy/tests/ui/const_comparisons.rs
@@ -40,54 +40,111 @@ fn main() {
let status_code = 500; // Value doesn't matter for the lint
let status = Status { code: status_code };
- status_code >= 400 && status_code < 500; // Correct
+ // Correct
+ status_code >= 400 && status_code < 500;
status_code <= 400 && status_code > 500;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `400` < `500`, the expression evaluates to false for any value of `st
status_code > 500 && status_code < 400;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `500` > `400`, the expression evaluates to false for any value of `st
status_code < 500 && status_code > 500;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: `status_code` cannot simultaneously be greater than and less than `500`
// More complex expressions
status_code < { 400 } && status_code > { 500 };
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any valu
status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluate
status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to f
status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: `status_code` cannot simultaneously be greater than and less than `STATUS_S
// Comparing two different types, via the `impl PartialOrd<u16> for Status`
status < { 400 } && status > { 500 };
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any valu
status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluate
status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to f
status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: `status` cannot simultaneously be greater than and less than `STATUS_SERVER
// Yoda conditions
- 500 <= status_code && 600 > status_code; // Correct
- 500 <= status_code && status_code <= 600; // Correct
- 500 >= status_code && 600 < status_code; // Incorrect
- 500 >= status_code && status_code > 600; // Incorrect
+ // Correct
+ 500 <= status_code && 600 > status_code;
+ // Correct
+ 500 <= status_code && status_code <= 600;
+ // Incorrect
+ 500 >= status_code && 600 < status_code;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st
+ // Incorrect
+ 500 >= status_code && status_code > 600;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st
// Yoda conditions, comparing two different types
- 500 <= status && 600 > status; // Correct
- 500 <= status && status <= 600; // Correct
- 500 >= status && 600 < status; // Incorrect
- 500 >= status && status > 600; // Incorrect
+ // Correct
+ 500 <= status && 600 > status;
+ // Correct
+ 500 <= status && status <= 600;
+ // Incorrect
+ 500 >= status && 600 < status;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st
+ // Incorrect
+ 500 >= status && status > 600;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `500` < `600`, the expression evaluates to false for any value of `st
// Expressions where one of the sides has no effect
status_code < 200 && status_code <= 299;
+ //~^ ERROR: right-hand side of `&&` operator has no effect
status_code > 200 && status_code >= 299;
-
- status_code >= 500 && status_code > 500; // Useless left
- status_code > 500 && status_code >= 500; // Useless right
- status_code <= 500 && status_code < 500; // Useless left
- status_code < 500 && status_code <= 500; // Useless right
+ //~^ ERROR: left-hand side of `&&` operator has no effect
+
+ // Useless left
+ status_code >= 500 && status_code > 500;
+ //~^ ERROR: left-hand side of `&&` operator has no effect
+ // Useless right
+ status_code > 500 && status_code >= 500;
+ //~^ ERROR: right-hand side of `&&` operator has no effect
+ // Useless left
+ status_code <= 500 && status_code < 500;
+ //~^ ERROR: left-hand side of `&&` operator has no effect
+ // Useless right
+ status_code < 500 && status_code <= 500;
+ //~^ ERROR: right-hand side of `&&` operator has no effect
// Other types
let name = "Steve";
name < "Jennifer" && name > "Shannon";
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `"Jennifer"` < `"Shannon"`, the expression evaluates to false for any
let numbers = [1, 2];
numbers < [3, 4] && numbers > [5, 6];
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `[3, 4]` < `[5, 6]`, the expression evaluates to false for any value
let letter = 'a';
letter < 'b' && letter > 'c';
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `'b'` < `'c'`, the expression evaluates to false for any value of `le
let area = 42.0;
area < std::f32::consts::E && area > std::f32::consts::PI;
+ //~^ ERROR: boolean expression will never evaluate to 'true'
+ //~| NOTE: since `std::f32::consts::E` < `std::f32::consts::PI`, the expression evalua
}
diff --git a/src/tools/clippy/tests/ui/const_comparisons.stderr b/src/tools/clippy/tests/ui/const_comparisons.stderr
index 90e6db647..f773ccbc7 100644
--- a/src/tools/clippy/tests/ui/const_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/const_comparisons.stderr
@@ -1,14 +1,15 @@
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:44:5
+ --> $DIR/const_comparisons.rs:45:5
|
LL | status_code <= 400 && status_code > 500;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: since `400` < `500`, the expression evaluates to false for any value of `status_code`
= note: `-D clippy::impossible-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::impossible_comparisons)]`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:45:5
+ --> $DIR/const_comparisons.rs:48:5
|
LL | status_code > 500 && status_code < 400;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | status_code > 500 && status_code < 400;
= note: since `500` > `400`, the expression evaluates to false for any value of `status_code`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:46:5
+ --> $DIR/const_comparisons.rs:51:5
|
LL | status_code < 500 && status_code > 500;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | status_code < 500 && status_code > 500;
= note: `status_code` cannot simultaneously be greater than and less than `500`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:49:5
+ --> $DIR/const_comparisons.rs:56:5
|
LL | status_code < { 400 } && status_code > { 500 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | status_code < { 400 } && status_code > { 500 };
= note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status_code`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:50:5
+ --> $DIR/const_comparisons.rs:59:5
|
LL | status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR;
= note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:51:5
+ --> $DIR/const_comparisons.rs:62:5
|
LL | status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR;
= note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:52:5
+ --> $DIR/const_comparisons.rs:65:5
|
LL | status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR;
= note: `status_code` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:55:5
+ --> $DIR/const_comparisons.rs:70:5
|
LL | status < { 400 } && status > { 500 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | status < { 400 } && status > { 500 };
= note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:56:5
+ --> $DIR/const_comparisons.rs:73:5
|
LL | status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR;
= note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:57:5
+ --> $DIR/const_comparisons.rs:76:5
|
LL | status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +81,7 @@ LL | status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR;
= note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:58:5
+ --> $DIR/const_comparisons.rs:79:5
|
LL | status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -88,112 +89,113 @@ LL | status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR;
= note: `status` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:63:5
+ --> $DIR/const_comparisons.rs:89:5
|
-LL | 500 >= status_code && 600 < status_code; // Incorrect
+LL | 500 >= status_code && 600 < status_code;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: since `500` < `600`, the expression evaluates to false for any value of `status_code`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:64:5
+ --> $DIR/const_comparisons.rs:93:5
|
-LL | 500 >= status_code && status_code > 600; // Incorrect
+LL | 500 >= status_code && status_code > 600;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: since `500` < `600`, the expression evaluates to false for any value of `status_code`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:69:5
+ --> $DIR/const_comparisons.rs:103:5
|
-LL | 500 >= status && 600 < status; // Incorrect
+LL | 500 >= status && 600 < status;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: since `500` < `600`, the expression evaluates to false for any value of `status`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:70:5
+ --> $DIR/const_comparisons.rs:107:5
|
-LL | 500 >= status && status > 600; // Incorrect
+LL | 500 >= status && status > 600;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: since `500` < `600`, the expression evaluates to false for any value of `status`
error: right-hand side of `&&` operator has no effect
- --> $DIR/const_comparisons.rs:73:5
+ --> $DIR/const_comparisons.rs:112:5
|
LL | status_code < 200 && status_code <= 299;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `if `status_code < 200` evaluates to true, status_code <= 299` will always evaluate to true as well
- --> $DIR/const_comparisons.rs:73:23
+ --> $DIR/const_comparisons.rs:112:23
|
LL | status_code < 200 && status_code <= 299;
| ^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::redundant-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_comparisons)]`
error: left-hand side of `&&` operator has no effect
- --> $DIR/const_comparisons.rs:74:5
+ --> $DIR/const_comparisons.rs:114:5
|
LL | status_code > 200 && status_code >= 299;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `if `status_code >= 299` evaluates to true, status_code > 200` will always evaluate to true as well
- --> $DIR/const_comparisons.rs:74:5
+ --> $DIR/const_comparisons.rs:114:5
|
LL | status_code > 200 && status_code >= 299;
| ^^^^^^^^^^^^^^^^^^^^^
error: left-hand side of `&&` operator has no effect
- --> $DIR/const_comparisons.rs:76:5
+ --> $DIR/const_comparisons.rs:118:5
|
-LL | status_code >= 500 && status_code > 500; // Useless left
+LL | status_code >= 500 && status_code > 500;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well
- --> $DIR/const_comparisons.rs:76:5
+ --> $DIR/const_comparisons.rs:118:5
|
-LL | status_code >= 500 && status_code > 500; // Useless left
+LL | status_code >= 500 && status_code > 500;
| ^^^^^^^^^^^^^^^^^^^^^^
error: right-hand side of `&&` operator has no effect
- --> $DIR/const_comparisons.rs:77:5
+ --> $DIR/const_comparisons.rs:121:5
|
-LL | status_code > 500 && status_code >= 500; // Useless right
+LL | status_code > 500 && status_code >= 500;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well
- --> $DIR/const_comparisons.rs:77:23
+ --> $DIR/const_comparisons.rs:121:23
|
-LL | status_code > 500 && status_code >= 500; // Useless right
+LL | status_code > 500 && status_code >= 500;
| ^^^^^^^^^^^^^^^^^^^^^
error: left-hand side of `&&` operator has no effect
- --> $DIR/const_comparisons.rs:78:5
+ --> $DIR/const_comparisons.rs:124:5
|
-LL | status_code <= 500 && status_code < 500; // Useless left
+LL | status_code <= 500 && status_code < 500;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well
- --> $DIR/const_comparisons.rs:78:5
+ --> $DIR/const_comparisons.rs:124:5
|
-LL | status_code <= 500 && status_code < 500; // Useless left
+LL | status_code <= 500 && status_code < 500;
| ^^^^^^^^^^^^^^^^^^^^^^
error: right-hand side of `&&` operator has no effect
- --> $DIR/const_comparisons.rs:79:5
+ --> $DIR/const_comparisons.rs:127:5
|
-LL | status_code < 500 && status_code <= 500; // Useless right
+LL | status_code < 500 && status_code <= 500;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well
- --> $DIR/const_comparisons.rs:79:23
+ --> $DIR/const_comparisons.rs:127:23
|
-LL | status_code < 500 && status_code <= 500; // Useless right
+LL | status_code < 500 && status_code <= 500;
| ^^^^^^^^^^^^^^^^^^^^^
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:83:5
+ --> $DIR/const_comparisons.rs:132:5
|
LL | name < "Jennifer" && name > "Shannon";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -201,7 +203,7 @@ LL | name < "Jennifer" && name > "Shannon";
= note: since `"Jennifer"` < `"Shannon"`, the expression evaluates to false for any value of `name`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:86:5
+ --> $DIR/const_comparisons.rs:137:5
|
LL | numbers < [3, 4] && numbers > [5, 6];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +211,7 @@ LL | numbers < [3, 4] && numbers > [5, 6];
= note: since `[3, 4]` < `[5, 6]`, the expression evaluates to false for any value of `numbers`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:89:5
+ --> $DIR/const_comparisons.rs:142:5
|
LL | letter < 'b' && letter > 'c';
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +219,7 @@ LL | letter < 'b' && letter > 'c';
= note: since `'b'` < `'c'`, the expression evaluates to false for any value of `letter`
error: boolean expression will never evaluate to 'true'
- --> $DIR/const_comparisons.rs:92:5
+ --> $DIR/const_comparisons.rs:147:5
|
LL | area < std::f32::consts::E && area > std::f32::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/copy_iterator.rs b/src/tools/clippy/tests/ui/copy_iterator.rs
index ae67ebded..c0e5fc3e4 100644
--- a/src/tools/clippy/tests/ui/copy_iterator.rs
+++ b/src/tools/clippy/tests/ui/copy_iterator.rs
@@ -4,6 +4,8 @@
struct Countdown(u8);
impl Iterator for Countdown {
+ //~^ ERROR: you are implementing `Iterator` on a `Copy` type
+ //~| NOTE: consider implementing `IntoIterator` instead
type Item = u8;
fn next(&mut self) -> Option<u8> {
diff --git a/src/tools/clippy/tests/ui/copy_iterator.stderr b/src/tools/clippy/tests/ui/copy_iterator.stderr
index 6bc6fd6b6..48c3385b6 100644
--- a/src/tools/clippy/tests/ui/copy_iterator.stderr
+++ b/src/tools/clippy/tests/ui/copy_iterator.stderr
@@ -2,9 +2,9 @@ error: you are implementing `Iterator` on a `Copy` type
--> $DIR/copy_iterator.rs:6:1
|
LL | / impl Iterator for Countdown {
-LL | | type Item = u8;
LL | |
-LL | | fn next(&mut self) -> Option<u8> {
+LL | |
+LL | | type Item = u8;
... |
LL | | }
LL | | }
@@ -12,6 +12,7 @@ LL | | }
|
= note: consider implementing `IntoIterator` instead
= note: `-D clippy::copy-iterator` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::copy_iterator)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs b/src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs
index bee29894b..882b66d67 100644
--- a/src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs
+++ b/src/tools/clippy/tests/ui/crashes/auxiliary/ice-7868-aux.rs
@@ -1,3 +1,5 @@
fn zero() {
unsafe { 0 };
+ //~^ ERROR: unsafe block missing a safety comment
+ //~| NOTE: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10148.rs b/src/tools/clippy/tests/ui/crashes/ice-10148.rs
index 0df22f413..d89d94edb 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-10148.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-10148.rs
@@ -1,5 +1,5 @@
-//@aux-build:../auxiliary/proc_macros.rs:proc-macro
-
+//@aux-build:../auxiliary/proc_macros.rs
+//@no-rustfix
extern crate proc_macros;
use proc_macros::with_span;
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10148.stderr b/src/tools/clippy/tests/ui/crashes/ice-10148.stderr
index f23e4433f..4d436e3aa 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-10148.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-10148.stderr
@@ -7,6 +7,7 @@ LL | println!(with_span!(""something ""));
| help: remove the empty string
|
= note: `-D clippy::println-empty-string` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr
index 0055fe061..fc5347c86 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr
@@ -11,6 +11,7 @@ LL | pub async fn bar<'a, T: 'a>(_: T) {}
| ^ has type `T` which is not `Send`
= note: `T` doesn't implement `std::marker::Send`
= note: `-D clippy::future-not-send` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]`
warning: 1 warning emitted
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10912.rs b/src/tools/clippy/tests/ui/crashes/ice-10912.rs
index 69d7f2f39..8dfce1942 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-10912.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-10912.rs
@@ -1,4 +1,8 @@
#![warn(clippy::unreadable_literal)]
+//@no-rustfix
fn f2() -> impl Sized { && 3.14159265358979323846E }
+//~^ ERROR: expected at least one digit in exponent
+//~| ERROR: long literal lacking separators
+//~| NOTE: `-D clippy::unreadable-literal` implied by `-D warnings`
fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10912.stderr b/src/tools/clippy/tests/ui/crashes/ice-10912.stderr
index a74ce7315..2be297b56 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-10912.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-10912.stderr
@@ -1,16 +1,17 @@
error: expected at least one digit in exponent
- --> $DIR/ice-10912.rs:2:28
+ --> $DIR/ice-10912.rs:3:28
|
LL | fn f2() -> impl Sized { && 3.14159265358979323846E }
| ^^^^^^^^^^^^^^^^^^^^^^^
error: long literal lacking separators
- --> $DIR/ice-10912.rs:2:28
+ --> $DIR/ice-10912.rs:3:28
|
LL | fn f2() -> impl Sized { && 3.14159265358979323846E }
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider: `3.141_592_653_589_793_238_46`
|
= note: `-D clippy::unreadable-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unreadable_literal)]`
error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11337.rs b/src/tools/clippy/tests/ui/crashes/ice-11337.rs
new file mode 100644
index 000000000..0bed4035f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-11337.rs
@@ -0,0 +1,9 @@
+#![feature(trait_alias)]
+
+trait Confusing<F> = Fn(i32) where F: Fn(u32);
+
+fn alias<T: Confusing<F>, F>(_: T, _: F) {}
+
+fn main() {
+ alias(|_| {}, |_| {});
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11422.fixed b/src/tools/clippy/tests/ui/crashes/ice-11422.fixed
new file mode 100644
index 000000000..ca5721cbb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-11422.fixed
@@ -0,0 +1,25 @@
+#![warn(clippy::implied_bounds_in_impls)]
+
+use std::fmt::Debug;
+use std::ops::*;
+
+fn gen() -> impl PartialOrd + Debug {}
+
+struct Bar {}
+trait Foo<T = Self> {}
+trait FooNested<T = Option<Self>> {}
+impl Foo for Bar {}
+impl FooNested for Bar {}
+
+fn foo() -> impl Foo + FooNested {
+ Bar {}
+}
+
+fn test_impl_ops() -> impl Add + Sub + Mul + Div {
+ 1
+}
+fn test_impl_assign_ops() -> impl AddAssign + SubAssign + MulAssign + DivAssign {
+ 1
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11422.rs b/src/tools/clippy/tests/ui/crashes/ice-11422.rs
new file mode 100644
index 000000000..355ec2480
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-11422.rs
@@ -0,0 +1,25 @@
+#![warn(clippy::implied_bounds_in_impls)]
+
+use std::fmt::Debug;
+use std::ops::*;
+
+fn gen() -> impl PartialOrd + PartialEq + Debug {}
+
+struct Bar {}
+trait Foo<T = Self> {}
+trait FooNested<T = Option<Self>> {}
+impl Foo for Bar {}
+impl FooNested for Bar {}
+
+fn foo() -> impl Foo + FooNested {
+ Bar {}
+}
+
+fn test_impl_ops() -> impl Add + Sub + Mul + Div {
+ 1
+}
+fn test_impl_assign_ops() -> impl AddAssign + SubAssign + MulAssign + DivAssign {
+ 1
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11422.stderr b/src/tools/clippy/tests/ui/crashes/ice-11422.stderr
new file mode 100644
index 000000000..fb80b5b14
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-11422.stderr
@@ -0,0 +1,16 @@
+error: this bound is already specified as the supertrait of `PartialOrd`
+ --> $DIR/ice-11422.rs:6:31
+ |
+LL | fn gen() -> impl PartialOrd + PartialEq + Debug {}
+ | ^^^^^^^^^
+ |
+ = note: `-D clippy::implied-bounds-in-impls` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::implied_bounds_in_impls)]`
+help: try removing this bound
+ |
+LL - fn gen() -> impl PartialOrd + PartialEq + Debug {}
+LL + fn gen() -> impl PartialOrd + Debug {}
+ |
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.fixed b/src/tools/clippy/tests/ui/crashes/ice-2774.fixed
new file mode 100644
index 000000000..96cf0d854
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-2774.fixed
@@ -0,0 +1,29 @@
+use std::collections::HashSet;
+
+// See rust-lang/rust-clippy#2774.
+
+#[derive(Eq, PartialEq, Debug, Hash)]
+pub struct Bar {
+ foo: Foo,
+}
+
+#[derive(Eq, PartialEq, Debug, Hash)]
+pub struct Foo;
+
+#[allow(clippy::implicit_hasher)]
+// This should not cause a "cannot relate bound region" ICE.
+pub fn add_barfoos_to_foos(bars: &HashSet<&Bar>) {
+ //~^ ERROR: the following explicit lifetimes could be elided: 'a
+ //~| NOTE: `-D clippy::needless-lifetimes` implied by `-D warnings`
+ let mut foos = HashSet::new();
+ foos.extend(bars.iter().map(|b| &b.foo));
+}
+
+#[allow(clippy::implicit_hasher)]
+// Also, this should not cause a "cannot relate bound region" ICE.
+pub fn add_barfoos_to_foos2(bars: &HashSet<&Bar>) {
+ let mut foos = HashSet::new();
+ foos.extend(bars.iter().map(|b| &b.foo));
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.rs b/src/tools/clippy/tests/ui/crashes/ice-2774.rs
index 88cfa1f92..464d7891c 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2774.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2774.rs
@@ -13,6 +13,8 @@ pub struct Foo;
#[allow(clippy::implicit_hasher)]
// This should not cause a "cannot relate bound region" ICE.
pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {
+ //~^ ERROR: the following explicit lifetimes could be elided: 'a
+ //~| NOTE: `-D clippy::needless-lifetimes` implied by `-D warnings`
let mut foos = HashSet::new();
foos.extend(bars.iter().map(|b| &b.foo));
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr
index a166ccb3e..ae9610c9a 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr
@@ -5,6 +5,7 @@ LL | pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {
| ^^ ^^
|
= note: `-D clippy::needless-lifetimes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]`
help: elide the lifetimes
|
LL - pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-360.rs b/src/tools/clippy/tests/ui/crashes/ice-360.rs
index 6555c19ca..0d10932b0 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-360.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-360.rs
@@ -1,12 +1,16 @@
fn main() {}
-
+//@no-rustfix
fn no_panic<T>(slice: &[T]) {
let mut iter = slice.iter();
loop {
+ //~^ ERROR: this loop never actually loops
+ //~| ERROR: this loop could be written as a `while let` loop
+ //~| NOTE: `-D clippy::while-let-loop` implied by `-D warnings`
let _ = match iter.next() {
Some(ele) => ele,
None => break,
};
loop {}
+ //~^ ERROR: empty `loop {}` wastes CPU cycles
}
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-360.stderr b/src/tools/clippy/tests/ui/crashes/ice-360.stderr
index a2e2ab8fd..a84697a9f 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-360.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-360.stderr
@@ -1,25 +1,41 @@
+error: this loop never actually loops
+ --> $DIR/ice-360.rs:5:5
+ |
+LL | / loop {
+LL | |
+LL | |
+LL | |
+... |
+LL | |
+LL | | }
+ | |_____^
+ |
+ = note: `#[deny(clippy::never_loop)]` on by default
+
error: this loop could be written as a `while let` loop
--> $DIR/ice-360.rs:5:5
|
LL | / loop {
-LL | | let _ = match iter.next() {
-LL | | Some(ele) => ele,
-LL | | None => break,
-LL | | };
-LL | | loop {}
+LL | |
+LL | |
+LL | |
+... |
+LL | |
LL | | }
| |_____^ help: try: `while let Some(ele) = iter.next() { .. }`
|
= note: `-D clippy::while-let-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]`
error: empty `loop {}` wastes CPU cycles
- --> $DIR/ice-360.rs:10:9
+ --> $DIR/ice-360.rs:13:9
|
LL | loop {}
| ^^^^^^^
|
= help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body
= note: `-D clippy::empty-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]`
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.fixed b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed
new file mode 100644
index 000000000..3f54b3269
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed
@@ -0,0 +1,11 @@
+#![deny(clippy::implicit_hasher)]
+
+use std::collections::HashSet;
+
+fn main() {}
+
+pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {
+ //~^ ERROR: parameter of type `HashSet` should be generalized over different hashers
+ let _ = [0u8; 0];
+ let _: HashSet<usize> = HashSet::default();
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.rs b/src/tools/clippy/tests/ui/crashes/ice-3717.rs
index f50714643..2890a9277 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3717.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.rs
@@ -5,6 +5,7 @@ use std::collections::HashSet;
fn main() {}
pub fn ice_3717(_: &HashSet<usize>) {
+ //~^ ERROR: parameter of type `HashSet` should be generalized over different hashers
let _ = [0u8; 0];
let _: HashSet<usize> = HashSet::new();
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3741.rs b/src/tools/clippy/tests/ui/crashes/ice-3741.rs
index 268c5ba0a..3106a2e72 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3741.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3741.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macro_crash.rs:proc-macro
+//@aux-build:proc_macro_crash.rs
#![warn(clippy::suspicious_else_formatting)]
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3891.rs b/src/tools/clippy/tests/ui/crashes/ice-3891.rs
index 05c5134c8..a3f1ccad7 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3891.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3891.rs
@@ -1,3 +1,4 @@
fn main() {
1x;
+ //~^ ERROR: invalid suffix `x` for number literal
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3969.rs b/src/tools/clippy/tests/ui/crashes/ice-3969.rs
index 9b68cac7f..d5676cbd9 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3969.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3969.rs
@@ -18,10 +18,13 @@ struct Dst<X: ?Sized> {
struct TwoStrs(str, str)
where
str: Sized;
+//~^ ERROR: trait bound str: std::marker::Sized does not depend on any type or lifetim
+//~| NOTE: `-D trivial-bounds` implied by `-D warnings`
fn unsized_local()
where
for<'a> Dst<dyn A + 'a>: Sized,
+ //~^ ERROR: trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend
{
let x: Dst<dyn A> = *(Box::new(Dst { x: 1 }) as Box<Dst<dyn A>>);
}
@@ -29,6 +32,7 @@ where
fn return_str() -> str
where
str: Sized,
+ //~^ ERROR: trait bound str: std::marker::Sized does not depend on any type or lifetim
{
*"Sized".to_string().into_boxed_str()
}
@@ -36,6 +40,7 @@ where
fn use_op(s: String) -> String
where
String: ::std::ops::Neg<Output = String>,
+ //~^ ERROR: trait bound std::string::String: std::ops::Neg does not depend on any type
{
-s
}
@@ -43,6 +48,7 @@ where
fn use_for()
where
i32: Iterator,
+ //~^ ERROR: trait bound i32: std::iter::Iterator does not depend on any type or lifeti
{
for _ in 2i32 {}
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3969.stderr b/src/tools/clippy/tests/ui/crashes/ice-3969.stderr
index 790180808..c6bef3004 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3969.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-3969.stderr
@@ -5,27 +5,28 @@ LL | str: Sized;
| ^^^^^
|
= note: `-D trivial-bounds` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(trivial_bounds)]`
error: trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
- --> $DIR/ice-3969.rs:24:30
+ --> $DIR/ice-3969.rs:26:30
|
LL | for<'a> Dst<dyn A + 'a>: Sized,
| ^^^^^
error: trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
- --> $DIR/ice-3969.rs:31:10
+ --> $DIR/ice-3969.rs:34:10
|
LL | str: Sized,
| ^^^^^
error: trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters
- --> $DIR/ice-3969.rs:38:13
+ --> $DIR/ice-3969.rs:42:13
|
LL | String: ::std::ops::Neg<Output = String>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters
- --> $DIR/ice-3969.rs:45:10
+ --> $DIR/ice-3969.rs:50:10
|
LL | i32: Iterator,
| ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5835.fixed b/src/tools/clippy/tests/ui/crashes/ice-5835.fixed
new file mode 100644
index 000000000..c0532d685
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-5835.fixed
@@ -0,0 +1,11 @@
+#[rustfmt::skip]
+pub struct Foo {
+ /// 位
+ //~^ ERROR: using tabs in doc comments is not recommended
+ //~| NOTE: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
+ /// ^ Do not remove this tab character.
+ /// It was required to trigger the ICE.
+ pub bar: u8,
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5835.rs b/src/tools/clippy/tests/ui/crashes/ice-5835.rs
index 5e99cb432..122bddd6a 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-5835.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-5835.rs
@@ -1,6 +1,8 @@
#[rustfmt::skip]
pub struct Foo {
/// 位
+ //~^ ERROR: using tabs in doc comments is not recommended
+ //~| NOTE: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
/// ^ Do not remove this tab character.
/// It was required to trigger the ICE.
pub bar: u8,
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5835.stderr b/src/tools/clippy/tests/ui/crashes/ice-5835.stderr
index c972bcb60..74d99a348 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-5835.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-5835.stderr
@@ -5,6 +5,7 @@ LL | /// 位
| ^^^^ help: consider using four spaces per tab
|
= note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5872.fixed b/src/tools/clippy/tests/ui/crashes/ice-5872.fixed
new file mode 100644
index 000000000..c8e870c62
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-5872.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::needless_collect)]
+
+fn main() {
+ let _ = vec![1, 2, 3].into_iter().next().is_none();
+ //~^ ERROR: avoid using `collect()` when not needed
+ //~| NOTE: `-D clippy::needless-collect` implied by `-D warnings`
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5872.rs b/src/tools/clippy/tests/ui/crashes/ice-5872.rs
index 68afa8f8c..c6ed31365 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-5872.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-5872.rs
@@ -2,4 +2,6 @@
fn main() {
let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();
+ //~^ ERROR: avoid using `collect()` when not needed
+ //~| NOTE: `-D clippy::needless-collect` implied by `-D warnings`
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5872.stderr b/src/tools/clippy/tests/ui/crashes/ice-5872.stderr
index a60ca345c..75a26ee31 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-5872.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-5872.stderr
@@ -5,6 +5,7 @@ LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
|
= note: `-D clippy::needless-collect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6250.rs b/src/tools/clippy/tests/ui/crashes/ice-6250.rs
index c33580ff6..32849f2ca 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6250.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6250.rs
@@ -1,6 +1,6 @@
// originally from glacier/fixed/77218.rs
// ice while adjusting...
-
+//@no-rustfix
pub struct Cache {
data: Vec<i32>,
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6251.rs b/src/tools/clippy/tests/ui/crashes/ice-6251.rs
index 6aa779aae..a81137a64 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6251.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6251.rs
@@ -1,6 +1,6 @@
// originally from glacier/fixed/77329.rs
// assertion failed: `(left == right) ; different DefIds
-
+//@no-rustfix
fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {
std::iter::empty()
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6251.stderr b/src/tools/clippy/tests/ui/crashes/ice-6251.stderr
index 68a5766c9..11081dc80 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6251.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6251.stderr
@@ -27,7 +27,7 @@ LL | fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {
| ^^^^^^^^^^^ expected `usize`, found closure
|
= note: expected type `usize`
- found closure `[closure@$DIR/ice-6251.rs:4:44: 4:53]`
+ found closure `{closure@$DIR/ice-6251.rs:4:44: 4:53}`
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.rs b/src/tools/clippy/tests/ui/crashes/ice-6252.rs
index 0ccf0aae9..67fbb0ff6 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6252.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6252.rs
@@ -1,5 +1,6 @@
// originally from glacier fixed/77919.rs
// encountered errors resolving bounds after type-checking
+//@no-rustfix
trait TypeVal<T> {
const VAL: T;
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr
index 4787282f5..cb65360d1 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr
@@ -1,5 +1,5 @@
error[E0412]: cannot find type `PhantomData` in this scope
- --> $DIR/ice-6252.rs:8:9
+ --> $DIR/ice-6252.rs:9:9
|
LL | _n: PhantomData,
| ^^^^^^^^^^^ not found in this scope
@@ -14,7 +14,7 @@ LL + use std::marker::PhantomData;
|
error[E0412]: cannot find type `VAL` in this scope
- --> $DIR/ice-6252.rs:10:63
+ --> $DIR/ice-6252.rs:11:63
|
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| ^^^ not found in this scope
@@ -25,7 +25,7 @@ LL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| +++++
error[E0046]: not all trait items implemented, missing: `VAL`
- --> $DIR/ice-6252.rs:10:1
+ --> $DIR/ice-6252.rs:11:1
|
LL | const VAL: T;
| ------------ `VAL` from trait
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6254.rs b/src/tools/clippy/tests/ui/crashes/ice-6254.rs
index 8af608903..2ae426cf7 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6254.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6254.rs
@@ -11,6 +11,8 @@ fn main() {
// This used to cause an ICE (https://github.com/rust-lang/rust/issues/78071)
match FOO_REF_REF {
FOO_REF_REF => {},
+ //~^ ERROR: to use a constant of type `Foo` in a pattern, `Foo` must be annotated
+ //~| NOTE: for more information, see issue #62411 <https://github.com/rust-lang/ru
Foo(_) => {},
}
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr
index 263c27d3d..6ace7dae8 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr
@@ -9,6 +9,7 @@ LL | FOO_REF_REF => {},
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
= note: `-D indirect-structural-match` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(indirect_structural_match)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7169.fixed b/src/tools/clippy/tests/ui/crashes/ice-7169.fixed
new file mode 100644
index 000000000..cf4077e4d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-7169.fixed
@@ -0,0 +1,13 @@
+#![allow(clippy::needless_if)]
+
+#[derive(Default)]
+struct A<T> {
+ a: Vec<A<T>>,
+ b: T,
+}
+
+fn main() {
+ if Ok::<_, ()>(A::<String>::default()).is_ok() {}
+ //~^ ERROR: redundant pattern matching, consider using `is_ok()`
+ //~| NOTE: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7169.rs b/src/tools/clippy/tests/ui/crashes/ice-7169.rs
index b203252f0..b09e6f384 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7169.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-7169.rs
@@ -8,4 +8,6 @@ struct A<T> {
fn main() {
if let Ok(_) = Ok::<_, ()>(A::<String>::default()) {}
+ //~^ ERROR: redundant pattern matching, consider using `is_ok()`
+ //~| NOTE: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7169.stderr b/src/tools/clippy/tests/ui/crashes/ice-7169.stderr
index 0cd028516..47947f89b 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7169.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-7169.stderr
@@ -5,6 +5,7 @@ LL | if let Ok(_) = Ok::<_, ()>(A::<String>::default()) {}
| -------^^^^^-------------------------------------- help: try: `if Ok::<_, ()>(A::<String>::default()).is_ok()`
|
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
index 1d8314e88..e5f14f221 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
@@ -6,6 +6,7 @@ LL | unsafe { 0 };
|
= help: consider adding a safety comment on the preceding line
= note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7869.rs b/src/tools/clippy/tests/ui/crashes/ice-7869.rs
index 8f97a063a..774e22f6b 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7869.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-7869.rs
@@ -1,4 +1,5 @@
enum Tila {
+ //~^ ERROR: all variants have the same prefix: `Työ`
TyöAlkoi,
TyöKeskeytyi,
TyöValmis,
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr
index 35d1e8fd2..7acace78a 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr
@@ -2,6 +2,7 @@ error: all variants have the same prefix: `Työ`
--> $DIR/ice-7869.rs:1:1
|
LL | / enum Tila {
+LL | |
LL | | TyöAlkoi,
LL | | TyöKeskeytyi,
LL | | TyöValmis,
@@ -10,6 +11,7 @@ LL | | }
|
= help: remove the prefixes and use full paths to the variants instead of glob imports
= note: `-D clippy::enum-variant-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8250.fixed b/src/tools/clippy/tests/ui/crashes/ice-8250.fixed
new file mode 100644
index 000000000..984b61258
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-8250.fixed
@@ -0,0 +1,8 @@
+fn _f(s: &str) -> Option<()> {
+ let _ = s[1..].split('.').next()?;
+ //~^ ERROR: unnecessary use of `splitn`
+ //~| NOTE: `-D clippy::needless-splitn` implied by `-D warnings`
+ Some(())
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8250.rs b/src/tools/clippy/tests/ui/crashes/ice-8250.rs
index d9a5ee116..c1b2e48ba 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-8250.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-8250.rs
@@ -1,5 +1,7 @@
fn _f(s: &str) -> Option<()> {
let _ = s[1..].splitn(2, '.').next()?;
+ //~^ ERROR: unnecessary use of `splitn`
+ //~| NOTE: `-D clippy::needless-splitn` implied by `-D warnings`
Some(())
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8250.stderr b/src/tools/clippy/tests/ui/crashes/ice-8250.stderr
index e6f3644ef..9c57f3345 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-8250.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-8250.stderr
@@ -5,6 +5,7 @@ LL | let _ = s[1..].splitn(2, '.').next()?;
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `s[1..].split('.')`
|
= note: `-D clippy::needless-splitn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_splitn)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8821.fixed b/src/tools/clippy/tests/ui/crashes/ice-8821.fixed
new file mode 100644
index 000000000..a25bb46f9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-8821.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::let_unit_value)]
+
+fn f() {}
+static FN: fn() = f;
+
+fn main() {
+ FN();
+ //~^ ERROR: this let-binding has unit value
+ //~| NOTE: `-D clippy::let-unit-value` implied by `-D warnings`
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8821.rs b/src/tools/clippy/tests/ui/crashes/ice-8821.rs
index fb87b79ae..082f7c926 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-8821.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-8821.rs
@@ -5,4 +5,6 @@ static FN: fn() = f;
fn main() {
let _: () = FN();
+ //~^ ERROR: this let-binding has unit value
+ //~| NOTE: `-D clippy::let-unit-value` implied by `-D warnings`
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8821.stderr b/src/tools/clippy/tests/ui/crashes/ice-8821.stderr
index 486096e0a..c8bd01fb1 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-8821.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-8821.stderr
@@ -5,6 +5,7 @@ LL | let _: () = FN();
| ^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `FN();`
|
= note: `-D clippy::let-unit-value` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8850.fixed b/src/tools/clippy/tests/ui/crashes/ice-8850.fixed
new file mode 100644
index 000000000..4569b9e87
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-8850.fixed
@@ -0,0 +1,31 @@
+fn fn_pointer_static() -> usize {
+ static FN: fn() -> usize = || 1;
+
+ FN() + 1
+ //~^ ERROR: returning the result of a `let` binding from a block
+ //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings`
+}
+
+fn fn_pointer_const() -> usize {
+ const FN: fn() -> usize = || 1;
+
+ FN() + 1
+ //~^ ERROR: returning the result of a `let` binding from a block
+}
+
+fn deref_to_dyn_fn() -> usize {
+ struct Derefs;
+ impl std::ops::Deref for Derefs {
+ type Target = dyn Fn() -> usize;
+
+ fn deref(&self) -> &Self::Target {
+ &|| 2
+ }
+ }
+ static FN: Derefs = Derefs;
+
+ FN() + 1
+ //~^ ERROR: returning the result of a `let` binding from a block
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8850.rs b/src/tools/clippy/tests/ui/crashes/ice-8850.rs
index f2747ab22..499756ece 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-8850.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-8850.rs
@@ -2,12 +2,15 @@ fn fn_pointer_static() -> usize {
static FN: fn() -> usize = || 1;
let res = FN() + 1;
res
+ //~^ ERROR: returning the result of a `let` binding from a block
+ //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings`
}
fn fn_pointer_const() -> usize {
const FN: fn() -> usize = || 1;
let res = FN() + 1;
res
+ //~^ ERROR: returning the result of a `let` binding from a block
}
fn deref_to_dyn_fn() -> usize {
@@ -22,6 +25,7 @@ fn deref_to_dyn_fn() -> usize {
static FN: Derefs = Derefs;
let res = FN() + 1;
res
+ //~^ ERROR: returning the result of a `let` binding from a block
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8850.stderr b/src/tools/clippy/tests/ui/crashes/ice-8850.stderr
index 620fd1eda..aa140f305 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-8850.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-8850.stderr
@@ -7,6 +7,7 @@ LL | res
| ^^^
|
= note: `-D clippy::let-and-return` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`
help: return the expression directly
|
LL ~
@@ -14,7 +15,7 @@ LL ~ FN() + 1
|
error: returning the result of a `let` binding from a block
- --> $DIR/ice-8850.rs:10:5
+ --> $DIR/ice-8850.rs:12:5
|
LL | let res = FN() + 1;
| ------------------- unnecessary `let` binding
@@ -28,7 +29,7 @@ LL ~ FN() + 1
|
error: returning the result of a `let` binding from a block
- --> $DIR/ice-8850.rs:24:5
+ --> $DIR/ice-8850.rs:27:5
|
LL | let res = FN() + 1;
| ------------------- unnecessary `let` binding
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9041.rs b/src/tools/clippy/tests/ui/crashes/ice-9041.rs
index 55cc9bc99..727d88f7f 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9041.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-9041.rs
@@ -1,8 +1,10 @@
pub struct Thing;
-
+//@no-rustfix
pub fn has_thing(things: &[Thing]) -> bool {
let is_thing_ready = |_peer: &Thing| -> bool { todo!() };
things.iter().find(|p| is_thing_ready(p)).is_some()
+ //~^ ERROR: called `is_some()` after searching an `Iterator` with `find`
+ //~| NOTE: `-D clippy::search-is-some` implied by `-D warnings`
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr
index f5038f0a8..49c9bdc30 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr
@@ -5,6 +5,7 @@ LL | things.iter().find(|p| is_thing_ready(p)).is_some()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|p| is_thing_ready(&p))`
|
= note: `-D clippy::search-is-some` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9405.stderr b/src/tools/clippy/tests/ui/crashes/ice-9405.stderr
index 9a6e410f2..56649a2bd 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9405.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-9405.stderr
@@ -1,7 +1,7 @@
warning: multiple lines skipped by escaped newline
--> $DIR/ice-9405.rs:6:10
|
-LL | "/
+LL | "\
| __________^
LL | |
LL | | {}",
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9445.rs b/src/tools/clippy/tests/ui/crashes/ice-9445.rs
index c67b22f6f..b6afbd33c 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9445.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-9445.rs
@@ -1,3 +1,5 @@
const UNINIT: core::mem::MaybeUninit<core::cell::Cell<&'static ()>> = core::mem::MaybeUninit::uninit();
+//~^ ERROR: a `const` item should never be interior mutable
+//~| NOTE: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9445.stderr b/src/tools/clippy/tests/ui/crashes/ice-9445.stderr
index a59d098e5..9307409ba 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9445.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-9445.stderr
@@ -7,6 +7,7 @@ LL | const UNINIT: core::mem::MaybeUninit<core::cell::Cell<&'static ()>> = core:
| make this a static item (maybe with lazy_static)
|
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9463.rs b/src/tools/clippy/tests/ui/crashes/ice-9463.rs
index 9564e77c2..fa83d25b3 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9463.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-9463.rs
@@ -1,5 +1,9 @@
#![deny(arithmetic_overflow)]
fn main() {
let _x = -1_i32 >> -1;
+ //~^ ERROR: this arithmetic operation will overflow
let _y = 1u32 >> 10000000000000u32;
+ //~^ ERROR: this arithmetic operation will overflow
+ //~| ERROR: literal out of range for `u32`
+ //~| NOTE: the literal `10000000000000u32` does not fit into the type `u32` whose rang
}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr
index 2b425e85a..911795694 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr
@@ -11,13 +11,13 @@ LL | #![deny(arithmetic_overflow)]
| ^^^^^^^^^^^^^^^^^^^
error: this arithmetic operation will overflow
- --> $DIR/ice-9463.rs:4:14
+ --> $DIR/ice-9463.rs:5:14
|
LL | let _y = 1u32 >> 10000000000000u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to shift right by `1316134912_u32`, which would overflow
error: literal out of range for `u32`
- --> $DIR/ice-9463.rs:4:22
+ --> $DIR/ice-9463.rs:5:22
|
LL | let _y = 1u32 >> 10000000000000u32;
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/crashes/ice-96721.fixed b/src/tools/clippy/tests/ui/crashes/ice-96721.fixed
new file mode 100644
index 000000000..976189d0b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-96721.fixed
@@ -0,0 +1,10 @@
+macro_rules! foo {
+ () => {
+ "bar.rs"
+ };
+}
+
+#[path = "file"] //~ ERROR: malformed `path` attribute
+mod abc {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
new file mode 100644
index 000000000..8bd9eea75
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
@@ -0,0 +1,21 @@
+#![deny(clippy::needless_lifetimes)]
+#![allow(dead_code)]
+
+trait Foo {}
+
+struct Bar;
+
+struct Baz<'a> {
+ bar: &'a Bar,
+}
+
+impl<'a> Foo for Baz<'a> {}
+
+impl Bar {
+ fn baz(&self) -> impl Foo + '_ {
+ //~^ ERROR: the following explicit lifetimes could be elided: 'a
+ Baz { bar: self }
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
index 376ff97ba..06947e3a3 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
@@ -13,6 +13,7 @@ impl<'a> Foo for Baz<'a> {}
impl Bar {
fn baz<'a>(&'a self) -> impl Foo + 'a {
+ //~^ ERROR: the following explicit lifetimes could be elided: 'a
Baz { bar: self }
}
}
diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed
new file mode 100644
index 000000000..774dea391
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed
@@ -0,0 +1,10 @@
+// https://github.com/rust-lang/rust/issues/107147
+
+#![warn(clippy::needless_pass_by_value)]
+
+struct Foo<'a>(&'a [(); 100]);
+
+fn test(x: &Foo<'_>) {}
+//~^ ERROR: this argument is passed by value, but not consumed in the function body
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs
index dd3d8b8b6..f3d887192 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs
+++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.rs
@@ -5,5 +5,6 @@
struct Foo<'a>(&'a [(); 100]);
fn test(x: Foo<'_>) {}
+//~^ ERROR: this argument is passed by value, but not consumed in the function body
fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
index 7a0a64897..6d4539399 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
+++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
@@ -10,6 +10,7 @@ help: consider marking this type as `Copy`
LL | struct Foo<'a>(&'a [(); 100]);
| ^^^^^^^^^^^^^^
= note: `-D clippy::needless-pass-by-value` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.fixed b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed
index 12a7b9470..bd91389c8 100644
--- a/src/tools/clippy/tests/ui/crate_in_macro_def.fixed
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::crate_in_macro_def)]
mod hygienic {
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.rs b/src/tools/clippy/tests/ui/crate_in_macro_def.rs
index a1a9eabf6..f6fa338ee 100644
--- a/src/tools/clippy/tests/ui/crate_in_macro_def.rs
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::crate_in_macro_def)]
mod hygienic {
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.stderr b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr
index 9ac5937dc..3e6246182 100644
--- a/src/tools/clippy/tests/ui/crate_in_macro_def.stderr
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr
@@ -1,10 +1,11 @@
error: `crate` references the macro call's crate
- --> $DIR/crate_in_macro_def.rs:19:28
+ --> $DIR/crate_in_macro_def.rs:18:28
|
LL | println!("{}", crate::unhygienic::MESSAGE);
| ^^^^^ help: to reference the macro definition's crate, use: `$crate`
|
= note: `-D clippy::crate-in-macro-def` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::crate_in_macro_def)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.fixed b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.fixed
new file mode 100644
index 000000000..32bccd3a0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.fixed
@@ -0,0 +1,13 @@
+#![no_std]
+#![feature(lang_items, start, libc)]
+#![crate_type = "lib"]
+
+use core::panic::PanicInfo;
+
+#[warn(clippy::all)]
+fn main() {
+ let mut a = 42;
+ let mut b = 1337;
+
+ core::mem::swap(&mut a, &mut b);
+}
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.rs b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.rs
index d3571eaf0..8ed45a334 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.rs
+++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.rs
@@ -10,5 +10,7 @@ fn main() {
let mut b = 1337;
a = b;
+ //~^ ERROR: this looks like you are trying to swap `a` and `b`
+ //~| NOTE: or maybe you should use `core::mem::replace`?
b = a;
}
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
index 7d8ea3f76..01033246d 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
+++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
@@ -2,11 +2,14 @@ error: this looks like you are trying to swap `a` and `b`
--> $DIR/no_std_swap.rs:12:5
|
LL | / a = b;
+LL | |
+LL | |
LL | | b = a;
| |_________^ help: try: `core::mem::swap(&mut a, &mut b)`
|
= note: or maybe you should use `core::mem::replace`?
= note: `-D clippy::almost-swapped` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::almost_swapped)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.rs b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.rs
index 89ff66099..c2c3e0958 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.rs
+++ b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.rs
@@ -3,4 +3,5 @@
fn main() {
println!("Hello, World!");
main();
+ //~^ ERROR: recursing into entrypoint `main`
}
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr
index 82c68bd1c..f3ffd6a10 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr
+++ b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr
@@ -6,6 +6,7 @@ LL | main();
|
= help: consider using another function for this recursion
= note: `-D clippy::main-recursion` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::main_recursion)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/create_dir.fixed b/src/tools/clippy/tests/ui/create_dir.fixed
index 5de3e9fea..8fbf7dd19 100644
--- a/src/tools/clippy/tests/ui/create_dir.fixed
+++ b/src/tools/clippy/tests/ui/create_dir.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused_must_use)]
#![warn(clippy::create_dir)]
diff --git a/src/tools/clippy/tests/ui/create_dir.rs b/src/tools/clippy/tests/ui/create_dir.rs
index d375bfb4a..af2c326ec 100644
--- a/src/tools/clippy/tests/ui/create_dir.rs
+++ b/src/tools/clippy/tests/ui/create_dir.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused_must_use)]
#![warn(clippy::create_dir)]
diff --git a/src/tools/clippy/tests/ui/create_dir.stderr b/src/tools/clippy/tests/ui/create_dir.stderr
index 67298fc47..037e6ff17 100644
--- a/src/tools/clippy/tests/ui/create_dir.stderr
+++ b/src/tools/clippy/tests/ui/create_dir.stderr
@@ -1,13 +1,14 @@
error: calling `std::fs::create_dir` where there may be a better way
- --> $DIR/create_dir.rs:11:5
+ --> $DIR/create_dir.rs:10:5
|
LL | std::fs::create_dir("foo");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `create_dir_all("foo")`
|
= note: `-D clippy::create-dir` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::create_dir)]`
error: calling `std::fs::create_dir` where there may be a better way
- --> $DIR/create_dir.rs:12:5
+ --> $DIR/create_dir.rs:11:5
|
LL | std::fs::create_dir("bar").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `create_dir_all("bar")`
diff --git a/src/tools/clippy/tests/ui/dbg_macro.rs b/src/tools/clippy/tests/ui/dbg_macro.rs
index 6c63c0989..149b08476 100644
--- a/src/tools/clippy/tests/ui/dbg_macro.rs
+++ b/src/tools/clippy/tests/ui/dbg_macro.rs
@@ -1,24 +1,36 @@
+//@no-rustfix
+
#![warn(clippy::dbg_macro)]
fn foo(n: u32) -> u32 {
if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
+ //~| NOTE: `-D clippy::dbg-macro` implied by `-D warnings`
}
fn bar(_: ()) {}
fn factorial(n: u32) -> u32 {
if dbg!(n <= 1) {
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
dbg!(1)
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
} else {
dbg!(n * factorial(n - 1))
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
}
}
fn main() {
dbg!(42);
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
dbg!(dbg!(dbg!(42)));
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
foo(3) + dbg!(factorial(4));
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
dbg!(1, 2, dbg!(3, 4));
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
dbg!(1, 2, 3, 4, 5);
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
}
fn issue9914() {
@@ -39,11 +51,16 @@ fn issue9914() {
}
dbg!();
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
#[allow(clippy::let_unit_value)]
let _ = dbg!();
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
bar(dbg!());
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
foo!(dbg!());
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
foo2!(foo!(dbg!()));
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
expand_to_dbg!();
}
@@ -65,22 +82,26 @@ mod issue7274 {
struct MyThing;
define_thing!(MyThing, {
dbg!(2);
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
});
}
#[test]
pub fn issue8481() {
dbg!(1);
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
}
#[cfg(test)]
fn foo2() {
dbg!(1);
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
}
#[cfg(test)]
mod mod1 {
fn func() {
dbg!(1);
+ //~^ ERROR: the `dbg!` macro is intended as a debugging tool
}
}
diff --git a/src/tools/clippy/tests/ui/dbg_macro.stderr b/src/tools/clippy/tests/ui/dbg_macro.stderr
index 3d2926259..f45a7ba1f 100644
--- a/src/tools/clippy/tests/ui/dbg_macro.stderr
+++ b/src/tools/clippy/tests/ui/dbg_macro.stderr
@@ -1,17 +1,18 @@
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:4:22
+ --> $DIR/dbg_macro.rs:6:22
|
LL | if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::dbg-macro` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`
help: remove the invocation before committing it to a version control system
|
LL | if let Some(n) = n.checked_sub(4) { n } else { n }
| ~~~~~~~~~~~~~~~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:9:8
+ --> $DIR/dbg_macro.rs:13:8
|
LL | if dbg!(n <= 1) {
| ^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | if n <= 1 {
| ~~~~~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:10:9
+ --> $DIR/dbg_macro.rs:15:9
|
LL | dbg!(1)
| ^^^^^^^
@@ -33,7 +34,7 @@ LL | 1
|
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:12:9
+ --> $DIR/dbg_macro.rs:18:9
|
LL | dbg!(n * factorial(n - 1))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +45,7 @@ LL | n * factorial(n - 1)
|
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:17:5
+ --> $DIR/dbg_macro.rs:24:5
|
LL | dbg!(42);
| ^^^^^^^^
@@ -55,7 +56,7 @@ LL | 42;
| ~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:18:5
+ --> $DIR/dbg_macro.rs:26:5
|
LL | dbg!(dbg!(dbg!(42)));
| ^^^^^^^^^^^^^^^^^^^^
@@ -66,7 +67,7 @@ LL | dbg!(dbg!(42));
| ~~~~~~~~~~~~~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:19:14
+ --> $DIR/dbg_macro.rs:28:14
|
LL | foo(3) + dbg!(factorial(4));
| ^^^^^^^^^^^^^^^^^^
@@ -77,7 +78,7 @@ LL | foo(3) + factorial(4);
| ~~~~~~~~~~~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:20:5
+ --> $DIR/dbg_macro.rs:30:5
|
LL | dbg!(1, 2, dbg!(3, 4));
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +89,7 @@ LL | (1, 2, dbg!(3, 4));
| ~~~~~~~~~~~~~~~~~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:21:5
+ --> $DIR/dbg_macro.rs:32:5
|
LL | dbg!(1, 2, 3, 4, 5);
| ^^^^^^^^^^^^^^^^^^^
@@ -99,7 +100,7 @@ LL | (1, 2, 3, 4, 5);
| ~~~~~~~~~~~~~~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:41:5
+ --> $DIR/dbg_macro.rs:53:5
|
LL | dbg!();
| ^^^^^^^
@@ -111,7 +112,7 @@ LL +
|
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:43:13
+ --> $DIR/dbg_macro.rs:56:13
|
LL | let _ = dbg!();
| ^^^^^^
@@ -122,7 +123,7 @@ LL | let _ = ();
| ~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:44:9
+ --> $DIR/dbg_macro.rs:58:9
|
LL | bar(dbg!());
| ^^^^^^
@@ -133,7 +134,7 @@ LL | bar(());
| ~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:45:10
+ --> $DIR/dbg_macro.rs:60:10
|
LL | foo!(dbg!());
| ^^^^^^
@@ -144,7 +145,7 @@ LL | foo!(());
| ~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:46:16
+ --> $DIR/dbg_macro.rs:62:16
|
LL | foo2!(foo!(dbg!()));
| ^^^^^^
@@ -155,7 +156,7 @@ LL | foo2!(foo!(()));
| ~~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:67:9
+ --> $DIR/dbg_macro.rs:84:9
|
LL | dbg!(2);
| ^^^^^^^
@@ -166,7 +167,7 @@ LL | 2;
| ~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:73:5
+ --> $DIR/dbg_macro.rs:91:5
|
LL | dbg!(1);
| ^^^^^^^
@@ -177,7 +178,7 @@ LL | 1;
| ~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:78:5
+ --> $DIR/dbg_macro.rs:97:5
|
LL | dbg!(1);
| ^^^^^^^
@@ -188,7 +189,7 @@ LL | 1;
| ~
error: the `dbg!` macro is intended as a debugging tool
- --> $DIR/dbg_macro.rs:84:9
+ --> $DIR/dbg_macro.rs:104:9
|
LL | dbg!(1);
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/debug_assert_with_mut_call.rs b/src/tools/clippy/tests/ui/debug_assert_with_mut_call.rs
index 46faa0a7b..8d04be777 100644
--- a/src/tools/clippy/tests/ui/debug_assert_with_mut_call.rs
+++ b/src/tools/clippy/tests/ui/debug_assert_with_mut_call.rs
@@ -40,13 +40,20 @@ fn func_non_mutable() {
fn func_mutable() {
debug_assert!(bool_mut(&mut 3));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
+ //~| NOTE: `-D clippy::debug-assert-with-mut-call` implied by `-D warnings`
debug_assert!(!bool_mut(&mut 3));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
debug_assert_eq!(0, u32_mut(&mut 3));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
debug_assert_eq!(u32_mut(&mut 3), 0);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
debug_assert_ne!(1, u32_mut(&mut 3));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!`
debug_assert_ne!(u32_mut(&mut 3), 1);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!`
}
fn method_non_mutable() {
@@ -62,20 +69,33 @@ fn method_non_mutable() {
fn method_mutable() {
debug_assert!(S.bool_self_mut());
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
debug_assert!(!S.bool_self_mut());
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
debug_assert!(S.bool_self_ref_arg_mut(&mut 3));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
debug_assert!(S.bool_self_mut_arg_ref(&3));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
debug_assert!(S.bool_self_mut_arg_mut(&mut 3));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
debug_assert_eq!(S.u32_self_mut(), 0);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
debug_assert_eq!(S.u32_self_mut_arg_ref(&3), 0);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
debug_assert_eq!(S.u32_self_ref_arg_mut(&mut 3), 0);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
debug_assert_eq!(S.u32_self_mut_arg_mut(&mut 3), 0);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
debug_assert_ne!(S.u32_self_mut(), 1);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!`
debug_assert_ne!(S.u32_self_mut_arg_ref(&3), 1);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!`
debug_assert_ne!(S.u32_self_ref_arg_mut(&mut 3), 1);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!`
debug_assert_ne!(S.u32_self_mut_arg_mut(&mut 3), 1);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!`
}
fn misc() {
@@ -84,27 +104,35 @@ fn misc() {
debug_assert_eq!(v.get(0), Some(&1));
debug_assert_ne!(v[0], 2);
debug_assert_eq!(v.pop(), Some(1));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
debug_assert_ne!(Some(3), v.pop());
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_ne!`
let a = &mut 3;
debug_assert!(bool_mut(a));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
// nested
debug_assert!(!(bool_ref(&u32_mut(&mut 3))));
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
// chained
debug_assert_eq!(v.pop().unwrap(), 3);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert_eq!`
// format args
debug_assert!(bool_ref(&3), "w/o format");
debug_assert!(bool_mut(&mut 3), "w/o format");
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
debug_assert!(bool_ref(&3), "{} format", "w/");
debug_assert!(bool_mut(&mut 3), "{} format", "w/");
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!`
// sub block
let mut x = 42_u32;
debug_assert!({
bool_mut(&mut x);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!
x > 10
});
@@ -112,6 +140,7 @@ fn misc() {
debug_assert!((|| {
let mut x = 42;
bool_mut(&mut x);
+ //~^ ERROR: do not call a function with mutable arguments inside of `debug_assert!
x > 10
})());
}
diff --git a/src/tools/clippy/tests/ui/debug_assert_with_mut_call.stderr b/src/tools/clippy/tests/ui/debug_assert_with_mut_call.stderr
index a2ca71b57..b993bbf55 100644
--- a/src/tools/clippy/tests/ui/debug_assert_with_mut_call.stderr
+++ b/src/tools/clippy/tests/ui/debug_assert_with_mut_call.stderr
@@ -5,165 +5,166 @@ LL | debug_assert!(bool_mut(&mut 3));
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::debug-assert-with-mut-call` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::debug_assert_with_mut_call)]`
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:43:20
+ --> $DIR/debug_assert_with_mut_call.rs:45:20
|
LL | debug_assert!(!bool_mut(&mut 3));
| ^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:45:25
+ --> $DIR/debug_assert_with_mut_call.rs:48:25
|
LL | debug_assert_eq!(0, u32_mut(&mut 3));
| ^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:46:22
+ --> $DIR/debug_assert_with_mut_call.rs:50:22
|
LL | debug_assert_eq!(u32_mut(&mut 3), 0);
| ^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_ne!`
- --> $DIR/debug_assert_with_mut_call.rs:48:25
+ --> $DIR/debug_assert_with_mut_call.rs:53:25
|
LL | debug_assert_ne!(1, u32_mut(&mut 3));
| ^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_ne!`
- --> $DIR/debug_assert_with_mut_call.rs:49:22
+ --> $DIR/debug_assert_with_mut_call.rs:55:22
|
LL | debug_assert_ne!(u32_mut(&mut 3), 1);
| ^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:64:19
+ --> $DIR/debug_assert_with_mut_call.rs:71:19
|
LL | debug_assert!(S.bool_self_mut());
| ^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:65:20
+ --> $DIR/debug_assert_with_mut_call.rs:73:20
|
LL | debug_assert!(!S.bool_self_mut());
| ^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:66:19
+ --> $DIR/debug_assert_with_mut_call.rs:75:19
|
LL | debug_assert!(S.bool_self_ref_arg_mut(&mut 3));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:67:19
+ --> $DIR/debug_assert_with_mut_call.rs:77:19
|
LL | debug_assert!(S.bool_self_mut_arg_ref(&3));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:68:19
+ --> $DIR/debug_assert_with_mut_call.rs:79:19
|
LL | debug_assert!(S.bool_self_mut_arg_mut(&mut 3));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:70:22
+ --> $DIR/debug_assert_with_mut_call.rs:82:22
|
LL | debug_assert_eq!(S.u32_self_mut(), 0);
| ^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:71:22
+ --> $DIR/debug_assert_with_mut_call.rs:84:22
|
LL | debug_assert_eq!(S.u32_self_mut_arg_ref(&3), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:72:22
+ --> $DIR/debug_assert_with_mut_call.rs:86:22
|
LL | debug_assert_eq!(S.u32_self_ref_arg_mut(&mut 3), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:73:22
+ --> $DIR/debug_assert_with_mut_call.rs:88:22
|
LL | debug_assert_eq!(S.u32_self_mut_arg_mut(&mut 3), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_ne!`
- --> $DIR/debug_assert_with_mut_call.rs:75:22
+ --> $DIR/debug_assert_with_mut_call.rs:91:22
|
LL | debug_assert_ne!(S.u32_self_mut(), 1);
| ^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_ne!`
- --> $DIR/debug_assert_with_mut_call.rs:76:22
+ --> $DIR/debug_assert_with_mut_call.rs:93:22
|
LL | debug_assert_ne!(S.u32_self_mut_arg_ref(&3), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_ne!`
- --> $DIR/debug_assert_with_mut_call.rs:77:22
+ --> $DIR/debug_assert_with_mut_call.rs:95:22
|
LL | debug_assert_ne!(S.u32_self_ref_arg_mut(&mut 3), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_ne!`
- --> $DIR/debug_assert_with_mut_call.rs:78:22
+ --> $DIR/debug_assert_with_mut_call.rs:97:22
|
LL | debug_assert_ne!(S.u32_self_mut_arg_mut(&mut 3), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:86:22
+ --> $DIR/debug_assert_with_mut_call.rs:106:22
|
LL | debug_assert_eq!(v.pop(), Some(1));
| ^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_ne!`
- --> $DIR/debug_assert_with_mut_call.rs:87:31
+ --> $DIR/debug_assert_with_mut_call.rs:108:31
|
LL | debug_assert_ne!(Some(3), v.pop());
| ^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:90:19
+ --> $DIR/debug_assert_with_mut_call.rs:112:19
|
LL | debug_assert!(bool_mut(a));
| ^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:93:31
+ --> $DIR/debug_assert_with_mut_call.rs:116:31
|
LL | debug_assert!(!(bool_ref(&u32_mut(&mut 3))));
| ^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert_eq!`
- --> $DIR/debug_assert_with_mut_call.rs:96:22
+ --> $DIR/debug_assert_with_mut_call.rs:120:22
|
LL | debug_assert_eq!(v.pop().unwrap(), 3);
| ^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:100:19
+ --> $DIR/debug_assert_with_mut_call.rs:125:19
|
LL | debug_assert!(bool_mut(&mut 3), "w/o format");
| ^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:102:19
+ --> $DIR/debug_assert_with_mut_call.rs:128:19
|
LL | debug_assert!(bool_mut(&mut 3), "{} format", "w/");
| ^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:107:9
+ --> $DIR/debug_assert_with_mut_call.rs:134:9
|
LL | bool_mut(&mut x);
| ^^^^^^^^^^^^^^^^
error: do not call a function with mutable arguments inside of `debug_assert!`
- --> $DIR/debug_assert_with_mut_call.rs:114:9
+ --> $DIR/debug_assert_with_mut_call.rs:142:9
|
LL | bool_mut(&mut x);
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/decimal_literal_representation.fixed b/src/tools/clippy/tests/ui/decimal_literal_representation.fixed
index a6eb8c214..e34f48b65 100644
--- a/src/tools/clippy/tests/ui/decimal_literal_representation.fixed
+++ b/src/tools/clippy/tests/ui/decimal_literal_representation.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[warn(clippy::decimal_literal_representation)]
#[allow(unused_variables)]
#[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/decimal_literal_representation.rs b/src/tools/clippy/tests/ui/decimal_literal_representation.rs
index 7c666d6d7..bcc4d0df9 100644
--- a/src/tools/clippy/tests/ui/decimal_literal_representation.rs
+++ b/src/tools/clippy/tests/ui/decimal_literal_representation.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[warn(clippy::decimal_literal_representation)]
#[allow(unused_variables)]
#[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/decimal_literal_representation.stderr b/src/tools/clippy/tests/ui/decimal_literal_representation.stderr
index 8d50c8f83..f1d4d744e 100644
--- a/src/tools/clippy/tests/ui/decimal_literal_representation.stderr
+++ b/src/tools/clippy/tests/ui/decimal_literal_representation.stderr
@@ -1,43 +1,44 @@
error: integer literal has a better hexadecimal representation
- --> $DIR/decimal_literal_representation.rs:18:9
+ --> $DIR/decimal_literal_representation.rs:16:9
|
LL | 32_773, // 0x8005
| ^^^^^^ help: consider: `0x8005`
|
= note: `-D clippy::decimal-literal-representation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::decimal_literal_representation)]`
error: integer literal has a better hexadecimal representation
- --> $DIR/decimal_literal_representation.rs:19:9
+ --> $DIR/decimal_literal_representation.rs:17:9
|
LL | 65_280, // 0xFF00
| ^^^^^^ help: consider: `0xFF00`
error: integer literal has a better hexadecimal representation
- --> $DIR/decimal_literal_representation.rs:20:9
+ --> $DIR/decimal_literal_representation.rs:18:9
|
LL | 2_131_750_927, // 0x7F0F_F00F
| ^^^^^^^^^^^^^ help: consider: `0x7F0F_F00F`
error: integer literal has a better hexadecimal representation
- --> $DIR/decimal_literal_representation.rs:21:9
+ --> $DIR/decimal_literal_representation.rs:19:9
|
LL | 2_147_483_647, // 0x7FFF_FFFF
| ^^^^^^^^^^^^^ help: consider: `0x7FFF_FFFF`
error: integer literal has a better hexadecimal representation
- --> $DIR/decimal_literal_representation.rs:23:9
+ --> $DIR/decimal_literal_representation.rs:21:9
|
LL | 4_042_322_160, // 0xF0F0_F0F0
| ^^^^^^^^^^^^^ help: consider: `0xF0F0_F0F0`
error: integer literal has a better hexadecimal representation
- --> $DIR/decimal_literal_representation.rs:24:9
+ --> $DIR/decimal_literal_representation.rs:22:9
|
LL | 32_773usize, // 0x8005_usize
| ^^^^^^^^^^^ help: consider: `0x8005_usize`
error: integer literal has a better hexadecimal representation
- --> $DIR/decimal_literal_representation.rs:25:9
+ --> $DIR/decimal_literal_representation.rs:23:9
|
LL | 2_131_750_927isize, // 0x7F0F_F00F_isize
| ^^^^^^^^^^^^^^^^^^ help: consider: `0x7F0F_F00F_isize`
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr
index 6070df749..6d3437388 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/enums.stderr
@@ -7,6 +7,7 @@ LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(tru
| make this a static item (maybe with lazy_static)
|
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
error: a `const` item should never be interior mutable
--> $DIR/enums.rs:23:1
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
index 0259f6a4a..cc286b9f7 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
@@ -7,6 +7,7 @@ LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5);
| make this a static item (maybe with lazy_static)
|
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
error: a `const` item should never be interior mutable
--> $DIR/others.rs:10:1
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
index ef62919df..7647cd96f 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/traits.stderr
@@ -5,6 +5,7 @@ LL | const ATOMIC: AtomicUsize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
error: a `const` item should never be interior mutable
--> $DIR/traits.rs:9:9
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs
index da0816830..190d636eb 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.rs
+++ b/src/tools/clippy/tests/ui/def_id_nocore.rs
@@ -25,6 +25,7 @@ struct A;
impl A {
pub fn as_ref(self) -> &'static str {
+ //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mutabl
"A"
}
}
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr
index f8fc17e87..bfd0de4e1 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.stderr
+++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr
@@ -6,6 +6,7 @@ LL | pub fn as_ref(self) -> &'static str {
|
= help: consider choosing a less ambiguous name
= note: `-D clippy::wrong-self-convention` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed b/src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed
index ac5fe38ff..3047c221d 100644
--- a/src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed
+++ b/src/tools/clippy/tests/ui/default_constructed_unit_structs.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::default_constructed_unit_structs)]
use std::marker::PhantomData;
diff --git a/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs b/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs
index de7f14ffb..66afedb23 100644
--- a/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs
+++ b/src/tools/clippy/tests/ui/default_constructed_unit_structs.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::default_constructed_unit_structs)]
use std::marker::PhantomData;
diff --git a/src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr b/src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr
index 13abb9149..434c72aa9 100644
--- a/src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr
+++ b/src/tools/clippy/tests/ui/default_constructed_unit_structs.stderr
@@ -1,37 +1,38 @@
error: use of `default` to create a unit struct
- --> $DIR/default_constructed_unit_structs.rs:13:13
+ --> $DIR/default_constructed_unit_structs.rs:11:13
|
LL | Self::default()
| ^^^^^^^^^^^ help: remove this call to `default`
|
= note: `-D clippy::default-constructed-unit-structs` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::default_constructed_unit_structs)]`
error: use of `default` to create a unit struct
- --> $DIR/default_constructed_unit_structs.rs:55:31
+ --> $DIR/default_constructed_unit_structs.rs:53:31
|
LL | inner: PhantomData::default(),
| ^^^^^^^^^^^ help: remove this call to `default`
error: use of `default` to create a unit struct
- --> $DIR/default_constructed_unit_structs.rs:128:33
+ --> $DIR/default_constructed_unit_structs.rs:126:33
|
LL | let _ = PhantomData::<usize>::default();
| ^^^^^^^^^^^ help: remove this call to `default`
error: use of `default` to create a unit struct
- --> $DIR/default_constructed_unit_structs.rs:129:42
+ --> $DIR/default_constructed_unit_structs.rs:127:42
|
LL | let _: PhantomData<i32> = PhantomData::default();
| ^^^^^^^^^^^ help: remove this call to `default`
error: use of `default` to create a unit struct
- --> $DIR/default_constructed_unit_structs.rs:130:55
+ --> $DIR/default_constructed_unit_structs.rs:128:55
|
LL | let _: PhantomData<i32> = std::marker::PhantomData::default();
| ^^^^^^^^^^^ help: remove this call to `default`
error: use of `default` to create a unit struct
- --> $DIR/default_constructed_unit_structs.rs:131:23
+ --> $DIR/default_constructed_unit_structs.rs:129:23
|
LL | let _ = UnitStruct::default();
| ^^^^^^^^^^^ help: remove this call to `default`
diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed
index f44d34576..3298a222b 100644
--- a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed
+++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::default_instead_of_iter_empty)]
#![allow(dead_code)]
use std::collections::HashMap;
diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs
index 1c649df25..75b088a99 100644
--- a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs
+++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::default_instead_of_iter_empty)]
#![allow(dead_code)]
use std::collections::HashMap;
diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.stderr b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.stderr
index 460fc84de..48d6c02d1 100644
--- a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.stderr
+++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.stderr
@@ -1,19 +1,20 @@
error: `std::iter::empty()` is the more idiomatic way
- --> $DIR/default_instead_of_iter_empty.rs:13:13
+ --> $DIR/default_instead_of_iter_empty.rs:12:13
|
LL | let _ = std::iter::Empty::<usize>::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty::<usize>()`
|
= note: `-D clippy::default-instead-of-iter-empty` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]`
error: `std::iter::empty()` is the more idiomatic way
- --> $DIR/default_instead_of_iter_empty.rs:14:13
+ --> $DIR/default_instead_of_iter_empty.rs:13:13
|
LL | let _ = std::iter::Empty::<HashMap<usize, usize>>::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty::<HashMap<usize, usize>>()`
error: `std::iter::empty()` is the more idiomatic way
- --> $DIR/default_instead_of_iter_empty.rs:15:41
+ --> $DIR/default_instead_of_iter_empty.rs:14:41
|
LL | let _foo: std::iter::Empty<usize> = std::iter::Empty::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
index 02eb78060..9072d2335 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::default_numeric_fallback)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
index 79a966983..256b94f6c 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::default_numeric_fallback)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr
index b949cd1d5..7ea2e3e68 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr
@@ -1,145 +1,146 @@
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:22:17
+ --> $DIR/default_numeric_fallback_f64.rs:21:17
|
LL | let x = 0.12;
| ^^^^ help: consider adding suffix: `0.12_f64`
|
= note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::default_numeric_fallback)]`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:23:18
+ --> $DIR/default_numeric_fallback_f64.rs:22:18
|
LL | let x = [1., 2., 3.];
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:23:22
+ --> $DIR/default_numeric_fallback_f64.rs:22:22
|
LL | let x = [1., 2., 3.];
| ^^ help: consider adding suffix: `2.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:23:26
+ --> $DIR/default_numeric_fallback_f64.rs:22:26
|
LL | let x = [1., 2., 3.];
| ^^ help: consider adding suffix: `3.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:24:28
+ --> $DIR/default_numeric_fallback_f64.rs:23:28
|
LL | let x = if true { (1., 2.) } else { (3., 4.) };
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:24:32
+ --> $DIR/default_numeric_fallback_f64.rs:23:32
|
LL | let x = if true { (1., 2.) } else { (3., 4.) };
| ^^ help: consider adding suffix: `2.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:24:46
+ --> $DIR/default_numeric_fallback_f64.rs:23:46
|
LL | let x = if true { (1., 2.) } else { (3., 4.) };
| ^^ help: consider adding suffix: `3.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:24:50
+ --> $DIR/default_numeric_fallback_f64.rs:23:50
|
LL | let x = if true { (1., 2.) } else { (3., 4.) };
| ^^ help: consider adding suffix: `4.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:25:23
+ --> $DIR/default_numeric_fallback_f64.rs:24:23
|
LL | let x = match 1. {
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:26:18
+ --> $DIR/default_numeric_fallback_f64.rs:25:18
|
LL | _ => 1.,
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:45:21
+ --> $DIR/default_numeric_fallback_f64.rs:44:21
|
LL | let y = 1.;
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:53:21
+ --> $DIR/default_numeric_fallback_f64.rs:52:21
|
LL | let y = 1.;
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:59:21
+ --> $DIR/default_numeric_fallback_f64.rs:58:21
|
LL | let y = 1.;
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:67:21
+ --> $DIR/default_numeric_fallback_f64.rs:66:21
|
LL | let y = 1.;
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:79:9
+ --> $DIR/default_numeric_fallback_f64.rs:78:9
|
LL | 1.
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:85:27
+ --> $DIR/default_numeric_fallback_f64.rs:84:27
|
LL | let f = || -> _ { 1. };
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:89:29
+ --> $DIR/default_numeric_fallback_f64.rs:88:29
|
LL | let f = || -> f64 { 1. };
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:103:21
+ --> $DIR/default_numeric_fallback_f64.rs:102:21
|
LL | generic_arg(1.);
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:106:32
+ --> $DIR/default_numeric_fallback_f64.rs:105:32
|
LL | let x: _ = generic_arg(1.);
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:124:28
+ --> $DIR/default_numeric_fallback_f64.rs:123:28
|
LL | GenericStruct { x: 1. };
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:127:36
+ --> $DIR/default_numeric_fallback_f64.rs:126:36
|
LL | let _ = GenericStruct { x: 1. };
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:145:24
+ --> $DIR/default_numeric_fallback_f64.rs:144:24
|
LL | GenericEnum::X(1.);
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:165:23
+ --> $DIR/default_numeric_fallback_f64.rs:164:23
|
LL | s.generic_arg(1.);
| ^^ help: consider adding suffix: `1.0_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_f64.rs:175:25
+ --> $DIR/default_numeric_fallback_f64.rs:174:25
|
LL | inline!(let x = 22.;);
| ^^^ help: consider adding suffix: `22.0_f64`
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
index 23272d07e..920cd9f8f 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(lint_reasons)]
#![warn(clippy::default_numeric_fallback)]
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
index fb1491416..bdb7b5f47 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(lint_reasons)]
#![warn(clippy::default_numeric_fallback)]
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr
index 48cd28102..b03b8b84c 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr
@@ -1,157 +1,158 @@
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:22:17
+ --> $DIR/default_numeric_fallback_i32.rs:21:17
|
LL | let x = 22;
| ^^ help: consider adding suffix: `22_i32`
|
= note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::default_numeric_fallback)]`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:23:18
+ --> $DIR/default_numeric_fallback_i32.rs:22:18
|
LL | let x = [1, 2, 3];
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:23:21
+ --> $DIR/default_numeric_fallback_i32.rs:22:21
|
LL | let x = [1, 2, 3];
| ^ help: consider adding suffix: `2_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:23:24
+ --> $DIR/default_numeric_fallback_i32.rs:22:24
|
LL | let x = [1, 2, 3];
| ^ help: consider adding suffix: `3_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:24:28
+ --> $DIR/default_numeric_fallback_i32.rs:23:28
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:24:31
+ --> $DIR/default_numeric_fallback_i32.rs:23:31
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `2_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:24:44
+ --> $DIR/default_numeric_fallback_i32.rs:23:44
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `3_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:24:47
+ --> $DIR/default_numeric_fallback_i32.rs:23:47
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `4_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:25:23
+ --> $DIR/default_numeric_fallback_i32.rs:24:23
|
LL | let x = match 1 {
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:26:13
+ --> $DIR/default_numeric_fallback_i32.rs:25:13
|
LL | 1 => 1,
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:26:18
+ --> $DIR/default_numeric_fallback_i32.rs:25:18
|
LL | 1 => 1,
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:27:18
+ --> $DIR/default_numeric_fallback_i32.rs:26:18
|
LL | _ => 2,
| ^ help: consider adding suffix: `2_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:46:21
+ --> $DIR/default_numeric_fallback_i32.rs:45:21
|
LL | let y = 1;
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:54:21
+ --> $DIR/default_numeric_fallback_i32.rs:53:21
|
LL | let y = 1;
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:60:21
+ --> $DIR/default_numeric_fallback_i32.rs:59:21
|
LL | let y = 1;
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:68:21
+ --> $DIR/default_numeric_fallback_i32.rs:67:21
|
LL | let y = 1;
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:80:9
+ --> $DIR/default_numeric_fallback_i32.rs:79:9
|
LL | 1
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:86:27
+ --> $DIR/default_numeric_fallback_i32.rs:85:27
|
LL | let f = || -> _ { 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:90:29
+ --> $DIR/default_numeric_fallback_i32.rs:89:29
|
LL | let f = || -> i32 { 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:104:21
+ --> $DIR/default_numeric_fallback_i32.rs:103:21
|
LL | generic_arg(1);
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:107:32
+ --> $DIR/default_numeric_fallback_i32.rs:106:32
|
LL | let x: _ = generic_arg(1);
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:125:28
+ --> $DIR/default_numeric_fallback_i32.rs:124:28
|
LL | GenericStruct { x: 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:128:36
+ --> $DIR/default_numeric_fallback_i32.rs:127:36
|
LL | let _ = GenericStruct { x: 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:146:24
+ --> $DIR/default_numeric_fallback_i32.rs:145:24
|
LL | GenericEnum::X(1);
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:166:23
+ --> $DIR/default_numeric_fallback_i32.rs:165:23
|
LL | s.generic_arg(1);
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback_i32.rs:176:25
+ --> $DIR/default_numeric_fallback_i32.rs:175:25
|
LL | inline!(let x = 22;);
| ^^ help: consider adding suffix: `22_i32`
diff --git a/src/tools/clippy/tests/ui/default_trait_access.fixed b/src/tools/clippy/tests/ui/default_trait_access.fixed
index 6e541473c..6f1e72c5a 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.fixed
+++ b/src/tools/clippy/tests/ui/default_trait_access.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![deny(clippy::default_trait_access)]
#![allow(dead_code, unused_imports)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/default_trait_access.rs b/src/tools/clippy/tests/ui/default_trait_access.rs
index 2ffeb32fb..5528ca8b7 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.rs
+++ b/src/tools/clippy/tests/ui/default_trait_access.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![deny(clippy::default_trait_access)]
#![allow(dead_code, unused_imports)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/default_trait_access.stderr b/src/tools/clippy/tests/ui/default_trait_access.stderr
index 103fccf6a..e53c8e2c7 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.stderr
+++ b/src/tools/clippy/tests/ui/default_trait_access.stderr
@@ -1,53 +1,53 @@
error: calling `String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:14:22
+ --> $DIR/default_trait_access.rs:13:22
|
LL | let s1: String = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `String::default()`
|
note: the lint level is defined here
- --> $DIR/default_trait_access.rs:3:9
+ --> $DIR/default_trait_access.rs:2:9
|
LL | #![deny(clippy::default_trait_access)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:18:22
+ --> $DIR/default_trait_access.rs:17:22
|
LL | let s3: String = D2::default();
| ^^^^^^^^^^^^^ help: try: `String::default()`
error: calling `String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:20:22
+ --> $DIR/default_trait_access.rs:19:22
|
LL | let s4: String = std::default::Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()`
error: calling `String::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:24:22
+ --> $DIR/default_trait_access.rs:23:22
|
LL | let s6: String = default::Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()`
error: calling `GenericDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:34:46
+ --> $DIR/default_trait_access.rs:33:46
|
LL | let s11: GenericDerivedDefault<String> = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()`
error: calling `TupleDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:40:36
+ --> $DIR/default_trait_access.rs:39:36
|
LL | let s14: TupleDerivedDefault = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()`
error: calling `ArrayDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:42:36
+ --> $DIR/default_trait_access.rs:41:36
|
LL | let s15: ArrayDerivedDefault = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()`
error: calling `TupleStructDerivedDefault::default()` is more clear than this expression
- --> $DIR/default_trait_access.rs:46:42
+ --> $DIR/default_trait_access.rs:45:42
|
LL | let s17: TupleStructDerivedDefault = Default::default();
| ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()`
diff --git a/src/tools/clippy/tests/ui/default_union_representation.rs b/src/tools/clippy/tests/ui/default_union_representation.rs
index 93b2d33da..41308b077 100644
--- a/src/tools/clippy/tests/ui/default_union_representation.rs
+++ b/src/tools/clippy/tests/ui/default_union_representation.rs
@@ -2,6 +2,7 @@
#![warn(clippy::default_union_representation)]
union NoAttribute {
+ //~^ ERROR: this union has the default representation
a: i32,
b: u32,
}
@@ -14,6 +15,7 @@ union ReprC {
#[repr(packed)]
union ReprPacked {
+ //~^ ERROR: this union has the default representation
a: i32,
b: u32,
}
@@ -32,6 +34,7 @@ union ReprCAlign {
#[repr(align(32))]
union ReprAlign {
+ //~^ ERROR: this union has the default representation
a: i32,
b: u32,
}
@@ -52,6 +55,7 @@ union ZSTsAndField2 {
f3: (),
}
union ZSTAndTwoFields {
+ //~^ ERROR: this union has the default representation
f0: u32,
f1: u64,
f2: (),
diff --git a/src/tools/clippy/tests/ui/default_union_representation.stderr b/src/tools/clippy/tests/ui/default_union_representation.stderr
index 8b7ed94cb..82f69ffee 100644
--- a/src/tools/clippy/tests/ui/default_union_representation.stderr
+++ b/src/tools/clippy/tests/ui/default_union_representation.stderr
@@ -2,6 +2,7 @@ error: this union has the default representation
--> $DIR/default_union_representation.rs:4:1
|
LL | / union NoAttribute {
+LL | |
LL | | a: i32,
LL | | b: u32,
LL | | }
@@ -9,11 +10,13 @@ LL | | }
|
= help: consider annotating `NoAttribute` with `#[repr(C)]` to explicitly specify memory layout
= note: `-D clippy::default-union-representation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::default_union_representation)]`
error: this union has the default representation
- --> $DIR/default_union_representation.rs:16:1
+ --> $DIR/default_union_representation.rs:17:1
|
LL | / union ReprPacked {
+LL | |
LL | | a: i32,
LL | | b: u32,
LL | | }
@@ -22,9 +25,10 @@ LL | | }
= help: consider annotating `ReprPacked` with `#[repr(C)]` to explicitly specify memory layout
error: this union has the default representation
- --> $DIR/default_union_representation.rs:34:1
+ --> $DIR/default_union_representation.rs:36:1
|
LL | / union ReprAlign {
+LL | |
LL | | a: i32,
LL | | b: u32,
LL | | }
@@ -33,9 +37,10 @@ LL | | }
= help: consider annotating `ReprAlign` with `#[repr(C)]` to explicitly specify memory layout
error: this union has the default representation
- --> $DIR/default_union_representation.rs:54:1
+ --> $DIR/default_union_representation.rs:57:1
|
LL | / union ZSTAndTwoFields {
+LL | |
LL | | f0: u32,
LL | | f1: u64,
LL | | f2: (),
diff --git a/src/tools/clippy/tests/ui/deprecated.stderr b/src/tools/clippy/tests/ui/deprecated.stderr
index 0e142ac8f..388fcc238 100644
--- a/src/tools/clippy/tests/ui/deprecated.stderr
+++ b/src/tools/clippy/tests/ui/deprecated.stderr
@@ -5,6 +5,7 @@ LL | #![warn(clippy::should_assert_eq)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D renamed-and-removed-lints` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
error: lint `clippy::extend_from_slice` has been removed: `.extend_from_slice(_)` is a faster way to extend a Vec by a slice
--> $DIR/deprecated.rs:6:9
diff --git a/src/tools/clippy/tests/ui/deprecated_old.rs b/src/tools/clippy/tests/ui/deprecated_old.rs
index e89dca4fc..356ad5f06 100644
--- a/src/tools/clippy/tests/ui/deprecated_old.rs
+++ b/src/tools/clippy/tests/ui/deprecated_old.rs
@@ -1,5 +1,9 @@
#[warn(unstable_as_slice)]
+//~^ ERROR: lint `unstable_as_slice` has been removed: `Vec::as_slice` has been stabilized
+//~| NOTE: `-D renamed-and-removed-lints` implied by `-D warnings`
#[warn(unstable_as_mut_slice)]
+//~^ ERROR: lint `unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` has been st
#[warn(misaligned_transmute)]
+//~^ ERROR: lint `misaligned_transmute` has been removed: this lint has been split into ca
fn main() {}
diff --git a/src/tools/clippy/tests/ui/deprecated_old.stderr b/src/tools/clippy/tests/ui/deprecated_old.stderr
index 8043ab005..d27ad852f 100644
--- a/src/tools/clippy/tests/ui/deprecated_old.stderr
+++ b/src/tools/clippy/tests/ui/deprecated_old.stderr
@@ -5,15 +5,16 @@ LL | #[warn(unstable_as_slice)]
| ^^^^^^^^^^^^^^^^^
|
= note: `-D renamed-and-removed-lints` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
error: lint `unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` has been stabilized in 1.7
- --> $DIR/deprecated_old.rs:2:8
+ --> $DIR/deprecated_old.rs:4:8
|
LL | #[warn(unstable_as_mut_slice)]
| ^^^^^^^^^^^^^^^^^^^^^
error: lint `misaligned_transmute` has been removed: this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr
- --> $DIR/deprecated_old.rs:3:8
+ --> $DIR/deprecated_old.rs:6:8
|
LL | #[warn(misaligned_transmute)]
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/deref_addrof.fixed b/src/tools/clippy/tests/ui/deref_addrof.fixed
index 0ecca1b8f..aa1cf19b7 100644
--- a/src/tools/clippy/tests/ui/deref_addrof.fixed
+++ b/src/tools/clippy/tests/ui/deref_addrof.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::return_self_not_must_use, clippy::useless_vec)]
#![warn(clippy::deref_addrof)]
diff --git a/src/tools/clippy/tests/ui/deref_addrof.rs b/src/tools/clippy/tests/ui/deref_addrof.rs
index 9f91310e6..38796aef3 100644
--- a/src/tools/clippy/tests/ui/deref_addrof.rs
+++ b/src/tools/clippy/tests/ui/deref_addrof.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::return_self_not_must_use, clippy::useless_vec)]
#![warn(clippy::deref_addrof)]
diff --git a/src/tools/clippy/tests/ui/deref_addrof.stderr b/src/tools/clippy/tests/ui/deref_addrof.stderr
index 9dd1e246b..b01fa4df6 100644
--- a/src/tools/clippy/tests/ui/deref_addrof.stderr
+++ b/src/tools/clippy/tests/ui/deref_addrof.stderr
@@ -1,55 +1,56 @@
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:24:13
+ --> $DIR/deref_addrof.rs:23:13
|
LL | let b = *&a;
| ^^^ help: try: `a`
|
= note: `-D clippy::deref-addrof` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:26:13
+ --> $DIR/deref_addrof.rs:25:13
|
LL | let b = *&get_number();
| ^^^^^^^^^^^^^^ help: try: `get_number()`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:31:13
+ --> $DIR/deref_addrof.rs:30:13
|
LL | let b = *&bytes[1..2][0];
| ^^^^^^^^^^^^^^^^ help: try: `bytes[1..2][0]`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:35:13
+ --> $DIR/deref_addrof.rs:34:13
|
LL | let b = *&(a);
| ^^^^^ help: try: `(a)`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:37:13
+ --> $DIR/deref_addrof.rs:36:13
|
LL | let b = *(&a);
| ^^^^^ help: try: `a`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:40:13
+ --> $DIR/deref_addrof.rs:39:13
|
LL | let b = *((&a));
| ^^^^^^^ help: try: `a`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:42:13
+ --> $DIR/deref_addrof.rs:41:13
|
LL | let b = *&&a;
| ^^^^ help: try: `&a`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:44:14
+ --> $DIR/deref_addrof.rs:43:14
|
LL | let b = **&aref;
| ^^^^^^ help: try: `aref`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:54:17
+ --> $DIR/deref_addrof.rs:53:17
|
LL | inline!(*& $(@expr self))
| ^^^^^^^^^^^^^^^^ help: try: `$(@expr self)`
@@ -57,7 +58,7 @@ LL | inline!(*& $(@expr self))
= note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
error: immediately dereferencing a reference
- --> $DIR/deref_addrof.rs:58:17
+ --> $DIR/deref_addrof.rs:57:17
|
LL | inline!(*&mut $(@expr self))
| ^^^^^^^^^^^^^^^^^^^ help: try: `$(@expr self)`
diff --git a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
index 453194329..32582a3a8 100644
--- a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
+++ b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
@@ -1,5 +1,5 @@
// This test can't work with run-rustfix because it needs two passes of test+fix
-
+//@no-rustfix
#[warn(clippy::deref_addrof)]
#[allow(unused_variables, unused_mut)]
fn main() {
@@ -8,10 +8,13 @@ fn main() {
//This produces a suggestion of 'let b = *&a;' which
//will trigger the 'clippy::deref_addrof' lint again
let b = **&&a;
+ //~^ ERROR: immediately dereferencing a reference
+ //~| NOTE: `-D clippy::deref-addrof` implied by `-D warnings`
{
let mut x = 10;
let y = *&mut x;
+ //~^ ERROR: immediately dereferencing a reference
}
{
@@ -19,5 +22,6 @@ fn main() {
//will trigger the 'clippy::deref_addrof' lint again
let mut x = 10;
let y = **&mut &mut x;
+ //~^ ERROR: immediately dereferencing a reference
}
}
diff --git a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.stderr b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.stderr
index 6fa5069b6..78ec73400 100644
--- a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.stderr
+++ b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.stderr
@@ -5,15 +5,16 @@ LL | let b = **&&a;
| ^^^^ help: try: `&a`
|
= note: `-D clippy::deref-addrof` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof_double_trigger.rs:14:17
+ --> $DIR/deref_addrof_double_trigger.rs:16:17
|
LL | let y = *&mut x;
| ^^^^^^^ help: try: `x`
error: immediately dereferencing a reference
- --> $DIR/deref_addrof_double_trigger.rs:21:18
+ --> $DIR/deref_addrof_double_trigger.rs:24:18
|
LL | let y = **&mut &mut x;
| ^^^^^^^^^^^^ help: try: `&mut x`
diff --git a/src/tools/clippy/tests/ui/deref_addrof_macro.rs b/src/tools/clippy/tests/ui/deref_addrof_macro.rs
index ce4b94a73..c7e60f365 100644
--- a/src/tools/clippy/tests/ui/deref_addrof_macro.rs
+++ b/src/tools/clippy/tests/ui/deref_addrof_macro.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::deref_addrof)]
diff --git a/src/tools/clippy/tests/ui/deref_by_slicing.fixed b/src/tools/clippy/tests/ui/deref_by_slicing.fixed
index f91a425c6..a3c2e8456 100644
--- a/src/tools/clippy/tests/ui/deref_by_slicing.fixed
+++ b/src/tools/clippy/tests/ui/deref_by_slicing.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::deref_by_slicing)]
#![allow(clippy::borrow_deref_ref)]
diff --git a/src/tools/clippy/tests/ui/deref_by_slicing.rs b/src/tools/clippy/tests/ui/deref_by_slicing.rs
index 1bfdd0a98..5b4a73712 100644
--- a/src/tools/clippy/tests/ui/deref_by_slicing.rs
+++ b/src/tools/clippy/tests/ui/deref_by_slicing.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::deref_by_slicing)]
#![allow(clippy::borrow_deref_ref)]
diff --git a/src/tools/clippy/tests/ui/deref_by_slicing.stderr b/src/tools/clippy/tests/ui/deref_by_slicing.stderr
index 8f042ef47..7b8144a9a 100644
--- a/src/tools/clippy/tests/ui/deref_by_slicing.stderr
+++ b/src/tools/clippy/tests/ui/deref_by_slicing.stderr
@@ -1,55 +1,56 @@
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:10:13
+ --> $DIR/deref_by_slicing.rs:8:13
|
LL | let _ = &vec[..];
| ^^^^^^^^ help: dereference the original value instead: `&*vec`
|
= note: `-D clippy::deref-by-slicing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::deref_by_slicing)]`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:11:13
+ --> $DIR/deref_by_slicing.rs:9:13
|
LL | let _ = &mut vec[..];
| ^^^^^^^^^^^^ help: dereference the original value instead: `&mut *vec`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:14:13
+ --> $DIR/deref_by_slicing.rs:12:13
|
LL | let _ = &ref_vec[..];
| ^^^^^^^^^^^^ help: dereference the original value instead: `&**ref_vec`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:15:21
+ --> $DIR/deref_by_slicing.rs:13:21
|
LL | let mut_slice = &mut ref_vec[..];
| ^^^^^^^^^^^^^^^^ help: dereference the original value instead: `&mut **ref_vec`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:16:13
+ --> $DIR/deref_by_slicing.rs:14:13
|
LL | let _ = &mut mut_slice[..]; // Err, re-borrows slice
| ^^^^^^^^^^^^^^^^^^ help: reborrow the original value instead: `&mut *mut_slice`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:19:13
+ --> $DIR/deref_by_slicing.rs:17:13
|
LL | let _ = &s[..];
| ^^^^^^ help: dereference the original value instead: `&*s`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:22:18
+ --> $DIR/deref_by_slicing.rs:20:18
|
LL | let _ = &mut &S[..]; // Err, re-borrows slice
| ^^^^^^ help: reborrow the original value instead: `&*S`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:26:13
+ --> $DIR/deref_by_slicing.rs:24:13
|
LL | let _ = &slice_ref[..]; // Err, derefs slice
| ^^^^^^^^^^^^^^ help: dereference the original value instead: `*slice_ref`
error: slicing when dereferencing would work
- --> $DIR/deref_by_slicing.rs:29:13
+ --> $DIR/deref_by_slicing.rs:27:13
|
LL | let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice
| ^^^^^^^^^^^^ help: reborrow the original value instead: `(&*bytes)`
diff --git a/src/tools/clippy/tests/ui/derivable_impls.fixed b/src/tools/clippy/tests/ui/derivable_impls.fixed
index a10f3d010..68c5a5c5c 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.fixed
+++ b/src/tools/clippy/tests/ui/derivable_impls.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
use std::collections::HashMap;
@@ -289,4 +287,17 @@ mod issue10158 {
}
}
+mod issue11368 {
+ pub struct A {
+ a: u32,
+ }
+
+ impl Default for A {
+ #[track_caller]
+ fn default() -> Self {
+ Self { a: 0 }
+ }
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/derivable_impls.rs b/src/tools/clippy/tests/ui/derivable_impls.rs
index 18cef1c5b..21d73ba8b 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.rs
+++ b/src/tools/clippy/tests/ui/derivable_impls.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
use std::collections::HashMap;
@@ -325,4 +323,17 @@ mod issue10158 {
}
}
+mod issue11368 {
+ pub struct A {
+ a: u32,
+ }
+
+ impl Default for A {
+ #[track_caller]
+ fn default() -> Self {
+ Self { a: 0 }
+ }
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/derivable_impls.stderr b/src/tools/clippy/tests/ui/derivable_impls.stderr
index 8089f5ea0..98e2f3612 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.stderr
+++ b/src/tools/clippy/tests/ui/derivable_impls.stderr
@@ -1,5 +1,5 @@
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:22:1
+ --> $DIR/derivable_impls.rs:20:1
|
LL | / impl std::default::Default for FooDefault<'_> {
LL | | fn default() -> Self {
@@ -11,6 +11,7 @@ LL | | }
| |_^
|
= note: `-D clippy::derivable-impls` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::derivable_impls)]`
= help: remove the manual implementation...
help: ...and instead derive it
|
@@ -19,7 +20,7 @@ LL | struct FooDefault<'a> {
|
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:43:1
+ --> $DIR/derivable_impls.rs:41:1
|
LL | / impl std::default::Default for TupleDefault {
LL | | fn default() -> Self {
@@ -36,7 +37,7 @@ LL | struct TupleDefault(bool, i32, u64);
|
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:95:1
+ --> $DIR/derivable_impls.rs:93:1
|
LL | / impl Default for StrDefault<'_> {
LL | | fn default() -> Self {
@@ -53,7 +54,7 @@ LL | struct StrDefault<'a>(&'a str);
|
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:121:1
+ --> $DIR/derivable_impls.rs:119:1
|
LL | / impl Default for Y {
LL | | fn default() -> Self {
@@ -70,7 +71,7 @@ LL | struct Y(u32);
|
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:160:1
+ --> $DIR/derivable_impls.rs:158:1
|
LL | / impl Default for WithoutSelfCurly {
LL | | fn default() -> Self {
@@ -87,7 +88,7 @@ LL | struct WithoutSelfCurly {
|
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:168:1
+ --> $DIR/derivable_impls.rs:166:1
|
LL | / impl Default for WithoutSelfParan {
LL | | fn default() -> Self {
@@ -104,7 +105,7 @@ LL | struct WithoutSelfParan(bool);
|
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:218:1
+ --> $DIR/derivable_impls.rs:216:1
|
LL | / impl Default for RepeatDefault1 {
LL | | fn default() -> Self {
@@ -121,7 +122,7 @@ LL | pub struct RepeatDefault1 {
|
error: this `impl` can be derived
- --> $DIR/derivable_impls.rs:252:1
+ --> $DIR/derivable_impls.rs:250:1
|
LL | / impl Default for SimpleEnum {
LL | | fn default() -> Self {
diff --git a/src/tools/clippy/tests/ui/derive.rs b/src/tools/clippy/tests/ui/derive.rs
index c76711312..20ac8a6e6 100644
--- a/src/tools/clippy/tests/ui/derive.rs
+++ b/src/tools/clippy/tests/ui/derive.rs
@@ -1,8 +1,4 @@
-#![allow(
- clippy::incorrect_clone_impl_on_copy_type,
- clippy::incorrect_partial_ord_impl_on_ord_type,
- dead_code
-)]
+#![allow(clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, dead_code)]
#![warn(clippy::expl_impl_clone_on_copy)]
@@ -10,6 +6,7 @@
struct Qux;
impl Clone for Qux {
+ //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type
fn clone(&self) -> Self {
Qux
}
@@ -34,6 +31,7 @@ struct Lt<'a> {
}
impl<'a> Clone for Lt<'a> {
+ //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type
fn clone(&self) -> Self {
unimplemented!()
}
@@ -45,6 +43,7 @@ struct BigArray {
}
impl Clone for BigArray {
+ //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type
fn clone(&self) -> Self {
unimplemented!()
}
@@ -56,6 +55,7 @@ struct FnPtr {
}
impl Clone for FnPtr {
+ //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type
fn clone(&self) -> Self {
unimplemented!()
}
@@ -76,6 +76,7 @@ impl<T> Clone for Generic<T> {
#[derive(Copy)]
struct Generic2<T>(T);
impl<T: Clone> Clone for Generic2<T> {
+ //~^ ERROR: you are implementing `Clone` explicitly on a `Copy` type
fn clone(&self) -> Self {
Self(self.0.clone())
}
diff --git a/src/tools/clippy/tests/ui/derive.stderr b/src/tools/clippy/tests/ui/derive.stderr
index 5d7ed0918..88942d954 100644
--- a/src/tools/clippy/tests/ui/derive.stderr
+++ b/src/tools/clippy/tests/ui/derive.stderr
@@ -1,7 +1,8 @@
error: you are implementing `Clone` explicitly on a `Copy` type
- --> $DIR/derive.rs:12:1
+ --> $DIR/derive.rs:8:1
|
LL | / impl Clone for Qux {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | Qux
LL | | }
@@ -9,20 +10,23 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
- --> $DIR/derive.rs:12:1
+ --> $DIR/derive.rs:8:1
|
LL | / impl Clone for Qux {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | Qux
LL | | }
LL | | }
| |_^
= note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
error: you are implementing `Clone` explicitly on a `Copy` type
- --> $DIR/derive.rs:36:1
+ --> $DIR/derive.rs:33:1
|
LL | / impl<'a> Clone for Lt<'a> {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | unimplemented!()
LL | | }
@@ -30,9 +34,10 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
- --> $DIR/derive.rs:36:1
+ --> $DIR/derive.rs:33:1
|
LL | / impl<'a> Clone for Lt<'a> {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | unimplemented!()
LL | | }
@@ -40,9 +45,10 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
- --> $DIR/derive.rs:47:1
+ --> $DIR/derive.rs:45:1
|
LL | / impl Clone for BigArray {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | unimplemented!()
LL | | }
@@ -50,9 +56,10 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
- --> $DIR/derive.rs:47:1
+ --> $DIR/derive.rs:45:1
|
LL | / impl Clone for BigArray {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | unimplemented!()
LL | | }
@@ -60,9 +67,10 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
- --> $DIR/derive.rs:58:1
+ --> $DIR/derive.rs:57:1
|
LL | / impl Clone for FnPtr {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | unimplemented!()
LL | | }
@@ -70,9 +78,10 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
- --> $DIR/derive.rs:58:1
+ --> $DIR/derive.rs:57:1
|
LL | / impl Clone for FnPtr {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | unimplemented!()
LL | | }
@@ -83,6 +92,7 @@ error: you are implementing `Clone` explicitly on a `Copy` type
--> $DIR/derive.rs:78:1
|
LL | / impl<T: Clone> Clone for Generic2<T> {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | Self(self.0.clone())
LL | | }
@@ -93,6 +103,7 @@ note: consider deriving `Clone` or removing `Copy`
--> $DIR/derive.rs:78:1
|
LL | / impl<T: Clone> Clone for Generic2<T> {
+LL | |
LL | | fn clone(&self) -> Self {
LL | | Self(self.0.clone())
LL | | }
diff --git a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.rs b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.rs
index 1fb3d51c4..1c7e6d1c2 100644
--- a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.rs
+++ b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.rs
@@ -1,6 +1,6 @@
#![warn(clippy::derive_ord_xor_partial_ord)]
#![allow(clippy::unnecessary_wraps)]
-#![allow(clippy::incorrect_partial_ord_impl_on_ord_type)]
+#![allow(clippy::non_canonical_partial_ord_impl)]
use std::cmp::Ordering;
@@ -20,6 +20,7 @@ impl PartialOrd<u64> for DeriveBoth {
}
#[derive(Ord, PartialEq, Eq)]
+//~^ ERROR: you are deriving `Ord` but have implemented `PartialOrd` explicitly
struct DeriveOrd;
impl PartialOrd for DeriveOrd {
@@ -29,6 +30,7 @@ impl PartialOrd for DeriveOrd {
}
#[derive(Ord, PartialEq, Eq)]
+//~^ ERROR: you are deriving `Ord` but have implemented `PartialOrd` explicitly
struct DeriveOrdWithExplicitTypeVariable;
impl PartialOrd<DeriveOrdWithExplicitTypeVariable> for DeriveOrdWithExplicitTypeVariable {
@@ -41,6 +43,7 @@ impl PartialOrd<DeriveOrdWithExplicitTypeVariable> for DeriveOrdWithExplicitType
struct DerivePartialOrd;
impl std::cmp::Ord for DerivePartialOrd {
+ //~^ ERROR: you are implementing `Ord` explicitly but have derived `PartialOrd`
fn cmp(&self, other: &Self) -> Ordering {
Ordering::Less
}
@@ -61,6 +64,7 @@ mod use_ord {
struct DerivePartialOrdInUseOrd;
impl Ord for DerivePartialOrdInUseOrd {
+ //~^ ERROR: you are implementing `Ord` explicitly but have derived `PartialOrd`
fn cmp(&self, other: &Self) -> Ordering {
Ordering::Less
}
diff --git a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr
index bd1488348..7555c12b1 100644
--- a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr
+++ b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr
@@ -5,30 +5,32 @@ LL | #[derive(Ord, PartialEq, Eq)]
| ^^^
|
note: `PartialOrd` implemented here
- --> $DIR/derive_ord_xor_partial_ord.rs:25:1
+ --> $DIR/derive_ord_xor_partial_ord.rs:26:1
|
LL | impl PartialOrd for DeriveOrd {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::derive-ord-xor-partial-ord` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::derive_ord_xor_partial_ord)]`
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `Ord` but have implemented `PartialOrd` explicitly
- --> $DIR/derive_ord_xor_partial_ord.rs:31:10
+ --> $DIR/derive_ord_xor_partial_ord.rs:32:10
|
LL | #[derive(Ord, PartialEq, Eq)]
| ^^^
|
note: `PartialOrd` implemented here
- --> $DIR/derive_ord_xor_partial_ord.rs:34:1
+ --> $DIR/derive_ord_xor_partial_ord.rs:36:1
|
LL | impl PartialOrd<DeriveOrdWithExplicitTypeVariable> for DeriveOrdWithExplicitTypeVariable {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are implementing `Ord` explicitly but have derived `PartialOrd`
- --> $DIR/derive_ord_xor_partial_ord.rs:43:1
+ --> $DIR/derive_ord_xor_partial_ord.rs:45:1
|
LL | / impl std::cmp::Ord for DerivePartialOrd {
+LL | |
LL | | fn cmp(&self, other: &Self) -> Ordering {
LL | | Ordering::Less
LL | | }
@@ -36,16 +38,17 @@ LL | | }
| |_^
|
note: `PartialOrd` implemented here
- --> $DIR/derive_ord_xor_partial_ord.rs:40:10
+ --> $DIR/derive_ord_xor_partial_ord.rs:42:10
|
LL | #[derive(PartialOrd, PartialEq, Eq)]
| ^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are implementing `Ord` explicitly but have derived `PartialOrd`
- --> $DIR/derive_ord_xor_partial_ord.rs:63:5
+ --> $DIR/derive_ord_xor_partial_ord.rs:66:5
|
LL | / impl Ord for DerivePartialOrdInUseOrd {
+LL | |
LL | | fn cmp(&self, other: &Self) -> Ordering {
LL | | Ordering::Less
LL | | }
@@ -53,7 +56,7 @@ LL | | }
| |_____^
|
note: `PartialOrd` implemented here
- --> $DIR/derive_ord_xor_partial_ord.rs:60:14
+ --> $DIR/derive_ord_xor_partial_ord.rs:63:14
|
LL | #[derive(PartialOrd, PartialEq, Eq)]
| ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
index a1f29430c..a7f5d3ec7 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::derive_partial_eq_without_eq)]
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
index ff4d88855..476d2aee2 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::derive_partial_eq_without_eq)]
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
index 794c5dab8..abfd70e8c 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
@@ -1,67 +1,68 @@
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:13:17
+ --> $DIR/derive_partial_eq_without_eq.rs:11:17
|
LL | #[derive(Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= note: `-D clippy::derive-partial-eq-without-eq` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::derive_partial_eq_without_eq)]`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:55:10
+ --> $DIR/derive_partial_eq_without_eq.rs:53:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:61:10
+ --> $DIR/derive_partial_eq_without_eq.rs:59:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:67:10
+ --> $DIR/derive_partial_eq_without_eq.rs:65:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:70:10
+ --> $DIR/derive_partial_eq_without_eq.rs:68:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:76:10
+ --> $DIR/derive_partial_eq_without_eq.rs:74:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:82:10
+ --> $DIR/derive_partial_eq_without_eq.rs:80:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:95:17
+ --> $DIR/derive_partial_eq_without_eq.rs:93:17
|
LL | #[derive(Debug, PartialEq, Clone)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:98:10
+ --> $DIR/derive_partial_eq_without_eq.rs:96:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:105:14
+ --> $DIR/derive_partial_eq_without_eq.rs:103:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
error: you are deriving `PartialEq` and can implement `Eq`
- --> $DIR/derive_partial_eq_without_eq.rs:108:14
+ --> $DIR/derive_partial_eq_without_eq.rs:106:14
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
diff --git a/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.rs b/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.rs
index 8ad09a8de..8423699d9 100644
--- a/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.rs
+++ b/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.rs
@@ -10,6 +10,7 @@ impl PartialEq<u64> for Foo {
}
#[derive(Hash)]
+//~^ ERROR: you are deriving `Hash` but have implemented `PartialEq` explicitly
struct Bar;
impl PartialEq for Bar {
@@ -19,6 +20,7 @@ impl PartialEq for Bar {
}
#[derive(Hash)]
+//~^ ERROR: you are deriving `Hash` but have implemented `PartialEq` explicitly
struct Baz;
impl PartialEq<Baz> for Baz {
diff --git a/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.stderr b/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.stderr
index 230940f25..8ef08f9fa 100644
--- a/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.stderr
+++ b/src/tools/clippy/tests/ui/derived_hash_with_manual_eq.stderr
@@ -5,7 +5,7 @@ LL | #[derive(Hash)]
| ^^^^
|
note: `PartialEq` implemented here
- --> $DIR/derived_hash_with_manual_eq.rs:15:1
+ --> $DIR/derived_hash_with_manual_eq.rs:16:1
|
LL | impl PartialEq for Bar {
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -13,13 +13,13 @@ LL | impl PartialEq for Bar {
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `Hash` but have implemented `PartialEq` explicitly
- --> $DIR/derived_hash_with_manual_eq.rs:21:10
+ --> $DIR/derived_hash_with_manual_eq.rs:22:10
|
LL | #[derive(Hash)]
| ^^^^
|
note: `PartialEq` implemented here
- --> $DIR/derived_hash_with_manual_eq.rs:24:1
+ --> $DIR/derived_hash_with_manual_eq.rs:26:1
|
LL | impl PartialEq<Baz> for Baz {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/disallowed_names.rs b/src/tools/clippy/tests/ui/disallowed_names.rs
index 5889f0443..9a701a2cb 100644
--- a/src/tools/clippy/tests/ui/disallowed_names.rs
+++ b/src/tools/clippy/tests/ui/disallowed_names.rs
@@ -10,11 +10,16 @@
#![warn(clippy::disallowed_names)]
fn test(foo: ()) {}
+//~^ ERROR: use of a disallowed/placeholder name `foo`
+//~| NOTE: `-D clippy::disallowed-names` implied by `-D warnings`
fn main() {
let foo = 42;
+ //~^ ERROR: use of a disallowed/placeholder name `foo`
let baz = 42;
+ //~^ ERROR: use of a disallowed/placeholder name `baz`
let quux = 42;
+ //~^ ERROR: use of a disallowed/placeholder name `quux`
// Unlike these others, `bar` is actually considered an acceptable name.
// Among many other legitimate uses, bar commonly refers to a period of time in music.
// See https://github.com/rust-lang/rust-clippy/issues/5225.
@@ -26,23 +31,33 @@ fn main() {
match (42, Some(1337), Some(0)) {
(foo, Some(baz), quux @ Some(_)) => (),
+ //~^ ERROR: use of a disallowed/placeholder name `foo`
+ //~| ERROR: use of a disallowed/placeholder name `baz`
+ //~| ERROR: use of a disallowed/placeholder name `quux`
_ => (),
}
}
fn issue_1647(mut foo: u8) {
+ //~^ ERROR: use of a disallowed/placeholder name `foo`
let mut baz = 0;
+ //~^ ERROR: use of a disallowed/placeholder name `baz`
if let Some(mut quux) = Some(42) {}
+ //~^ ERROR: use of a disallowed/placeholder name `quux`
}
fn issue_1647_ref() {
let ref baz = 0;
+ //~^ ERROR: use of a disallowed/placeholder name `baz`
if let Some(ref quux) = Some(42) {}
+ //~^ ERROR: use of a disallowed/placeholder name `quux`
}
fn issue_1647_ref_mut() {
let ref mut baz = 0;
+ //~^ ERROR: use of a disallowed/placeholder name `baz`
if let Some(ref mut quux) = Some(42) {}
+ //~^ ERROR: use of a disallowed/placeholder name `quux`
}
mod tests {
diff --git a/src/tools/clippy/tests/ui/disallowed_names.stderr b/src/tools/clippy/tests/ui/disallowed_names.stderr
index 9ab68b641..3387906a0 100644
--- a/src/tools/clippy/tests/ui/disallowed_names.stderr
+++ b/src/tools/clippy/tests/ui/disallowed_names.stderr
@@ -5,81 +5,82 @@ LL | fn test(foo: ()) {}
| ^^^
|
= note: `-D clippy::disallowed-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`
error: use of a disallowed/placeholder name `foo`
- --> $DIR/disallowed_names.rs:15:9
+ --> $DIR/disallowed_names.rs:17:9
|
LL | let foo = 42;
| ^^^
error: use of a disallowed/placeholder name `baz`
- --> $DIR/disallowed_names.rs:16:9
+ --> $DIR/disallowed_names.rs:19:9
|
LL | let baz = 42;
| ^^^
error: use of a disallowed/placeholder name `quux`
- --> $DIR/disallowed_names.rs:17:9
+ --> $DIR/disallowed_names.rs:21:9
|
LL | let quux = 42;
| ^^^^
error: use of a disallowed/placeholder name `foo`
- --> $DIR/disallowed_names.rs:28:10
+ --> $DIR/disallowed_names.rs:33:10
|
LL | (foo, Some(baz), quux @ Some(_)) => (),
| ^^^
error: use of a disallowed/placeholder name `baz`
- --> $DIR/disallowed_names.rs:28:20
+ --> $DIR/disallowed_names.rs:33:20
|
LL | (foo, Some(baz), quux @ Some(_)) => (),
| ^^^
error: use of a disallowed/placeholder name `quux`
- --> $DIR/disallowed_names.rs:28:26
+ --> $DIR/disallowed_names.rs:33:26
|
LL | (foo, Some(baz), quux @ Some(_)) => (),
| ^^^^
error: use of a disallowed/placeholder name `foo`
- --> $DIR/disallowed_names.rs:33:19
+ --> $DIR/disallowed_names.rs:41:19
|
LL | fn issue_1647(mut foo: u8) {
| ^^^
error: use of a disallowed/placeholder name `baz`
- --> $DIR/disallowed_names.rs:34:13
+ --> $DIR/disallowed_names.rs:43:13
|
LL | let mut baz = 0;
| ^^^
error: use of a disallowed/placeholder name `quux`
- --> $DIR/disallowed_names.rs:35:21
+ --> $DIR/disallowed_names.rs:45:21
|
LL | if let Some(mut quux) = Some(42) {}
| ^^^^
error: use of a disallowed/placeholder name `baz`
- --> $DIR/disallowed_names.rs:39:13
+ --> $DIR/disallowed_names.rs:50:13
|
LL | let ref baz = 0;
| ^^^
error: use of a disallowed/placeholder name `quux`
- --> $DIR/disallowed_names.rs:40:21
+ --> $DIR/disallowed_names.rs:52:21
|
LL | if let Some(ref quux) = Some(42) {}
| ^^^^
error: use of a disallowed/placeholder name `baz`
- --> $DIR/disallowed_names.rs:44:17
+ --> $DIR/disallowed_names.rs:57:17
|
LL | let ref mut baz = 0;
| ^^^
error: use of a disallowed/placeholder name `quux`
- --> $DIR/disallowed_names.rs:45:25
+ --> $DIR/disallowed_names.rs:59:25
|
LL | if let Some(ref mut quux) = Some(42) {}
| ^^^^
diff --git a/src/tools/clippy/tests/ui/disallowed_script_idents.rs b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
index cfdda3597..6b68fae31 100644
--- a/src/tools/clippy/tests/ui/disallowed_script_idents.rs
+++ b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
@@ -2,9 +2,15 @@
#![allow(dead_code)]
fn main() {
- let counter = 10; // OK, latin is allowed.
- let zähler = 10; // OK, it's still latin.
+ // OK, latin is allowed.
+ let counter = 10;
+ // OK, it's still latin.
+ let zähler = 10;
- let счётчик = 10; // Cyrillic is not allowed by default.
- let カウンタ = 10; // Same for japanese.
+ // Cyrillic is not allowed by default.
+ let счётчик = 10;
+ //~^ ERROR: identifier `счётчик` has a Unicode script that is not allowed by configura
+ // Same for japanese.
+ let カウンタ = 10;
+ //~^ ERROR: identifier `カウンタ` has a Unicode script that is not allowed by configuratio
}
diff --git a/src/tools/clippy/tests/ui/disallowed_script_idents.stderr b/src/tools/clippy/tests/ui/disallowed_script_idents.stderr
index cc84dc1d4..bf5cbe306 100644
--- a/src/tools/clippy/tests/ui/disallowed_script_idents.stderr
+++ b/src/tools/clippy/tests/ui/disallowed_script_idents.stderr
@@ -1,7 +1,7 @@
error: identifier `счётчик` has a Unicode script that is not allowed by configuration: Cyrillic
- --> $DIR/disallowed_script_idents.rs:8:9
+ --> $DIR/disallowed_script_idents.rs:11:9
|
-LL | let счётчик = 10; // Cyrillic is not allowed by default.
+LL | let счётчик = 10;
| ^^^^^^^
|
note: the lint level is defined here
@@ -11,9 +11,9 @@ LL | #![deny(clippy::disallowed_script_idents)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana
- --> $DIR/disallowed_script_idents.rs:9:9
+ --> $DIR/disallowed_script_idents.rs:14:9
|
-LL | let カウンタ = 10; // Same for japanese.
+LL | let カウンタ = 10;
| ^^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.rs b/src/tools/clippy/tests/ui/diverging_sub_expression.rs
index 9b1619baf..e0acf0509 100644
--- a/src/tools/clippy/tests/ui/diverging_sub_expression.rs
+++ b/src/tools/clippy/tests/ui/diverging_sub_expression.rs
@@ -18,7 +18,10 @@ impl A {
fn main() {
let b = true;
b || diverge();
+ //~^ ERROR: sub-expression diverges
+ //~| NOTE: `-D clippy::diverging-sub-expression` implied by `-D warnings`
b || A.foo();
+ //~^ ERROR: sub-expression diverges
}
#[allow(dead_code, unused_variables)]
@@ -29,20 +32,28 @@ fn foobar() {
4 => return,
5 => continue,
6 => true || return,
+ //~^ ERROR: sub-expression diverges
7 => true || continue,
+ //~^ ERROR: sub-expression diverges
8 => break,
9 => diverge(),
3 => true || diverge(),
+ //~^ ERROR: sub-expression diverges
10 => match 42 {
99 => return,
_ => true || panic!("boo"),
+ //~^ ERROR: sub-expression diverges
},
// lint blocks as well
15 => true || { return; },
+ //~^ ERROR: sub-expression diverges
16 => false || { return; },
+ //~^ ERROR: sub-expression diverges
// ... and when it's a single expression
17 => true || { return },
+ //~^ ERROR: sub-expression diverges
18 => false || { return },
+ //~^ ERROR: sub-expression diverges
// ... but not when there's both an expression and a statement
19 => true || { _ = 1; return },
20 => false || { _ = 1; return },
@@ -52,6 +63,7 @@ fn foobar() {
23 => true || { return; true },
24 => true || { return; true },
_ => true || break,
+ //~^ ERROR: sub-expression diverges
};
}
}
diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr
index 243a5cf53..d8021c5d7 100644
--- a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr
+++ b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr
@@ -5,33 +5,34 @@ LL | b || diverge();
| ^^^^^^^^^
|
= note: `-D clippy::diverging-sub-expression` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]`
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:21:10
+ --> $DIR/diverging_sub_expression.rs:23:10
|
LL | b || A.foo();
| ^^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:31:26
+ --> $DIR/diverging_sub_expression.rs:34:26
|
LL | 6 => true || return,
| ^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:32:26
+ --> $DIR/diverging_sub_expression.rs:36:26
|
LL | 7 => true || continue,
| ^^^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:35:26
+ --> $DIR/diverging_sub_expression.rs:40:26
|
LL | 3 => true || diverge(),
| ^^^^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:38:30
+ --> $DIR/diverging_sub_expression.rs:44:30
|
LL | _ => true || panic!("boo"),
| ^^^^^^^^^^^^^
@@ -39,31 +40,31 @@ LL | _ => true || panic!("boo"),
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:41:29
+ --> $DIR/diverging_sub_expression.rs:48:29
|
LL | 15 => true || { return; },
| ^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:42:30
+ --> $DIR/diverging_sub_expression.rs:50:30
|
LL | 16 => false || { return; },
| ^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:44:29
+ --> $DIR/diverging_sub_expression.rs:53:29
|
LL | 17 => true || { return },
| ^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:45:30
+ --> $DIR/diverging_sub_expression.rs:55:30
|
LL | 18 => false || { return },
| ^^^^^^
error: sub-expression diverges
- --> $DIR/diverging_sub_expression.rs:54:26
+ --> $DIR/diverging_sub_expression.rs:65:26
|
LL | _ => true || break,
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index 14444df4c..47b56960a 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -1,4 +1,4 @@
-//@run-rustfix
+
//! This file tests for the `DOC_MARKDOWN` lint.
#![allow(dead_code, incomplete_features)]
@@ -198,6 +198,16 @@ fn pulldown_cmark_crash() {}
/// [plain text][path::to::item]
fn intra_doc_link() {}
+/// Ignore escaped\_underscores
+///
+/// \\[
+/// \\prod\_{x\\in X} p\_x
+/// \\]
+fn issue_2581() {}
+
+/// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
+fn lint_after_escaped_chars() {}
+
// issue #7033 - generic_const_exprs ICE
struct S<T, const N: usize>
where [(); N.checked_next_power_of_two().unwrap()]: {
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 542d33b13..4d9a4eafa 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -1,4 +1,4 @@
-//@run-rustfix
+
//! This file tests for the `DOC_MARKDOWN` lint.
#![allow(dead_code, incomplete_features)]
@@ -198,6 +198,16 @@ fn pulldown_cmark_crash() {}
/// [plain text][path::to::item]
fn intra_doc_link() {}
+/// Ignore escaped\_underscores
+///
+/// \\[
+/// \\prod\_{x\\in X} p\_x
+/// \\]
+fn issue_2581() {}
+
+/// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint
+fn lint_after_escaped_chars() {}
+
// issue #7033 - generic_const_exprs ICE
struct S<T, const N: usize>
where [(); N.checked_next_power_of_two().unwrap()]: {
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
index 94ef43afc..4c9ff41d9 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
@@ -5,6 +5,7 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t
| ^^^^^^^
|
= note: `-D clippy::doc-markdown` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
help: try
|
LL | /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there)
@@ -24,12 +25,12 @@ LL | /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot
error: item in documentation is missing backticks
--> $DIR/doc-fixable.rs:10:83
|
-LL | /// Markdown is _weird_. I mean _really weird_. This /_ is ok. So is `_`. But not Foo::some_fun
+LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun
| ^^^^^^^^^^^^^
|
help: try
|
-LL | /// Markdown is _weird_. I mean _really weird_. This /_ is ok. So is `_`. But not `Foo::some_fun`
+LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun`
| ~~~~~~~~~~~~~~~
error: item in documentation is missing backticks
@@ -307,5 +308,16 @@ help: try
LL | /// An iterator over `mycrate::Collection`'s values.
| ~~~~~~~~~~~~~~~~~~~~~
-error: aborting due to 28 previous errors
+error: item in documentation is missing backticks
+ --> $DIR/doc-fixable.rs:208:34
+ |
+LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint
+ | ^^^^^^^^^^^^^^^
+ |
+help: try
+ |
+LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
+ | ~~~~~~~~~~~~~~~~~
+
+error: aborting due to 29 previous errors
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
index 8e8324b30..6f7bab720 100644
--- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
@@ -1,20 +1,24 @@
//! This file tests for the `DOC_MARKDOWN` lint, specifically cases
//! where ticks are unbalanced (see issue #6753).
-
+//@no-rustfix
#![allow(dead_code)]
#![warn(clippy::doc_markdown)]
/// This is a doc comment with `unbalanced_tick marks and several words that
+//~^ ERROR: backticks are unbalanced
/// should be `encompassed_by` tick marks because they `contain_underscores`.
/// Because of the initial `unbalanced_tick` pair, the error message is
/// very `confusing_and_misleading`.
fn main() {}
/// This paragraph has `unbalanced_tick marks and should stop_linting.
+//~^ ERROR: backticks are unbalanced
///
/// This paragraph is fine and should_be linted normally.
+//~^ ERROR: item in documentation is missing backticks
///
/// Double unbalanced backtick from ``here to here` should lint.
+//~^ ERROR: backticks are unbalanced
///
/// Double balanced back ticks ``start end`` is fine.
fn multiple_paragraphs() {}
@@ -28,11 +32,15 @@ fn in_code_block() {}
/// # `Fine`
///
/// ## not_fine
+//~^ ERROR: item in documentation is missing backticks
///
/// ### `unbalanced
+//~^ ERROR: backticks are unbalanced
///
/// - This `item has unbalanced tick marks
+//~^ ERROR: backticks are unbalanced
/// - This item needs backticks_here
+//~^ ERROR: item in documentation is missing backticks
fn other_markdown() {}
#[rustfmt::skip]
@@ -40,4 +48,4 @@ fn other_markdown() {}
/// /// `lol`
/// pub struct Struct;
/// ```
-fn iss_7421() {}
+fn issue_7421() {}
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
index f2ac6bc32..89ad8db39 100644
--- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
@@ -1,7 +1,9 @@
error: backticks are unbalanced
- --> $DIR/unbalanced_ticks.rs:7:1
+ --> $DIR/unbalanced_ticks.rs:7:5
|
-LL | / /// This is a doc comment with `unbalanced_tick marks and several words that
+LL | /// This is a doc comment with `unbalanced_tick marks and several words that
+ | _____^
+LL | |
LL | | /// should be `encompassed_by` tick marks because they `contain_underscores`.
LL | | /// Because of the initial `unbalanced_tick` pair, the error message is
LL | | /// very `confusing_and_misleading`.
@@ -9,17 +11,18 @@ LL | | /// very `confusing_and_misleading`.
|
= help: a backtick may be missing a pair
= note: `-D clippy::doc-markdown` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
error: backticks are unbalanced
- --> $DIR/unbalanced_ticks.rs:13:1
+ --> $DIR/unbalanced_ticks.rs:14:5
|
LL | /// This paragraph has `unbalanced_tick marks and should stop_linting.
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: a backtick may be missing a pair
error: item in documentation is missing backticks
- --> $DIR/unbalanced_ticks.rs:15:32
+ --> $DIR/unbalanced_ticks.rs:17:32
|
LL | /// This paragraph is fine and should_be linted normally.
| ^^^^^^^^^
@@ -30,15 +33,15 @@ LL | /// This paragraph is fine and `should_be` linted normally.
| ~~~~~~~~~~~
error: backticks are unbalanced
- --> $DIR/unbalanced_ticks.rs:17:1
+ --> $DIR/unbalanced_ticks.rs:20:5
|
LL | /// Double unbalanced backtick from ``here to here` should lint.
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: a backtick may be missing a pair
error: item in documentation is missing backticks
- --> $DIR/unbalanced_ticks.rs:30:8
+ --> $DIR/unbalanced_ticks.rs:34:8
|
LL | /// ## not_fine
| ^^^^^^^^
@@ -49,23 +52,23 @@ LL | /// ## `not_fine`
| ~~~~~~~~~~
error: backticks are unbalanced
- --> $DIR/unbalanced_ticks.rs:32:1
+ --> $DIR/unbalanced_ticks.rs:37:5
|
LL | /// ### `unbalanced
- | ^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^
|
= help: a backtick may be missing a pair
error: backticks are unbalanced
- --> $DIR/unbalanced_ticks.rs:34:1
+ --> $DIR/unbalanced_ticks.rs:40:5
|
LL | /// - This `item has unbalanced tick marks
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: a backtick may be missing a pair
error: item in documentation is missing backticks
- --> $DIR/unbalanced_ticks.rs:35:23
+ --> $DIR/unbalanced_ticks.rs:42:23
|
LL | /// - This item needs backticks_here
| ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/doc_errors.rs b/src/tools/clippy/tests/ui/doc_errors.rs
index 30fdd3b08..9b3783aaf 100644
--- a/src/tools/clippy/tests/ui/doc_errors.rs
+++ b/src/tools/clippy/tests/ui/doc_errors.rs
@@ -5,20 +5,25 @@
use std::io;
pub fn pub_fn_missing_errors_header() -> Result<(), ()> {
+ //~^ ERROR: docs for function returning `Result` missing `# Errors` section
+ //~| NOTE: `-D clippy::missing-errors-doc` implied by `-D warnings`
unimplemented!();
}
pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> {
+ //~^ ERROR: docs for function returning `Result` missing `# Errors` section
unimplemented!();
}
/// This is not sufficiently documented.
pub fn pub_fn_returning_io_result() -> io::Result<()> {
+ //~^ ERROR: docs for function returning `Result` missing `# Errors` section
unimplemented!();
}
/// This is not sufficiently documented.
pub async fn async_pub_fn_returning_io_result() -> io::Result<()> {
+ //~^ ERROR: docs for function returning `Result` missing `# Errors` section
unimplemented!();
}
@@ -49,11 +54,13 @@ pub struct Struct1;
impl Struct1 {
/// This is not sufficiently documented.
pub fn pub_method_missing_errors_header() -> Result<(), ()> {
+ //~^ ERROR: docs for function returning `Result` missing `# Errors` section
unimplemented!();
}
/// This is not sufficiently documented.
pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> {
+ //~^ ERROR: docs for function returning `Result` missing `# Errors` section
unimplemented!();
}
@@ -78,15 +85,42 @@ impl Struct1 {
async fn async_priv_method_missing_errors_header() -> Result<(), ()> {
unimplemented!();
}
+
+ /**
+ # Errors
+ A description of the errors goes here.
+ */
+ fn block_comment() -> Result<(), ()> {
+ unimplemented!();
+ }
+
+ /**
+ * # Errors
+ * A description of the errors goes here.
+ */
+ fn block_comment_leading_asterisks() -> Result<(), ()> {
+ unimplemented!();
+ }
+
+ #[doc(hidden)]
+ fn doc_hidden() -> Result<(), ()> {
+ unimplemented!();
+ }
}
pub trait Trait1 {
/// This is not sufficiently documented.
fn trait_method_missing_errors_header() -> Result<(), ()>;
+ //~^ ERROR: docs for function returning `Result` missing `# Errors` section
/// # Errors
/// A description of the errors goes here.
fn trait_method_with_errors_header() -> Result<(), ()>;
+
+ #[doc(hidden)]
+ fn doc_hidden() -> Result<(), ()> {
+ unimplemented!();
+ }
}
impl Trait1 for Struct1 {
@@ -99,6 +133,11 @@ impl Trait1 for Struct1 {
}
}
+#[doc(hidden)]
+pub trait DocHidden {
+ fn f() -> Result<(), ()>;
+}
+
fn main() -> Result<(), ()> {
Ok(())
}
diff --git a/src/tools/clippy/tests/ui/doc_errors.stderr b/src/tools/clippy/tests/ui/doc_errors.stderr
index d74f2dbfe..dc59675b9 100644
--- a/src/tools/clippy/tests/ui/doc_errors.stderr
+++ b/src/tools/clippy/tests/ui/doc_errors.stderr
@@ -5,39 +5,40 @@ LL | pub fn pub_fn_missing_errors_header() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::missing-errors-doc` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_errors_doc)]`
error: docs for function returning `Result` missing `# Errors` section
- --> $DIR/doc_errors.rs:11:1
+ --> $DIR/doc_errors.rs:13:1
|
LL | pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: docs for function returning `Result` missing `# Errors` section
- --> $DIR/doc_errors.rs:16:1
+ --> $DIR/doc_errors.rs:19:1
|
LL | pub fn pub_fn_returning_io_result() -> io::Result<()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: docs for function returning `Result` missing `# Errors` section
- --> $DIR/doc_errors.rs:21:1
+ --> $DIR/doc_errors.rs:25:1
|
LL | pub async fn async_pub_fn_returning_io_result() -> io::Result<()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: docs for function returning `Result` missing `# Errors` section
- --> $DIR/doc_errors.rs:51:5
+ --> $DIR/doc_errors.rs:56:5
|
LL | pub fn pub_method_missing_errors_header() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: docs for function returning `Result` missing `# Errors` section
- --> $DIR/doc_errors.rs:56:5
+ --> $DIR/doc_errors.rs:62:5
|
LL | pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: docs for function returning `Result` missing `# Errors` section
- --> $DIR/doc_errors.rs:85:5
+ --> $DIR/doc_errors.rs:113:5
|
LL | fn trait_method_missing_errors_header() -> Result<(), ()>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/doc_link_with_quotes.rs b/src/tools/clippy/tests/ui/doc_link_with_quotes.rs
index 17c04c34e..37d0d1359 100644
--- a/src/tools/clippy/tests/ui/doc_link_with_quotes.rs
+++ b/src/tools/clippy/tests/ui/doc_link_with_quotes.rs
@@ -5,6 +5,8 @@ fn main() {
}
/// Calls ['bar'] uselessly
+//~^ ERROR: possible intra-doc link using quotes instead of backticks
+//~| NOTE: `-D clippy::doc-link-with-quotes` implied by `-D warnings`
pub fn foo() {
bar()
}
diff --git a/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr b/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr
index ea730e667..2db1bc092 100644
--- a/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr
+++ b/src/tools/clippy/tests/ui/doc_link_with_quotes.stderr
@@ -5,6 +5,7 @@ LL | /// Calls ['bar'] uselessly
| ^^^^^
|
= note: `-D clippy::doc-link-with-quotes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::doc_link_with_quotes)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/doc_unsafe.rs b/src/tools/clippy/tests/ui/doc_unsafe.rs
index d21b046f1..0c8eac5cc 100644
--- a/src/tools/clippy/tests/ui/doc_unsafe.rs
+++ b/src/tools/clippy/tests/ui/doc_unsafe.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::let_unit_value)]
diff --git a/src/tools/clippy/tests/ui/doc_unsafe.stderr b/src/tools/clippy/tests/ui/doc_unsafe.stderr
index a86e19137..ab3fb3c02 100644
--- a/src/tools/clippy/tests/ui/doc_unsafe.stderr
+++ b/src/tools/clippy/tests/ui/doc_unsafe.stderr
@@ -5,6 +5,7 @@ LL | pub unsafe fn destroy_the_planet() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::missing-safety-doc` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_safety_doc)]`
error: unsafe function's docs miss `# Safety` section
--> $DIR/doc_unsafe.rs:32:5
diff --git a/src/tools/clippy/tests/ui/double_comparison.fixed b/src/tools/clippy/tests/ui/double_comparison.fixed
index f8ca92ef0..788f3224b 100644
--- a/src/tools/clippy/tests/ui/double_comparison.fixed
+++ b/src/tools/clippy/tests/ui/double_comparison.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::needless_if)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/double_comparison.rs b/src/tools/clippy/tests/ui/double_comparison.rs
index 47ff87bea..245a83d57 100644
--- a/src/tools/clippy/tests/ui/double_comparison.rs
+++ b/src/tools/clippy/tests/ui/double_comparison.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::needless_if)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/double_comparison.stderr b/src/tools/clippy/tests/ui/double_comparison.stderr
index 4df1c28ac..02f0a9609 100644
--- a/src/tools/clippy/tests/ui/double_comparison.stderr
+++ b/src/tools/clippy/tests/ui/double_comparison.stderr
@@ -1,49 +1,50 @@
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:7:8
+ --> $DIR/double_comparison.rs:6:8
|
LL | if x == y || x < y {
| ^^^^^^^^^^^^^^^ help: try: `x <= y`
|
= note: `-D clippy::double-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::double_comparisons)]`
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:10:8
+ --> $DIR/double_comparison.rs:9:8
|
LL | if x < y || x == y {
| ^^^^^^^^^^^^^^^ help: try: `x <= y`
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:13:8
+ --> $DIR/double_comparison.rs:12:8
|
LL | if x == y || x > y {
| ^^^^^^^^^^^^^^^ help: try: `x >= y`
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:16:8
+ --> $DIR/double_comparison.rs:15:8
|
LL | if x > y || x == y {
| ^^^^^^^^^^^^^^^ help: try: `x >= y`
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:19:8
+ --> $DIR/double_comparison.rs:18:8
|
LL | if x < y || x > y {
| ^^^^^^^^^^^^^^ help: try: `x != y`
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:22:8
+ --> $DIR/double_comparison.rs:21:8
|
LL | if x > y || x < y {
| ^^^^^^^^^^^^^^ help: try: `x != y`
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:25:8
+ --> $DIR/double_comparison.rs:24:8
|
LL | if x <= y && x >= y {
| ^^^^^^^^^^^^^^^^ help: try: `x == y`
error: this binary expression can be simplified
- --> $DIR/double_comparison.rs:28:8
+ --> $DIR/double_comparison.rs:27:8
|
LL | if x >= y && x <= y {
| ^^^^^^^^^^^^^^^^ help: try: `x == y`
diff --git a/src/tools/clippy/tests/ui/double_must_use.rs b/src/tools/clippy/tests/ui/double_must_use.rs
index 26a387b3c..615de3e24 100644
--- a/src/tools/clippy/tests/ui/double_must_use.rs
+++ b/src/tools/clippy/tests/ui/double_must_use.rs
@@ -3,16 +3,19 @@
#[must_use]
pub fn must_use_result() -> Result<(), ()> {
+ //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
unimplemented!();
}
#[must_use]
pub fn must_use_tuple() -> (Result<(), ()>, u8) {
+ //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
unimplemented!();
}
#[must_use]
pub fn must_use_array() -> [Result<(), ()>; 1] {
+ //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
unimplemented!();
}
@@ -29,6 +32,7 @@ async fn async_must_use() -> usize {
#[must_use]
async fn async_must_use_result() -> Result<(), ()> {
+ //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
Ok(())
}
diff --git a/src/tools/clippy/tests/ui/double_must_use.stderr b/src/tools/clippy/tests/ui/double_must_use.stderr
index 49ab2ea3e..a2d87c59e 100644
--- a/src/tools/clippy/tests/ui/double_must_use.stderr
+++ b/src/tools/clippy/tests/ui/double_must_use.stderr
@@ -6,9 +6,10 @@ LL | pub fn must_use_result() -> Result<(), ()> {
|
= help: either add some descriptive text or remove the attribute
= note: `-D clippy::double-must-use` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]`
error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
- --> $DIR/double_must_use.rs:10:1
+ --> $DIR/double_must_use.rs:11:1
|
LL | pub fn must_use_tuple() -> (Result<(), ()>, u8) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | pub fn must_use_tuple() -> (Result<(), ()>, u8) {
= help: either add some descriptive text or remove the attribute
error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
- --> $DIR/double_must_use.rs:15:1
+ --> $DIR/double_must_use.rs:17:1
|
LL | pub fn must_use_array() -> [Result<(), ()>; 1] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | pub fn must_use_array() -> [Result<(), ()>; 1] {
= help: either add some descriptive text or remove the attribute
error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
- --> $DIR/double_must_use.rs:31:1
+ --> $DIR/double_must_use.rs:34:1
|
LL | async fn async_must_use_result() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/double_neg.rs b/src/tools/clippy/tests/ui/double_neg.rs
index 38a8fbd74..da8289044 100644
--- a/src/tools/clippy/tests/ui/double_neg.rs
+++ b/src/tools/clippy/tests/ui/double_neg.rs
@@ -5,4 +5,6 @@ fn main() {
-x;
-(-x);
--x;
+ //~^ ERROR: `--x` could be misinterpreted as pre-decrement by C programmers, is usuall
+ //~| NOTE: `-D clippy::double-neg` implied by `-D warnings`
}
diff --git a/src/tools/clippy/tests/ui/double_neg.stderr b/src/tools/clippy/tests/ui/double_neg.stderr
index 7cdb040b6..a6241c786 100644
--- a/src/tools/clippy/tests/ui/double_neg.stderr
+++ b/src/tools/clippy/tests/ui/double_neg.stderr
@@ -5,6 +5,7 @@ LL | --x;
| ^^^
|
= note: `-D clippy::double-neg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::double_neg)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/double_parens.rs b/src/tools/clippy/tests/ui/double_parens.rs
index ff1dc76ab..ab1459eed 100644
--- a/src/tools/clippy/tests/ui/double_parens.rs
+++ b/src/tools/clippy/tests/ui/double_parens.rs
@@ -13,22 +13,28 @@ impl DummyStruct {
fn simple_double_parens() -> i32 {
((0))
+ //~^ ERROR: consider removing unnecessary double parentheses
+ //~| NOTE: `-D clippy::double-parens` implied by `-D warnings`
}
fn fn_double_parens() {
dummy_fn((0));
+ //~^ ERROR: consider removing unnecessary double parentheses
}
fn method_double_parens(x: DummyStruct) {
x.dummy_method((0));
+ //~^ ERROR: consider removing unnecessary double parentheses
}
fn tuple_double_parens() -> (i32, i32) {
((1, 2))
+ //~^ ERROR: consider removing unnecessary double parentheses
}
fn unit_double_parens() {
(())
+ //~^ ERROR: consider removing unnecessary double parentheses
}
fn fn_tuple_ok() {
@@ -51,6 +57,7 @@ fn method_unit_ok(x: DummyStruct) {
fn inside_macro() {
assert_eq!((1, 2), (1, 2), "Error");
assert_eq!(((1, 2)), (1, 2), "Error");
+ //~^ ERROR: consider removing unnecessary double parentheses
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/double_parens.stderr b/src/tools/clippy/tests/ui/double_parens.stderr
index 40fcad2ab..8a010d8cc 100644
--- a/src/tools/clippy/tests/ui/double_parens.stderr
+++ b/src/tools/clippy/tests/ui/double_parens.stderr
@@ -5,33 +5,34 @@ LL | ((0))
| ^^^^^
|
= note: `-D clippy::double-parens` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::double_parens)]`
error: consider removing unnecessary double parentheses
- --> $DIR/double_parens.rs:19:14
+ --> $DIR/double_parens.rs:21:14
|
LL | dummy_fn((0));
| ^^^
error: consider removing unnecessary double parentheses
- --> $DIR/double_parens.rs:23:20
+ --> $DIR/double_parens.rs:26:20
|
LL | x.dummy_method((0));
| ^^^
error: consider removing unnecessary double parentheses
- --> $DIR/double_parens.rs:27:5
+ --> $DIR/double_parens.rs:31:5
|
LL | ((1, 2))
| ^^^^^^^^
error: consider removing unnecessary double parentheses
- --> $DIR/double_parens.rs:31:5
+ --> $DIR/double_parens.rs:36:5
|
LL | (())
| ^^^^
error: consider removing unnecessary double parentheses
- --> $DIR/double_parens.rs:53:16
+ --> $DIR/double_parens.rs:59:16
|
LL | assert_eq!(((1, 2)), (1, 2), "Error");
| ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/drain_collect.fixed b/src/tools/clippy/tests/ui/drain_collect.fixed
index 11001bd31..6f597243f 100644
--- a/src/tools/clippy/tests/ui/drain_collect.fixed
+++ b/src/tools/clippy/tests/ui/drain_collect.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::drain_collect)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/drain_collect.rs b/src/tools/clippy/tests/ui/drain_collect.rs
index 373a3ca35..353aac4da 100644
--- a/src/tools/clippy/tests/ui/drain_collect.rs
+++ b/src/tools/clippy/tests/ui/drain_collect.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::drain_collect)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/drain_collect.stderr b/src/tools/clippy/tests/ui/drain_collect.stderr
index 0792f0254..3364466ec 100644
--- a/src/tools/clippy/tests/ui/drain_collect.stderr
+++ b/src/tools/clippy/tests/ui/drain_collect.stderr
@@ -1,65 +1,65 @@
error: you seem to be trying to move all elements into a new `BinaryHeap`
- --> $DIR/drain_collect.rs:9:5
+ --> $DIR/drain_collect.rs:7:5
|
LL | b.drain().collect()
| ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
|
note: the lint level is defined here
- --> $DIR/drain_collect.rs:3:9
+ --> $DIR/drain_collect.rs:1:9
|
LL | #![deny(clippy::drain_collect)]
| ^^^^^^^^^^^^^^^^^^^^^
error: you seem to be trying to move all elements into a new `HashMap`
- --> $DIR/drain_collect.rs:17:5
+ --> $DIR/drain_collect.rs:15:5
|
LL | b.drain().collect()
| ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
error: you seem to be trying to move all elements into a new `HashSet`
- --> $DIR/drain_collect.rs:25:5
+ --> $DIR/drain_collect.rs:23:5
|
LL | b.drain().collect()
| ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
error: you seem to be trying to move all elements into a new `Vec`
- --> $DIR/drain_collect.rs:33:5
+ --> $DIR/drain_collect.rs:31:5
|
LL | b.drain(..).collect()
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
error: you seem to be trying to move all elements into a new `Vec`
- --> $DIR/drain_collect.rs:41:5
+ --> $DIR/drain_collect.rs:39:5
|
LL | b.drain(..).collect()
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
error: you seem to be trying to move all elements into a new `Vec`
- --> $DIR/drain_collect.rs:45:5
+ --> $DIR/drain_collect.rs:43:5
|
LL | b.drain(0..).collect()
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
error: you seem to be trying to move all elements into a new `Vec`
- --> $DIR/drain_collect.rs:49:5
+ --> $DIR/drain_collect.rs:47:5
|
LL | b.drain(..b.len()).collect()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
error: you seem to be trying to move all elements into a new `Vec`
- --> $DIR/drain_collect.rs:53:5
+ --> $DIR/drain_collect.rs:51:5
|
LL | b.drain(0..b.len()).collect()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
error: you seem to be trying to move all elements into a new `Vec`
- --> $DIR/drain_collect.rs:58:5
+ --> $DIR/drain_collect.rs:56:5
|
LL | b.drain(..).collect()
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(&mut b)`
error: you seem to be trying to move all elements into a new `String`
- --> $DIR/drain_collect.rs:66:5
+ --> $DIR/drain_collect.rs:64:5
|
LL | b.drain(..).collect()
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.rs b/src/tools/clippy/tests/ui/drop_non_drop.rs
index 5a0ebde82..6dbcb7777 100644
--- a/src/tools/clippy/tests/ui/drop_non_drop.rs
+++ b/src/tools/clippy/tests/ui/drop_non_drop.rs
@@ -20,6 +20,7 @@ fn main() {
struct Foo;
// Lint
drop(Foo);
+ //~^ ERROR: call to `std::mem::drop` with a value that does not implement `Drop`. Drop
// Don't lint
drop(make_result(Foo));
// Don't lint
@@ -35,6 +36,7 @@ fn main() {
struct Baz<T>(T);
// Lint
drop(Baz(Foo));
+ //~^ ERROR: call to `std::mem::drop` with a value that does not implement `Drop`. Drop
// Don't lint
drop(Baz(Bar));
}
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.stderr b/src/tools/clippy/tests/ui/drop_non_drop.stderr
index b86057c0c..a571076f6 100644
--- a/src/tools/clippy/tests/ui/drop_non_drop.stderr
+++ b/src/tools/clippy/tests/ui/drop_non_drop.stderr
@@ -10,15 +10,16 @@ note: argument has type `main::Foo`
LL | drop(Foo);
| ^^^
= note: `-D clippy::drop-non-drop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::drop_non_drop)]`
error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes
- --> $DIR/drop_non_drop.rs:37:5
+ --> $DIR/drop_non_drop.rs:38:5
|
LL | drop(Baz(Foo));
| ^^^^^^^^^^^^^^
|
note: argument has type `main::Baz<main::Foo>`
- --> $DIR/drop_non_drop.rs:37:10
+ --> $DIR/drop_non_drop.rs:38:10
|
LL | drop(Baz(Foo));
| ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs b/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs
index 54d748c7c..118f6e4a3 100644
--- a/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs
+++ b/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs
@@ -2,6 +2,8 @@
#[allow(dead_code, unused)]
fn join_the_dark_side(darth: i32, _darth: i32) {}
+//~^ ERROR: `darth` already exists, having another argument having almost the same name ma
+//~| NOTE: `-D clippy::duplicate-underscore-argument` implied by `-D warnings`
fn join_the_light_side(knight: i32, _master: i32) {} // the Force is strong with this one
fn main() {
diff --git a/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr b/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr
index f71614a5f..f47f6c896 100644
--- a/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr
+++ b/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr
@@ -5,6 +5,7 @@ LL | fn join_the_dark_side(darth: i32, _darth: i32) {}
| ^^^^^
|
= note: `-D clippy::duplicate-underscore-argument` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::duplicate_underscore_argument)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/duration_subsec.fixed b/src/tools/clippy/tests/ui/duration_subsec.fixed
index bfd30f004..114c516ed 100644
--- a/src/tools/clippy/tests/ui/duration_subsec.fixed
+++ b/src/tools/clippy/tests/ui/duration_subsec.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::needless_borrow)]
#![warn(clippy::duration_subsec)]
diff --git a/src/tools/clippy/tests/ui/duration_subsec.rs b/src/tools/clippy/tests/ui/duration_subsec.rs
index 860233f08..8469fe086 100644
--- a/src/tools/clippy/tests/ui/duration_subsec.rs
+++ b/src/tools/clippy/tests/ui/duration_subsec.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::needless_borrow)]
#![warn(clippy::duration_subsec)]
diff --git a/src/tools/clippy/tests/ui/duration_subsec.stderr b/src/tools/clippy/tests/ui/duration_subsec.stderr
index cdbeff6a0..705683837 100644
--- a/src/tools/clippy/tests/ui/duration_subsec.stderr
+++ b/src/tools/clippy/tests/ui/duration_subsec.stderr
@@ -1,31 +1,32 @@
error: calling `subsec_millis()` is more concise than this calculation
- --> $DIR/duration_subsec.rs:10:24
+ --> $DIR/duration_subsec.rs:9:24
|
LL | let bad_millis_1 = dur.subsec_micros() / 1_000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()`
|
= note: `-D clippy::duration-subsec` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::duration_subsec)]`
error: calling `subsec_millis()` is more concise than this calculation
- --> $DIR/duration_subsec.rs:11:24
+ --> $DIR/duration_subsec.rs:10:24
|
LL | let bad_millis_2 = dur.subsec_nanos() / 1_000_000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()`
error: calling `subsec_micros()` is more concise than this calculation
- --> $DIR/duration_subsec.rs:16:22
+ --> $DIR/duration_subsec.rs:15:22
|
LL | let bad_micros = dur.subsec_nanos() / 1_000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()`
error: calling `subsec_micros()` is more concise than this calculation
- --> $DIR/duration_subsec.rs:21:13
+ --> $DIR/duration_subsec.rs:20:13
|
LL | let _ = (&dur).subsec_nanos() / 1_000;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&dur).subsec_micros()`
error: calling `subsec_micros()` is more concise than this calculation
- --> $DIR/duration_subsec.rs:25:13
+ --> $DIR/duration_subsec.rs:24:13
|
LL | let _ = dur.subsec_nanos() / NANOS_IN_MICRO;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()`
diff --git a/src/tools/clippy/tests/ui/else_if_without_else.stderr b/src/tools/clippy/tests/ui/else_if_without_else.stderr
index 11baf7544..b2bf4ac4d 100644
--- a/src/tools/clippy/tests/ui/else_if_without_else.stderr
+++ b/src/tools/clippy/tests/ui/else_if_without_else.stderr
@@ -10,6 +10,7 @@ LL | | }
|
= help: add an `else` block here
= note: `-D clippy::else-if-without-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::else_if_without_else)]`
error: `if` expression with an `else if`, but without a final `else`
--> $DIR/else_if_without_else.rs:54:12
diff --git a/src/tools/clippy/tests/ui/empty_drop.fixed b/src/tools/clippy/tests/ui/empty_drop.fixed
index fd0a9a708..949d0d8b3 100644
--- a/src/tools/clippy/tests/ui/empty_drop.fixed
+++ b/src/tools/clippy/tests/ui/empty_drop.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::empty_drop)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/empty_drop.rs b/src/tools/clippy/tests/ui/empty_drop.rs
index 6c15cb933..74822ea50 100644
--- a/src/tools/clippy/tests/ui/empty_drop.rs
+++ b/src/tools/clippy/tests/ui/empty_drop.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::empty_drop)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/empty_drop.stderr b/src/tools/clippy/tests/ui/empty_drop.stderr
index 70f7880d0..5848eab74 100644
--- a/src/tools/clippy/tests/ui/empty_drop.stderr
+++ b/src/tools/clippy/tests/ui/empty_drop.stderr
@@ -1,5 +1,5 @@
error: empty drop implementation
- --> $DIR/empty_drop.rs:8:1
+ --> $DIR/empty_drop.rs:7:1
|
LL | / impl Drop for Foo {
LL | | fn drop(&mut self) {}
@@ -7,9 +7,10 @@ LL | | }
| |_^ help: try removing this impl
|
= note: `-D clippy::empty-drop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_drop)]`
error: empty drop implementation
- --> $DIR/empty_drop.rs:24:1
+ --> $DIR/empty_drop.rs:23:1
|
LL | / impl Drop for Baz {
LL | | fn drop(&mut self) {
diff --git a/src/tools/clippy/tests/ui/empty_enum.rs b/src/tools/clippy/tests/ui/empty_enum.rs
index a2e5c13c4..77357c15d 100644
--- a/src/tools/clippy/tests/ui/empty_enum.rs
+++ b/src/tools/clippy/tests/ui/empty_enum.rs
@@ -3,5 +3,6 @@
// Enable never type to test empty enum lint
#![feature(never_type)]
enum Empty {}
+//~^ ERROR: enum with no variants
fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_enum.stderr b/src/tools/clippy/tests/ui/empty_enum.stderr
index 0d9aa5818..92d81c726 100644
--- a/src/tools/clippy/tests/ui/empty_enum.stderr
+++ b/src/tools/clippy/tests/ui/empty_enum.stderr
@@ -6,6 +6,7 @@ LL | enum Empty {}
|
= help: consider using the uninhabited type `!` (never type) or a wrapper around it to introduce a type which can't be instantiated
= note: `-D clippy::empty-enum` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_enum)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs b/src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs
index cc36ce5f4..e843770f5 100644
--- a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs
+++ b/src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs
@@ -1,7 +1,4 @@
-//@aux-build:proc_macro_attr.rs:proc-macro
-// Flaky test, see https://github.com/rust-lang/rust/issues/113585.
-//@ignore-32bit
-//@ignore-64bit
+//@aux-build:proc_macro_attr.rs
#![warn(clippy::empty_line_after_doc_comments)]
#![allow(clippy::assertions_on_constants)]
#![feature(custom_inner_attributes)]
diff --git a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr
index 2ca1b5167..2cf5b5b0f 100644
--- a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr
@@ -7,6 +7,7 @@ LL | | fn with_doc_and_newline() { assert!(true)}
| |_
|
= note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`
error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?
--> $DIR/empty_line_after_doc_comments.rs:68:1
diff --git a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs
index bc54e0fd2..269e66ea0 100644
--- a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs
+++ b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs
@@ -1,7 +1,4 @@
-//@aux-build:proc_macro_attr.rs:proc-macro
-// Flaky test, see https://github.com/rust-lang/rust/issues/113585.
-//@ignore-32bit
-//@ignore-64bit
+//@aux-build:proc_macro_attr.rs
#![warn(clippy::empty_line_after_outer_attr)]
#![allow(clippy::assertions_on_constants)]
#![feature(custom_inner_attributes)]
diff --git a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr
index 594fca44a..0cb848c20 100644
--- a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr
@@ -8,6 +8,7 @@ LL | | fn with_one_newline_and_comment() { assert!(true) }
| |_
|
= note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
--> $DIR/empty_line_after_outer_attribute.rs:23:1
diff --git a/src/tools/clippy/tests/ui/empty_loop.rs b/src/tools/clippy/tests/ui/empty_loop.rs
index f1a55415c..be3475631 100644
--- a/src/tools/clippy/tests/ui/empty_loop.rs
+++ b/src/tools/clippy/tests/ui/empty_loop.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::empty_loop)]
@@ -7,10 +7,12 @@ use proc_macros::{external, inline_macros};
fn should_trigger() {
loop {}
+ #[allow(clippy::never_loop)]
loop {
loop {}
}
+ #[allow(clippy::never_loop)]
'outer: loop {
'inner: loop {}
}
@@ -18,6 +20,7 @@ fn should_trigger() {
#[inline_macros]
fn should_not_trigger() {
+ #[allow(clippy::never_loop)]
loop {
panic!("This is fine")
}
diff --git a/src/tools/clippy/tests/ui/empty_loop.stderr b/src/tools/clippy/tests/ui/empty_loop.stderr
index 760241233..113556f67 100644
--- a/src/tools/clippy/tests/ui/empty_loop.stderr
+++ b/src/tools/clippy/tests/ui/empty_loop.stderr
@@ -6,9 +6,10 @@ LL | loop {}
|
= help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body
= note: `-D clippy::empty-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]`
error: empty `loop {}` wastes CPU cycles
- --> $DIR/empty_loop.rs:11:9
+ --> $DIR/empty_loop.rs:12:9
|
LL | loop {}
| ^^^^^^^
@@ -16,7 +17,7 @@ LL | loop {}
= help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body
error: empty `loop {}` wastes CPU cycles
- --> $DIR/empty_loop.rs:15:9
+ --> $DIR/empty_loop.rs:17:9
|
LL | 'inner: loop {}
| ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.rs b/src/tools/clippy/tests/ui/empty_loop_no_std.rs
index f9ab443df..5fe32351e 100644
--- a/src/tools/clippy/tests/ui/empty_loop_no_std.rs
+++ b/src/tools/clippy/tests/ui/empty_loop_no_std.rs
@@ -11,6 +11,7 @@ use core::panic::PanicInfo;
fn main(argc: isize, argv: *const *const u8) -> isize {
// This should trigger the lint
loop {}
+ //~^ ERROR: empty `loop {}` wastes CPU cycles
}
#[panic_handler]
@@ -23,4 +24,5 @@ fn panic(_info: &PanicInfo) -> ! {
extern "C" fn eh_personality() {
// This should also trigger the lint
loop {}
+ //~^ ERROR: empty `loop {}` wastes CPU cycles
}
diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
index 71af64f49..902008264 100644
--- a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
+++ b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
@@ -6,9 +6,10 @@ LL | loop {}
|
= help: you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body
= note: `-D clippy::empty-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]`
error: empty `loop {}` wastes CPU cycles
- --> $DIR/empty_loop_no_std.rs:25:5
+ --> $DIR/empty_loop_no_std.rs:26:5
|
LL | loop {}
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
index 6fab30208..80572645f 100644
--- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::empty_structs_with_brackets)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
index 0caa3c49c..8fb3e247a 100644
--- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::empty_structs_with_brackets)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
index 0308cb557..4b8572d5c 100644
--- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
@@ -1,14 +1,15 @@
error: found empty brackets on struct declaration
- --> $DIR/empty_structs_with_brackets.rs:5:25
+ --> $DIR/empty_structs_with_brackets.rs:4:25
|
LL | pub struct MyEmptyStruct {} // should trigger lint
| ^^^
|
= note: `-D clippy::empty-structs-with-brackets` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::empty_structs_with_brackets)]`
= help: remove the brackets
error: found empty brackets on struct declaration
- --> $DIR/empty_structs_with_brackets.rs:6:26
+ --> $DIR/empty_structs_with_brackets.rs:5:26
|
LL | struct MyEmptyTupleStruct(); // should trigger lint
| ^^^
diff --git a/src/tools/clippy/tests/ui/endian_bytes.stderr b/src/tools/clippy/tests/ui/endian_bytes.stderr
index 5e64ea5b5..a458c46fa 100644
--- a/src/tools/clippy/tests/ui/endian_bytes.stderr
+++ b/src/tools/clippy/tests/ui/endian_bytes.stderr
@@ -9,6 +9,7 @@ LL | fn host() { fn_body!(); }
|
= help: specify the desired endianness explicitly
= note: `-D clippy::host-endian-bytes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::host_endian_bytes)]`
= note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)
error: usage of the `i8::to_ne_bytes` method
@@ -346,6 +347,7 @@ LL | fn little() { fn_body!(); }
|
= help: use the native endianness instead
= note: `-D clippy::little-endian-bytes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::little_endian_bytes)]`
= note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)
error: usage of the `i8::to_le_bytes` method
@@ -707,6 +709,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); }
|
= help: use `u8::to_le_bytes` instead
= note: `-D clippy::big-endian-bytes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::big_endian_bytes)]`
= note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)
error: usage of the function `u8::from_be_bytes`
diff --git a/src/tools/clippy/tests/ui/entry.fixed b/src/tools/clippy/tests/ui/entry.fixed
index 7e8239060..4099fe7e1 100644
--- a/src/tools/clippy/tests/ui/entry.fixed
+++ b/src/tools/clippy/tests/ui/entry.fixed
@@ -1,5 +1,4 @@
//@needs-asm-support
-//@run-rustfix
#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
#![warn(clippy::map_entry)]
diff --git a/src/tools/clippy/tests/ui/entry.rs b/src/tools/clippy/tests/ui/entry.rs
index 742c93225..409be0aa0 100644
--- a/src/tools/clippy/tests/ui/entry.rs
+++ b/src/tools/clippy/tests/ui/entry.rs
@@ -1,5 +1,4 @@
//@needs-asm-support
-//@run-rustfix
#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
#![warn(clippy::map_entry)]
diff --git a/src/tools/clippy/tests/ui/entry.stderr b/src/tools/clippy/tests/ui/entry.stderr
index e8a003e9c..b01f0a9a0 100644
--- a/src/tools/clippy/tests/ui/entry.stderr
+++ b/src/tools/clippy/tests/ui/entry.stderr
@@ -1,5 +1,5 @@
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:25:5
+ --> $DIR/entry.rs:24:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v);
@@ -7,9 +7,10 @@ LL | | }
| |_____^ help: try: `m.entry(k).or_insert(v);`
|
= note: `-D clippy::map-entry` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:30:5
+ --> $DIR/entry.rs:29:5
|
LL | / if !m.contains_key(&k) {
LL | | if true {
@@ -32,7 +33,7 @@ LL + });
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:39:5
+ --> $DIR/entry.rs:38:5
|
LL | / if !m.contains_key(&k) {
LL | | if true {
@@ -55,7 +56,7 @@ LL + });
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:48:5
+ --> $DIR/entry.rs:47:5
|
LL | / if !m.contains_key(&k) {
LL | | if true {
@@ -79,7 +80,7 @@ LL + }
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:58:5
+ --> $DIR/entry.rs:57:5
|
LL | / if !m.contains_key(&k) {
LL | | foo();
@@ -96,7 +97,7 @@ LL + });
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:64:5
+ --> $DIR/entry.rs:63:5
|
LL | / if !m.contains_key(&k) {
LL | | match 0 {
@@ -122,7 +123,7 @@ LL + });
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:76:5
+ --> $DIR/entry.rs:75:5
|
LL | / if !m.contains_key(&k) {
LL | | match 0 {
@@ -146,7 +147,7 @@ LL + }
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:86:5
+ --> $DIR/entry.rs:85:5
|
LL | / if !m.contains_key(&k) {
LL | | foo();
@@ -187,7 +188,7 @@ LL + });
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:120:5
+ --> $DIR/entry.rs:119:5
|
LL | / if !m.contains_key(&m!(k)) {
LL | | m.insert(m!(k), m!(v));
@@ -195,7 +196,7 @@ LL | | }
| |_____^ help: try: `m.entry(m!(k)).or_insert_with(|| m!(v));`
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry.rs:152:5
+ --> $DIR/entry.rs:151:5
|
LL | / if !m.contains_key(&k) {
LL | | let x = (String::new(), String::new());
diff --git a/src/tools/clippy/tests/ui/entry_btree.fixed b/src/tools/clippy/tests/ui/entry_btree.fixed
index 3baaacffd..228212c79 100644
--- a/src/tools/clippy/tests/ui/entry_btree.fixed
+++ b/src/tools/clippy/tests/ui/entry_btree.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::map_entry)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/entry_btree.rs b/src/tools/clippy/tests/ui/entry_btree.rs
index 770e8e91d..44703c567 100644
--- a/src/tools/clippy/tests/ui/entry_btree.rs
+++ b/src/tools/clippy/tests/ui/entry_btree.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::map_entry)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/entry_btree.stderr b/src/tools/clippy/tests/ui/entry_btree.stderr
index 8f41581d6..cc0e951d9 100644
--- a/src/tools/clippy/tests/ui/entry_btree.stderr
+++ b/src/tools/clippy/tests/ui/entry_btree.stderr
@@ -1,5 +1,5 @@
error: usage of `contains_key` followed by `insert` on a `BTreeMap`
- --> $DIR/entry_btree.rs:12:5
+ --> $DIR/entry_btree.rs:10:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v);
@@ -8,6 +8,7 @@ LL | | }
| |_____^
|
= note: `-D clippy::map-entry` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`
help: try
|
LL ~ if let std::collections::btree_map::Entry::Vacant(e) = m.entry(k) {
diff --git a/src/tools/clippy/tests/ui/entry_with_else.fixed b/src/tools/clippy/tests/ui/entry_with_else.fixed
index 71fe04fd6..34804b9ee 100644
--- a/src/tools/clippy/tests/ui/entry_with_else.fixed
+++ b/src/tools/clippy/tests/ui/entry_with_else.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
#![warn(clippy::map_entry)]
diff --git a/src/tools/clippy/tests/ui/entry_with_else.rs b/src/tools/clippy/tests/ui/entry_with_else.rs
index 80f74649a..0515748fd 100644
--- a/src/tools/clippy/tests/ui/entry_with_else.rs
+++ b/src/tools/clippy/tests/ui/entry_with_else.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
#![warn(clippy::map_entry)]
diff --git a/src/tools/clippy/tests/ui/entry_with_else.stderr b/src/tools/clippy/tests/ui/entry_with_else.stderr
index 0d0eb9649..425e87122 100644
--- a/src/tools/clippy/tests/ui/entry_with_else.stderr
+++ b/src/tools/clippy/tests/ui/entry_with_else.stderr
@@ -1,5 +1,5 @@
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry_with_else.rs:16:5
+ --> $DIR/entry_with_else.rs:14:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v);
@@ -9,6 +9,7 @@ LL | | }
| |_____^
|
= note: `-D clippy::map-entry` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`
help: try
|
LL ~ match m.entry(k) {
@@ -22,7 +23,7 @@ LL + }
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry_with_else.rs:22:5
+ --> $DIR/entry_with_else.rs:20:5
|
LL | / if m.contains_key(&k) {
LL | | m.insert(k, v);
@@ -44,7 +45,7 @@ LL + }
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry_with_else.rs:28:5
+ --> $DIR/entry_with_else.rs:26:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v);
@@ -63,7 +64,7 @@ LL + }
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry_with_else.rs:34:5
+ --> $DIR/entry_with_else.rs:32:5
|
LL | / if !m.contains_key(&k) {
LL | | foo();
@@ -82,7 +83,7 @@ LL + }
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry_with_else.rs:40:5
+ --> $DIR/entry_with_else.rs:38:5
|
LL | / if !m.contains_key(&k) {
LL | | m.insert(k, v);
@@ -104,7 +105,7 @@ LL + }
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry_with_else.rs:46:5
+ --> $DIR/entry_with_else.rs:44:5
|
LL | / if m.contains_key(&k) {
LL | | if true { m.insert(k, v) } else { m.insert(k, v2) }
@@ -127,7 +128,7 @@ LL ~ };
|
error: usage of `contains_key` followed by `insert` on a `HashMap`
- --> $DIR/entry_with_else.rs:52:5
+ --> $DIR/entry_with_else.rs:50:5
|
LL | / if m.contains_key(&k) {
LL | | foo();
diff --git a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs
index abe42a230..c50404c50 100644
--- a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs
+++ b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs
@@ -1,4 +1,4 @@
-//@ignore-target-x86
+//@ignore-32bit
#![warn(clippy::enum_clike_unportable_variant)]
#![allow(unused, non_upper_case_globals)]
@@ -6,6 +6,8 @@
#[repr(usize)]
enum NonPortable {
X = 0x1_0000_0000,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
+ //~| NOTE: `-D clippy::enum-clike-unportable-variant` implied by `-D warnings`
Y = 0,
Z = 0x7FFF_FFFF,
A = 0xFFFF_FFFF,
@@ -13,9 +15,11 @@ enum NonPortable {
enum NonPortableNoHint {
X = 0x1_0000_0000,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
Y = 0,
Z = 0x7FFF_FFFF,
A = 0xFFFF_FFFF,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
}
#[repr(isize)]
@@ -23,21 +27,27 @@ enum NonPortableSigned {
X = -1,
Y = 0x7FFF_FFFF,
Z = 0xFFFF_FFFF,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
A = 0x1_0000_0000,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
B = i32::MIN as isize,
C = (i32::MIN as isize) - 1,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
}
enum NonPortableSignedNoHint {
X = -1,
Y = 0x7FFF_FFFF,
Z = 0xFFFF_FFFF,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
A = 0x1_0000_0000,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
}
#[repr(usize)]
enum NonPortable2 {
X = <usize as Trait>::Number,
+ //~^ ERROR: C-like enum variant discriminant is not portable to 32-bit targets
Y = 0,
}
diff --git a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.stderr b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.stderr
index 5935eea5e..93ad4daa9 100644
--- a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.stderr
+++ b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.stderr
@@ -5,51 +5,52 @@ LL | X = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::enum-clike-unportable-variant` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::enum_clike_unportable_variant)]`
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:15:5
+ --> $DIR/enum_clike_unportable_variant.rs:17:5
|
LL | X = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:18:5
+ --> $DIR/enum_clike_unportable_variant.rs:21:5
|
LL | A = 0xFFFF_FFFF,
| ^^^^^^^^^^^^^^^
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:25:5
+ --> $DIR/enum_clike_unportable_variant.rs:29:5
|
LL | Z = 0xFFFF_FFFF,
| ^^^^^^^^^^^^^^^
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:26:5
+ --> $DIR/enum_clike_unportable_variant.rs:31:5
|
LL | A = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:28:5
+ --> $DIR/enum_clike_unportable_variant.rs:34:5
|
LL | C = (i32::MIN as isize) - 1,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:34:5
+ --> $DIR/enum_clike_unportable_variant.rs:41:5
|
LL | Z = 0xFFFF_FFFF,
| ^^^^^^^^^^^^^^^
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:35:5
+ --> $DIR/enum_clike_unportable_variant.rs:43:5
|
LL | A = 0x1_0000_0000,
| ^^^^^^^^^^^^^^^^^
error: C-like enum variant discriminant is not portable to 32-bit targets
- --> $DIR/enum_clike_unportable_variant.rs:40:5
+ --> $DIR/enum_clike_unportable_variant.rs:49:5
|
LL | X = <usize as Trait>::Number,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/enum_glob_use.fixed b/src/tools/clippy/tests/ui/enum_glob_use.fixed
index 419370ffb..9044e8026 100644
--- a/src/tools/clippy/tests/ui/enum_glob_use.fixed
+++ b/src/tools/clippy/tests/ui/enum_glob_use.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::enum_glob_use)]
#![allow(unused)]
#![warn(unused_imports)]
diff --git a/src/tools/clippy/tests/ui/enum_glob_use.rs b/src/tools/clippy/tests/ui/enum_glob_use.rs
index 645ed9832..4f157a97c 100644
--- a/src/tools/clippy/tests/ui/enum_glob_use.rs
+++ b/src/tools/clippy/tests/ui/enum_glob_use.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::enum_glob_use)]
#![allow(unused)]
#![warn(unused_imports)]
diff --git a/src/tools/clippy/tests/ui/enum_glob_use.stderr b/src/tools/clippy/tests/ui/enum_glob_use.stderr
index 69531aed3..8b94e67f8 100644
--- a/src/tools/clippy/tests/ui/enum_glob_use.stderr
+++ b/src/tools/clippy/tests/ui/enum_glob_use.stderr
@@ -1,19 +1,20 @@
error: usage of wildcard import for enum variants
- --> $DIR/enum_glob_use.rs:7:5
+ --> $DIR/enum_glob_use.rs:5:5
|
LL | use std::cmp::Ordering::*;
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::cmp::Ordering::Less`
|
= note: `-D clippy::enum-glob-use` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::enum_glob_use)]`
error: usage of wildcard import for enum variants
- --> $DIR/enum_glob_use.rs:13:5
+ --> $DIR/enum_glob_use.rs:11:5
|
LL | use self::Enum::*;
| ^^^^^^^^^^^^^ help: try: `self::Enum::Foo`
error: usage of wildcard import for enum variants
- --> $DIR/enum_glob_use.rs:17:13
+ --> $DIR/enum_glob_use.rs:15:13
|
LL | use crate::Enum::*;
| ^^^^^^^^^^^^^^ help: try: `crate::Enum::Foo`
diff --git a/src/tools/clippy/tests/ui/enum_variants.rs b/src/tools/clippy/tests/ui/enum_variants.rs
index 531652a0e..85df852f7 100644
--- a/src/tools/clippy/tests/ui/enum_variants.rs
+++ b/src/tools/clippy/tests/ui/enum_variants.rs
@@ -12,7 +12,10 @@ enum FakeCallType2 {
}
enum Foo {
+ //~^ ERROR: all variants have the same prefix: `c`
cFoo,
+ //~^ ERROR: variant name ends with the enum's name
+ //~| NOTE: `-D clippy::enum-variant-names` implied by `-D warnings`
cBar,
cBaz,
}
@@ -23,9 +26,13 @@ enum Fooo {
}
enum Food {
+ //~^ ERROR: all variants have the same prefix: `Food`
FoodGood,
+ //~^ ERROR: variant name starts with the enum's name
FoodMiddle,
+ //~^ ERROR: variant name starts with the enum's name
FoodBad,
+ //~^ ERROR: variant name starts with the enum's name
}
enum Stuff {
@@ -33,6 +40,7 @@ enum Stuff {
}
enum BadCallType {
+ //~^ ERROR: all variants have the same prefix: `CallType`
CallTypeCall,
CallTypeCreate,
CallTypeDestroy,
@@ -45,6 +53,7 @@ enum TwoCallType {
}
enum Consts {
+ //~^ ERROR: all variants have the same prefix: `Constant`
ConstantInt,
ConstantCake,
ConstantLie,
@@ -57,6 +66,7 @@ enum Two {
}
enum Something {
+ //~^ ERROR: all variants have the same prefix: `C`
CCall,
CCreate,
CCryogenize,
@@ -79,6 +89,7 @@ enum Sealll {
}
enum Seallll {
+ //~^ ERROR: all variants have the same prefix: `WithOut`
WithOutCake,
WithOutTea,
WithOut,
@@ -134,12 +145,14 @@ pub enum NetworkLayer {
// should lint suggesting `IData`, not only `Data` (see #4639)
enum IDataRequest {
+ //~^ ERROR: all variants have the same postfix: `IData`
PutIData(String),
GetIData(String),
DeleteUnpubIData(String),
}
enum HIDataRequest {
+ //~^ ERROR: all variants have the same postfix: `HIData`
PutHIData(String),
GetHIData(String),
DeleteUnpubHIData(String),
@@ -160,6 +173,7 @@ enum Phase {
mod issue9018 {
enum DoLint {
+ //~^ ERROR: all variants have the same prefix: `_Type`
_TypeCreate,
_TypeRead,
_TypeUpdate,
@@ -167,6 +181,7 @@ mod issue9018 {
}
enum DoLintToo {
+ //~^ ERROR: all variants have the same postfix: `Type`
_CreateType,
_UpdateType,
_DeleteType,
diff --git a/src/tools/clippy/tests/ui/enum_variants.stderr b/src/tools/clippy/tests/ui/enum_variants.stderr
index 7342aff80..9ea80b635 100644
--- a/src/tools/clippy/tests/ui/enum_variants.stderr
+++ b/src/tools/clippy/tests/ui/enum_variants.stderr
@@ -1,17 +1,20 @@
error: variant name ends with the enum's name
- --> $DIR/enum_variants.rs:15:5
+ --> $DIR/enum_variants.rs:16:5
|
LL | cFoo,
| ^^^^
|
= note: `-D clippy::enum-variant-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`
error: all variants have the same prefix: `c`
--> $DIR/enum_variants.rs:14:1
|
LL | / enum Foo {
+LL | |
LL | | cFoo,
-LL | | cBar,
+LL | |
+... |
LL | | cBaz,
LL | | }
| |_^
@@ -19,39 +22,42 @@ LL | | }
= help: remove the prefixes and use full paths to the variants instead of glob imports
error: variant name starts with the enum's name
- --> $DIR/enum_variants.rs:26:5
+ --> $DIR/enum_variants.rs:30:5
|
LL | FoodGood,
| ^^^^^^^^
error: variant name starts with the enum's name
- --> $DIR/enum_variants.rs:27:5
+ --> $DIR/enum_variants.rs:32:5
|
LL | FoodMiddle,
| ^^^^^^^^^^
error: variant name starts with the enum's name
- --> $DIR/enum_variants.rs:28:5
+ --> $DIR/enum_variants.rs:34:5
|
LL | FoodBad,
| ^^^^^^^
error: all variants have the same prefix: `Food`
- --> $DIR/enum_variants.rs:25:1
+ --> $DIR/enum_variants.rs:28:1
|
LL | / enum Food {
+LL | |
LL | | FoodGood,
-LL | | FoodMiddle,
-LL | | FoodBad,
+LL | |
+... |
+LL | |
LL | | }
| |_^
|
= help: remove the prefixes and use full paths to the variants instead of glob imports
error: all variants have the same prefix: `CallType`
- --> $DIR/enum_variants.rs:35:1
+ --> $DIR/enum_variants.rs:42:1
|
LL | / enum BadCallType {
+LL | |
LL | | CallTypeCall,
LL | | CallTypeCreate,
LL | | CallTypeDestroy,
@@ -61,9 +67,10 @@ LL | | }
= help: remove the prefixes and use full paths to the variants instead of glob imports
error: all variants have the same prefix: `Constant`
- --> $DIR/enum_variants.rs:47:1
+ --> $DIR/enum_variants.rs:55:1
|
LL | / enum Consts {
+LL | |
LL | | ConstantInt,
LL | | ConstantCake,
LL | | ConstantLie,
@@ -73,9 +80,10 @@ LL | | }
= help: remove the prefixes and use full paths to the variants instead of glob imports
error: all variants have the same prefix: `C`
- --> $DIR/enum_variants.rs:59:1
+ --> $DIR/enum_variants.rs:68:1
|
LL | / enum Something {
+LL | |
LL | | CCall,
LL | | CCreate,
LL | | CCryogenize,
@@ -85,9 +93,10 @@ LL | | }
= help: remove the prefixes and use full paths to the variants instead of glob imports
error: all variants have the same prefix: `WithOut`
- --> $DIR/enum_variants.rs:81:1
+ --> $DIR/enum_variants.rs:91:1
|
LL | / enum Seallll {
+LL | |
LL | | WithOutCake,
LL | | WithOutTea,
LL | | WithOut,
@@ -97,9 +106,10 @@ LL | | }
= help: remove the prefixes and use full paths to the variants instead of glob imports
error: all variants have the same postfix: `IData`
- --> $DIR/enum_variants.rs:136:1
+ --> $DIR/enum_variants.rs:147:1
|
LL | / enum IDataRequest {
+LL | |
LL | | PutIData(String),
LL | | GetIData(String),
LL | | DeleteUnpubIData(String),
@@ -109,9 +119,10 @@ LL | | }
= help: remove the postfixes and use full paths to the variants instead of glob imports
error: all variants have the same postfix: `HIData`
- --> $DIR/enum_variants.rs:142:1
+ --> $DIR/enum_variants.rs:154:1
|
LL | / enum HIDataRequest {
+LL | |
LL | | PutHIData(String),
LL | | GetHIData(String),
LL | | DeleteUnpubHIData(String),
@@ -121,9 +132,10 @@ LL | | }
= help: remove the postfixes and use full paths to the variants instead of glob imports
error: all variants have the same prefix: `_Type`
- --> $DIR/enum_variants.rs:162:5
+ --> $DIR/enum_variants.rs:175:5
|
LL | / enum DoLint {
+LL | |
LL | | _TypeCreate,
LL | | _TypeRead,
LL | | _TypeUpdate,
@@ -134,9 +146,10 @@ LL | | }
= help: remove the prefixes and use full paths to the variants instead of glob imports
error: all variants have the same postfix: `Type`
- --> $DIR/enum_variants.rs:169:5
+ --> $DIR/enum_variants.rs:183:5
|
LL | / enum DoLintToo {
+LL | |
LL | | _CreateType,
LL | | _UpdateType,
LL | | _DeleteType,
diff --git a/src/tools/clippy/tests/ui/eprint_with_newline.fixed b/src/tools/clippy/tests/ui/eprint_with_newline.fixed
new file mode 100644
index 000000000..7383d784c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/eprint_with_newline.fixed
@@ -0,0 +1,69 @@
+#![allow(clippy::print_literal)]
+#![warn(clippy::print_with_newline)]
+
+fn main() {
+ eprintln!("Hello");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+ //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings`
+ eprintln!("Hello {}", "world");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+ eprintln!("Hello {} {}", "world", "#2");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+ eprintln!("{}", 1265);
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+ eprintln!();
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+
+ // these are all fine
+ eprint!("");
+ eprint!("Hello");
+ eprintln!("Hello");
+ eprintln!("Hello\n");
+ eprintln!("Hello {}\n", "world");
+ eprint!("Issue\n{}", 1265);
+ eprint!("{}", 1265);
+ eprint!("\n{}", 1275);
+ eprint!("\n\n");
+ eprint!("like eof\n\n");
+ eprint!("Hello {} {}\n\n", "world", "#2");
+ // #3126
+ eprintln!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n");
+ // #3126
+ eprintln!("\nbla\n\n");
+
+ // Escaping
+ // #3514
+ eprint!("\\n");
+ eprintln!("\\");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+ eprint!("\\\\n");
+
+ // Raw strings
+ // #3778
+ eprint!(r"\n");
+
+ // Literal newlines should also fail
+ eprintln!(
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+
+ );
+ eprintln!(
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+
+ );
+
+ // Don't warn on CRLF (#4208)
+ eprint!("\r\n");
+ eprint!("foo\r\n");
+ eprintln!("\\r");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+ eprint!("foo\rbar\n");
+
+ // Ignore expanded format strings
+ macro_rules! newline {
+ () => {
+ "\n"
+ };
+ }
+ eprint!(newline!());
+}
diff --git a/src/tools/clippy/tests/ui/eprint_with_newline.rs b/src/tools/clippy/tests/ui/eprint_with_newline.rs
index 8389806c8..5b1140564 100644
--- a/src/tools/clippy/tests/ui/eprint_with_newline.rs
+++ b/src/tools/clippy/tests/ui/eprint_with_newline.rs
@@ -3,10 +3,16 @@
fn main() {
eprint!("Hello\n");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
+ //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings`
eprint!("Hello {}\n", "world");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
eprint!("Hello {} {}\n", "world", "#2");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
eprint!("{}\n", 1265);
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
eprint!("\n");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
// these are all fine
eprint!("");
@@ -20,23 +26,30 @@ fn main() {
eprint!("\n\n");
eprint!("like eof\n\n");
eprint!("Hello {} {}\n\n", "world", "#2");
- eprintln!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
- eprintln!("\nbla\n\n"); // #3126
+ // #3126
+ eprintln!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n");
+ // #3126
+ eprintln!("\nbla\n\n");
// Escaping
- eprint!("\\n"); // #3514
- eprint!("\\\n"); // should fail
+ // #3514
+ eprint!("\\n");
+ eprint!("\\\n");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
eprint!("\\\\n");
// Raw strings
- eprint!(r"\n"); // #3778
+ // #3778
+ eprint!(r"\n");
// Literal newlines should also fail
eprint!(
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
"
"
);
eprint!(
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
r"
"
);
@@ -45,6 +58,7 @@ fn main() {
eprint!("\r\n");
eprint!("foo\r\n");
eprint!("\\r\n");
+ //~^ ERROR: using `eprint!()` with a format string that ends in a single newline
eprint!("foo\rbar\n");
// Ignore expanded format strings
diff --git a/src/tools/clippy/tests/ui/eprint_with_newline.stderr b/src/tools/clippy/tests/ui/eprint_with_newline.stderr
index 0a6bdf15d..674b4fdae 100644
--- a/src/tools/clippy/tests/ui/eprint_with_newline.stderr
+++ b/src/tools/clippy/tests/ui/eprint_with_newline.stderr
@@ -1,80 +1,82 @@
error: using `eprint!()` with a format string that ends in a single newline
--> $DIR/eprint_with_newline.rs:5:5
|
-LL | eprint!("Hello/n");
+LL | eprint!("Hello\n");
| ^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::print-with-newline` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_with_newline)]`
help: use `eprintln!` instead
|
-LL - eprint!("Hello/n");
+LL - eprint!("Hello\n");
LL + eprintln!("Hello");
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:6:5
+ --> $DIR/eprint_with_newline.rs:8:5
|
-LL | eprint!("Hello {}/n", "world");
+LL | eprint!("Hello {}\n", "world");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `eprintln!` instead
|
-LL - eprint!("Hello {}/n", "world");
+LL - eprint!("Hello {}\n", "world");
LL + eprintln!("Hello {}", "world");
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:7:5
+ --> $DIR/eprint_with_newline.rs:10:5
|
-LL | eprint!("Hello {} {}/n", "world", "#2");
+LL | eprint!("Hello {} {}\n", "world", "#2");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `eprintln!` instead
|
-LL - eprint!("Hello {} {}/n", "world", "#2");
+LL - eprint!("Hello {} {}\n", "world", "#2");
LL + eprintln!("Hello {} {}", "world", "#2");
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:8:5
+ --> $DIR/eprint_with_newline.rs:12:5
|
-LL | eprint!("{}/n", 1265);
+LL | eprint!("{}\n", 1265);
| ^^^^^^^^^^^^^^^^^^^^^
|
help: use `eprintln!` instead
|
-LL - eprint!("{}/n", 1265);
+LL - eprint!("{}\n", 1265);
LL + eprintln!("{}", 1265);
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:9:5
+ --> $DIR/eprint_with_newline.rs:14:5
|
-LL | eprint!("/n");
+LL | eprint!("\n");
| ^^^^^^^^^^^^^
|
help: use `eprintln!` instead
|
-LL - eprint!("/n");
+LL - eprint!("\n");
LL + eprintln!();
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:28:5
+ --> $DIR/eprint_with_newline.rs:37:5
|
-LL | eprint!("///n"); // should fail
+LL | eprint!("\\\n");
| ^^^^^^^^^^^^^^^
|
help: use `eprintln!` instead
|
-LL - eprint!("///n"); // should fail
-LL + eprintln!("//"); // should fail
+LL - eprint!("\\\n");
+LL + eprintln!("\\");
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:35:5
+ --> $DIR/eprint_with_newline.rs:46:5
|
LL | / eprint!(
+LL | |
LL | | "
LL | | "
LL | | );
@@ -83,13 +85,15 @@ LL | | );
help: use `eprintln!` instead
|
LL ~ eprintln!(
+LL |
LL ~
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:39:5
+ --> $DIR/eprint_with_newline.rs:51:5
|
LL | / eprint!(
+LL | |
LL | | r"
LL | | "
LL | | );
@@ -98,19 +102,20 @@ LL | | );
help: use `eprintln!` instead
|
LL ~ eprintln!(
+LL |
LL ~
|
error: using `eprint!()` with a format string that ends in a single newline
- --> $DIR/eprint_with_newline.rs:47:5
+ --> $DIR/eprint_with_newline.rs:60:5
|
-LL | eprint!("//r/n");
+LL | eprint!("\\r\n");
| ^^^^^^^^^^^^^^^^
|
help: use `eprintln!` instead
|
-LL - eprint!("//r/n");
-LL + eprintln!("//r");
+LL - eprint!("\\r\n");
+LL + eprintln!("\\r");
|
error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/eq_op.rs b/src/tools/clippy/tests/ui/eq_op.rs
index e973e5ba2..7c2c13187 100644
--- a/src/tools/clippy/tests/ui/eq_op.rs
+++ b/src/tools/clippy/tests/ui/eq_op.rs
@@ -5,51 +5,80 @@
fn main() {
// simple values and comparisons
let _ = 1 == 1;
+ //~^ ERROR: equal expressions as operands to `==`
+ //~| NOTE: `-D clippy::eq-op` implied by `-D warnings`
let _ = "no" == "no";
+ //~^ ERROR: equal expressions as operands to `==`
// even though I agree that no means no ;-)
let _ = false != false;
+ //~^ ERROR: equal expressions as operands to `!=`
let _ = 1.5 < 1.5;
+ //~^ ERROR: equal expressions as operands to `<`
let _ = 1u64 >= 1u64;
+ //~^ ERROR: equal expressions as operands to `>=`
let x = f32::NAN;
let _ = x != x;
+ //~^ ERROR: equal expressions as operands to `!=`
+ //~| NOTE: if you intended to check if the operand is NaN, use `.is_nan()` instead
// casts, methods, parentheses
let _ = (1u32 as u64) & (1u32 as u64);
+ //~^ ERROR: equal expressions as operands to `&`
#[rustfmt::skip]
{
let _ = 1 ^ ((((((1))))));
+ //~^ ERROR: equal expressions as operands to `^`
};
// unary and binary operators
let _ = (-(2) < -(2));
+ //~^ ERROR: equal expressions as operands to `<`
let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
+ //~^ ERROR: equal expressions as operands to `==`
+ //~| ERROR: equal expressions as operands to `&`
+ //~| ERROR: equal expressions as operands to `&`
let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4;
+ //~^ ERROR: equal expressions as operands to `==`
// various other things
let _ = ([1] != [1]);
+ //~^ ERROR: equal expressions as operands to `!=`
let _ = ((1, 2) != (1, 2));
+ //~^ ERROR: equal expressions as operands to `!=`
let _ = vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros
// const folding
let _ = 1 + 1 == 2;
+ //~^ ERROR: equal expressions as operands to `==`
let _ = 1 - 1 == 0;
+ //~^ ERROR: equal expressions as operands to `==`
+ //~| ERROR: equal expressions as operands to `-`
let _ = 1 - 1;
+ //~^ ERROR: equal expressions as operands to `-`
let _ = 1 / 1;
+ //~^ ERROR: equal expressions as operands to `/`
let _ = true && true;
+ //~^ ERROR: equal expressions as operands to `&&`
let _ = true || true;
+ //~^ ERROR: equal expressions as operands to `||`
let a: u32 = 0;
let b: u32 = 0;
let _ = a == b && b == a;
+ //~^ ERROR: equal expressions as operands to `&&`
let _ = a != b && b != a;
+ //~^ ERROR: equal expressions as operands to `&&`
let _ = a < b && b > a;
+ //~^ ERROR: equal expressions as operands to `&&`
let _ = a <= b && b >= a;
+ //~^ ERROR: equal expressions as operands to `&&`
let mut a = vec![1];
let _ = a == a;
+ //~^ ERROR: equal expressions as operands to `==`
let _ = 2 * a.len() == 2 * a.len(); // ok, functions
let _ = a.pop() == a.pop(); // ok, functions
@@ -60,6 +89,7 @@ fn main() {
const B: u32 = 10;
const C: u32 = A / B; // ok, different named constants
const D: u32 = A / A;
+ //~^ ERROR: equal expressions as operands to `/`
}
macro_rules! check_if_named_foo {
@@ -91,6 +121,7 @@ struct Nested {
fn check_nested(n1: &Nested, n2: &Nested) -> bool {
// `n2.inner.0.0` mistyped as `n1.inner.0.0`
(n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
+ //~^ ERROR: equal expressions as operands to `==`
}
#[test]
diff --git a/src/tools/clippy/tests/ui/eq_op.stderr b/src/tools/clippy/tests/ui/eq_op.stderr
index c7fa253bd..2427ac0dd 100644
--- a/src/tools/clippy/tests/ui/eq_op.stderr
+++ b/src/tools/clippy/tests/ui/eq_op.stderr
@@ -5,33 +5,34 @@ LL | let _ = 1 == 1;
| ^^^^^^
|
= note: `-D clippy::eq-op` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::eq_op)]`
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:8:13
+ --> $DIR/eq_op.rs:10:13
|
LL | let _ = "no" == "no";
| ^^^^^^^^^^^^
error: equal expressions as operands to `!=`
- --> $DIR/eq_op.rs:10:13
+ --> $DIR/eq_op.rs:13:13
|
LL | let _ = false != false;
| ^^^^^^^^^^^^^^
error: equal expressions as operands to `<`
- --> $DIR/eq_op.rs:11:13
+ --> $DIR/eq_op.rs:15:13
|
LL | let _ = 1.5 < 1.5;
| ^^^^^^^^^
error: equal expressions as operands to `>=`
- --> $DIR/eq_op.rs:12:13
+ --> $DIR/eq_op.rs:17:13
|
LL | let _ = 1u64 >= 1u64;
| ^^^^^^^^^^^^
error: equal expressions as operands to `!=`
- --> $DIR/eq_op.rs:14:13
+ --> $DIR/eq_op.rs:20:13
|
LL | let _ = x != x;
| ^^^^^^
@@ -39,139 +40,139 @@ LL | let _ = x != x;
= note: if you intended to check if the operand is NaN, use `.is_nan()` instead
error: equal expressions as operands to `&`
- --> $DIR/eq_op.rs:17:13
+ --> $DIR/eq_op.rs:25:13
|
LL | let _ = (1u32 as u64) & (1u32 as u64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `^`
- --> $DIR/eq_op.rs:20:17
+ --> $DIR/eq_op.rs:29:17
|
LL | let _ = 1 ^ ((((((1))))));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `<`
- --> $DIR/eq_op.rs:24:13
+ --> $DIR/eq_op.rs:34:13
|
LL | let _ = (-(2) < -(2));
| ^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:25:13
+ --> $DIR/eq_op.rs:36:13
|
LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&`
- --> $DIR/eq_op.rs:25:14
+ --> $DIR/eq_op.rs:36:14
|
LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&`
- --> $DIR/eq_op.rs:25:35
+ --> $DIR/eq_op.rs:36:35
|
LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:26:13
+ --> $DIR/eq_op.rs:40:13
|
LL | let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `!=`
- --> $DIR/eq_op.rs:29:13
+ --> $DIR/eq_op.rs:44:13
|
LL | let _ = ([1] != [1]);
| ^^^^^^^^^^^^
error: equal expressions as operands to `!=`
- --> $DIR/eq_op.rs:30:13
+ --> $DIR/eq_op.rs:46:13
|
LL | let _ = ((1, 2) != (1, 2));
| ^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:34:13
+ --> $DIR/eq_op.rs:51:13
|
LL | let _ = 1 + 1 == 2;
| ^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:35:13
+ --> $DIR/eq_op.rs:53:13
|
LL | let _ = 1 - 1 == 0;
| ^^^^^^^^^^
error: equal expressions as operands to `-`
- --> $DIR/eq_op.rs:35:13
+ --> $DIR/eq_op.rs:53:13
|
LL | let _ = 1 - 1 == 0;
| ^^^^^
error: equal expressions as operands to `-`
- --> $DIR/eq_op.rs:37:13
+ --> $DIR/eq_op.rs:57:13
|
LL | let _ = 1 - 1;
| ^^^^^
error: equal expressions as operands to `/`
- --> $DIR/eq_op.rs:38:13
+ --> $DIR/eq_op.rs:59:13
|
LL | let _ = 1 / 1;
| ^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:39:13
+ --> $DIR/eq_op.rs:61:13
|
LL | let _ = true && true;
| ^^^^^^^^^^^^
error: equal expressions as operands to `||`
- --> $DIR/eq_op.rs:41:13
+ --> $DIR/eq_op.rs:64:13
|
LL | let _ = true || true;
| ^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:46:13
+ --> $DIR/eq_op.rs:70:13
|
LL | let _ = a == b && b == a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:47:13
+ --> $DIR/eq_op.rs:72:13
|
LL | let _ = a != b && b != a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:48:13
+ --> $DIR/eq_op.rs:74:13
|
LL | let _ = a < b && b > a;
| ^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:49:13
+ --> $DIR/eq_op.rs:76:13
|
LL | let _ = a <= b && b >= a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:52:13
+ --> $DIR/eq_op.rs:80:13
|
LL | let _ = a == a;
| ^^^^^^
error: equal expressions as operands to `/`
- --> $DIR/eq_op.rs:62:20
+ --> $DIR/eq_op.rs:91:20
|
LL | const D: u32 = A / A;
| ^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:93:5
+ --> $DIR/eq_op.rs:123:5
|
LL | (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/eq_op_macros.rs b/src/tools/clippy/tests/ui/eq_op_macros.rs
index 482406772..a511af4a3 100644
--- a/src/tools/clippy/tests/ui/eq_op_macros.rs
+++ b/src/tools/clippy/tests/ui/eq_op_macros.rs
@@ -21,7 +21,9 @@ fn main() {
// lint identical args in `assert_eq!`
assert_eq!(a, a);
+ //~^ ERROR: identical args used in this `assert_eq!` macro call
assert_eq!(a + 1, a + 1);
+ //~^ ERROR: identical args used in this `assert_eq!` macro call
// ok
assert_eq!(a, b);
assert_eq!(a, a + 1);
@@ -29,7 +31,9 @@ fn main() {
// lint identical args in `assert_ne!`
assert_ne!(a, a);
+ //~^ ERROR: identical args used in this `assert_ne!` macro call
assert_ne!(a + 1, a + 1);
+ //~^ ERROR: identical args used in this `assert_ne!` macro call
// ok
assert_ne!(a, b);
assert_ne!(a, a + 1);
@@ -37,7 +41,9 @@ fn main() {
// lint identical args in `debug_assert_eq!`
debug_assert_eq!(a, a);
+ //~^ ERROR: identical args used in this `debug_assert_eq!` macro call
debug_assert_eq!(a + 1, a + 1);
+ //~^ ERROR: identical args used in this `debug_assert_eq!` macro call
// ok
debug_assert_eq!(a, b);
debug_assert_eq!(a, a + 1);
@@ -45,7 +51,9 @@ fn main() {
// lint identical args in `debug_assert_ne!`
debug_assert_ne!(a, a);
+ //~^ ERROR: identical args used in this `debug_assert_ne!` macro call
debug_assert_ne!(a + 1, a + 1);
+ //~^ ERROR: identical args used in this `debug_assert_ne!` macro call
// ok
debug_assert_ne!(a, b);
debug_assert_ne!(a, a + 1);
diff --git a/src/tools/clippy/tests/ui/eq_op_macros.stderr b/src/tools/clippy/tests/ui/eq_op_macros.stderr
index cb9b0c018..0df26607a 100644
--- a/src/tools/clippy/tests/ui/eq_op_macros.stderr
+++ b/src/tools/clippy/tests/ui/eq_op_macros.stderr
@@ -8,6 +8,7 @@ LL | assert_in_macro_def!();
| ---------------------- in this macro invocation
|
= note: `-D clippy::eq-op` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::eq_op)]`
= note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info)
error: identical args used in this `assert_ne!` macro call
@@ -50,43 +51,43 @@ LL | assert_eq!(a, a);
| ^^^^
error: identical args used in this `assert_eq!` macro call
- --> $DIR/eq_op_macros.rs:24:16
+ --> $DIR/eq_op_macros.rs:25:16
|
LL | assert_eq!(a + 1, a + 1);
| ^^^^^^^^^^^^
error: identical args used in this `assert_ne!` macro call
- --> $DIR/eq_op_macros.rs:31:16
+ --> $DIR/eq_op_macros.rs:33:16
|
LL | assert_ne!(a, a);
| ^^^^
error: identical args used in this `assert_ne!` macro call
- --> $DIR/eq_op_macros.rs:32:16
+ --> $DIR/eq_op_macros.rs:35:16
|
LL | assert_ne!(a + 1, a + 1);
| ^^^^^^^^^^^^
error: identical args used in this `debug_assert_eq!` macro call
- --> $DIR/eq_op_macros.rs:39:22
+ --> $DIR/eq_op_macros.rs:43:22
|
LL | debug_assert_eq!(a, a);
| ^^^^
error: identical args used in this `debug_assert_eq!` macro call
- --> $DIR/eq_op_macros.rs:40:22
+ --> $DIR/eq_op_macros.rs:45:22
|
LL | debug_assert_eq!(a + 1, a + 1);
| ^^^^^^^^^^^^
error: identical args used in this `debug_assert_ne!` macro call
- --> $DIR/eq_op_macros.rs:47:22
+ --> $DIR/eq_op_macros.rs:53:22
|
LL | debug_assert_ne!(a, a);
| ^^^^
error: identical args used in this `debug_assert_ne!` macro call
- --> $DIR/eq_op_macros.rs:48:22
+ --> $DIR/eq_op_macros.rs:55:22
|
LL | debug_assert_ne!(a + 1, a + 1);
| ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/equatable_if_let.fixed b/src/tools/clippy/tests/ui/equatable_if_let.fixed
index 6cc070fb5..2b523e1e1 100644
--- a/src/tools/clippy/tests/ui/equatable_if_let.fixed
+++ b/src/tools/clippy/tests/ui/equatable_if_let.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(
unused_variables,
diff --git a/src/tools/clippy/tests/ui/equatable_if_let.rs b/src/tools/clippy/tests/ui/equatable_if_let.rs
index f00a129be..f7e3bb296 100644
--- a/src/tools/clippy/tests/ui/equatable_if_let.rs
+++ b/src/tools/clippy/tests/ui/equatable_if_let.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(
unused_variables,
diff --git a/src/tools/clippy/tests/ui/equatable_if_let.stderr b/src/tools/clippy/tests/ui/equatable_if_let.stderr
index 649495dde..6cc19d829 100644
--- a/src/tools/clippy/tests/ui/equatable_if_let.stderr
+++ b/src/tools/clippy/tests/ui/equatable_if_let.stderr
@@ -1,85 +1,86 @@
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:65:8
+ --> $DIR/equatable_if_let.rs:64:8
|
LL | if let 2 = a {}
| ^^^^^^^^^ help: try: `a == 2`
|
= note: `-D clippy::equatable-if-let` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::equatable_if_let)]`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:66:8
+ --> $DIR/equatable_if_let.rs:65:8
|
LL | if let Ordering::Greater = a.cmp(&b) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:67:8
+ --> $DIR/equatable_if_let.rs:66:8
|
LL | if let Some(2) = c {}
| ^^^^^^^^^^^^^^^ help: try: `c == Some(2)`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:68:8
+ --> $DIR/equatable_if_let.rs:67:8
|
LL | if let Struct { a: 2, b: false } = d {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:69:8
+ --> $DIR/equatable_if_let.rs:68:8
|
LL | if let Enum::TupleVariant(32, 64) = e {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:70:8
+ --> $DIR/equatable_if_let.rs:69:8
|
LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:71:8
+ --> $DIR/equatable_if_let.rs:70:8
|
LL | if let Enum::UnitVariant = e {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:72:8
+ --> $DIR/equatable_if_let.rs:71:8
|
LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })`
error: this pattern matching can be expressed using `matches!`
- --> $DIR/equatable_if_let.rs:81:8
+ --> $DIR/equatable_if_let.rs:80:8
|
LL | if let NotPartialEq::A = f {}
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:82:8
+ --> $DIR/equatable_if_let.rs:81:8
|
LL | if let NotStructuralEq::A = g {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A`
error: this pattern matching can be expressed using `matches!`
- --> $DIR/equatable_if_let.rs:83:8
+ --> $DIR/equatable_if_let.rs:82:8
|
LL | if let Some(NotPartialEq::A) = Some(f) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:84:8
+ --> $DIR/equatable_if_let.rs:83:8
|
LL | if let Some(NotStructuralEq::A) = Some(g) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)`
error: this pattern matching can be expressed using `matches!`
- --> $DIR/equatable_if_let.rs:85:8
+ --> $DIR/equatable_if_let.rs:84:8
|
LL | if let NoPartialEqStruct { a: 2, b: false } = h {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:87:8
+ --> $DIR/equatable_if_let.rs:86:8
|
LL | if let inline!("abc") = "abc" {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")`
diff --git a/src/tools/clippy/tests/ui/erasing_op.rs b/src/tools/clippy/tests/ui/erasing_op.rs
index 74985029e..00c74f23f 100644
--- a/src/tools/clippy/tests/ui/erasing_op.rs
+++ b/src/tools/clippy/tests/ui/erasing_op.rs
@@ -33,11 +33,17 @@ impl core::ops::Mul<i32> for Vec1 {
#[warn(clippy::erasing_op)]
fn test(x: u8) {
x * 0;
+ //~^ ERROR: this operation will always return zero. This is likely not the intended ou
+ //~| NOTE: `-D clippy::erasing-op` implied by `-D warnings`
0 & x;
+ //~^ ERROR: this operation will always return zero. This is likely not the intended ou
0 / x;
+ //~^ ERROR: this operation will always return zero. This is likely not the intended ou
0 * Meter; // no error: Output type is different from the non-zero argument
0 * Vec1 { x: 5 };
+ //~^ ERROR: this operation will always return zero. This is likely not the intended ou
Vec1 { x: 5 } * 0;
+ //~^ ERROR: this operation will always return zero. This is likely not the intended ou
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/erasing_op.stderr b/src/tools/clippy/tests/ui/erasing_op.stderr
index 979412523..1b50a05cd 100644
--- a/src/tools/clippy/tests/ui/erasing_op.stderr
+++ b/src/tools/clippy/tests/ui/erasing_op.stderr
@@ -5,27 +5,28 @@ LL | x * 0;
| ^^^^^
|
= note: `-D clippy::erasing-op` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::erasing_op)]`
error: this operation will always return zero. This is likely not the intended outcome
- --> $DIR/erasing_op.rs:36:5
+ --> $DIR/erasing_op.rs:38:5
|
LL | 0 & x;
| ^^^^^
error: this operation will always return zero. This is likely not the intended outcome
- --> $DIR/erasing_op.rs:37:5
+ --> $DIR/erasing_op.rs:40:5
|
LL | 0 / x;
| ^^^^^
error: this operation will always return zero. This is likely not the intended outcome
- --> $DIR/erasing_op.rs:39:5
+ --> $DIR/erasing_op.rs:43:5
|
LL | 0 * Vec1 { x: 5 };
| ^^^^^^^^^^^^^^^^^
error: this operation will always return zero. This is likely not the intended outcome
- --> $DIR/erasing_op.rs:40:5
+ --> $DIR/erasing_op.rs:45:5
|
LL | Vec1 { x: 5 } * 0;
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/err_expect.fixed b/src/tools/clippy/tests/ui/err_expect.fixed
index 46e2816da..abbc6dbeb 100644
--- a/src/tools/clippy/tests/ui/err_expect.fixed
+++ b/src/tools/clippy/tests/ui/err_expect.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::unnecessary_literal_unwrap)]
struct MyTypeNonDebug;
diff --git a/src/tools/clippy/tests/ui/err_expect.rs b/src/tools/clippy/tests/ui/err_expect.rs
index b9446034d..0c7ad185d 100644
--- a/src/tools/clippy/tests/ui/err_expect.rs
+++ b/src/tools/clippy/tests/ui/err_expect.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::unnecessary_literal_unwrap)]
struct MyTypeNonDebug;
diff --git a/src/tools/clippy/tests/ui/err_expect.stderr b/src/tools/clippy/tests/ui/err_expect.stderr
index 82c0754cf..da7cd47f0 100644
--- a/src/tools/clippy/tests/ui/err_expect.stderr
+++ b/src/tools/clippy/tests/ui/err_expect.stderr
@@ -1,13 +1,14 @@
error: called `.err().expect()` on a `Result` value
- --> $DIR/err_expect.rs:12:16
+ --> $DIR/err_expect.rs:10:16
|
LL | test_debug.err().expect("Testing debug type");
| ^^^^^^^^^^^^ help: try: `expect_err`
|
= note: `-D clippy::err-expect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::err_expect)]`
error: called `.err().expect()` on a `Result` value
- --> $DIR/err_expect.rs:27:7
+ --> $DIR/err_expect.rs:25:7
|
LL | x.err().expect("17");
| ^^^^^^^^^^^^ help: try: `expect_err`
diff --git a/src/tools/clippy/tests/ui/error_impl_error.rs b/src/tools/clippy/tests/ui/error_impl_error.rs
index 40ce4181b..05003f7d0 100644
--- a/src/tools/clippy/tests/ui/error_impl_error.rs
+++ b/src/tools/clippy/tests/ui/error_impl_error.rs
@@ -5,6 +5,7 @@
pub mod a {
#[derive(Debug)]
pub struct Error;
+ //~^ ERROR: exported type named `Error` that implements `Error`
impl std::fmt::Display for Error {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -18,6 +19,7 @@ pub mod a {
mod b {
#[derive(Debug)]
pub(super) enum Error {}
+ //~^ ERROR: exported type named `Error` that implements `Error`
impl std::fmt::Display for Error {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -30,6 +32,7 @@ mod b {
pub mod c {
pub union Error {
+ //~^ ERROR: exported type named `Error` that implements `Error`
a: u32,
b: u32,
}
@@ -51,6 +54,7 @@ pub mod c {
pub mod d {
pub type Error = std::fmt::Error;
+ //~^ ERROR: exported type alias named `Error` that implements `Error`
}
mod e {
diff --git a/src/tools/clippy/tests/ui/error_impl_error.stderr b/src/tools/clippy/tests/ui/error_impl_error.stderr
index f3e04b641..d7a1aa829 100644
--- a/src/tools/clippy/tests/ui/error_impl_error.stderr
+++ b/src/tools/clippy/tests/ui/error_impl_error.stderr
@@ -5,38 +5,39 @@ LL | pub struct Error;
| ^^^^^
|
note: `Error` was implemented here
- --> $DIR/error_impl_error.rs:15:5
+ --> $DIR/error_impl_error.rs:16:5
|
LL | impl std::error::Error for Error {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::error-impl-error` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::error_impl_error)]`
error: exported type named `Error` that implements `Error`
- --> $DIR/error_impl_error.rs:20:21
+ --> $DIR/error_impl_error.rs:21:21
|
LL | pub(super) enum Error {}
| ^^^^^
|
note: `Error` was implemented here
- --> $DIR/error_impl_error.rs:28:5
+ --> $DIR/error_impl_error.rs:30:5
|
LL | impl std::error::Error for Error {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: exported type named `Error` that implements `Error`
- --> $DIR/error_impl_error.rs:32:15
+ --> $DIR/error_impl_error.rs:34:15
|
LL | pub union Error {
| ^^^^^
|
note: `Error` was implemented here
- --> $DIR/error_impl_error.rs:49:5
+ --> $DIR/error_impl_error.rs:52:5
|
LL | impl std::error::Error for Error {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: exported type alias named `Error` that implements `Error`
- --> $DIR/error_impl_error.rs:53:14
+ --> $DIR/error_impl_error.rs:56:14
|
LL | pub type Error = std::fmt::Error;
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index ddabe7616..32c7499bf 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#![allow(unused)]
#![allow(
@@ -8,7 +7,8 @@
clippy::option_map_unit_fn,
clippy::redundant_closure_call,
clippy::uninlined_format_args,
- clippy::useless_vec
+ clippy::useless_vec,
+ clippy::unnecessary_map_on_constructor
)]
use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index 92ecff6eb..25b7431ba 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
#![allow(unused)]
#![allow(
@@ -8,7 +7,8 @@
clippy::option_map_unit_fn,
clippy::redundant_closure_call,
clippy::uninlined_format_args,
- clippy::useless_vec
+ clippy::useless_vec,
+ clippy::unnecessary_map_on_constructor
)]
use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index ff40a2074..951e4ac74 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -5,6 +5,7 @@ LL | let a = Some(1u8).map(|a| foo(a));
| ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
|
= note: `-D clippy::redundant-closure` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
error: redundant closure
--> $DIR/eta.rs:33:40
@@ -37,6 +38,7 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
| ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
|
= note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]`
error: redundant closure
--> $DIR/eta.rs:95:51
diff --git a/src/tools/clippy/tests/ui/excessive_precision.fixed b/src/tools/clippy/tests/ui/excessive_precision.fixed
index 7bb4da453..cc5531035 100644
--- a/src/tools/clippy/tests/ui/excessive_precision.fixed
+++ b/src/tools/clippy/tests/ui/excessive_precision.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::excessive_precision)]
#![allow(
dead_code,
diff --git a/src/tools/clippy/tests/ui/excessive_precision.rs b/src/tools/clippy/tests/ui/excessive_precision.rs
index e8d6ab687..fff986a82 100644
--- a/src/tools/clippy/tests/ui/excessive_precision.rs
+++ b/src/tools/clippy/tests/ui/excessive_precision.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::excessive_precision)]
#![allow(
dead_code,
diff --git a/src/tools/clippy/tests/ui/excessive_precision.stderr b/src/tools/clippy/tests/ui/excessive_precision.stderr
index 348ad183d..5e7672e18 100644
--- a/src/tools/clippy/tests/ui/excessive_precision.stderr
+++ b/src/tools/clippy/tests/ui/excessive_precision.stderr
@@ -1,91 +1,92 @@
error: float has excessive precision
- --> $DIR/excessive_precision.rs:21:26
+ --> $DIR/excessive_precision.rs:20:26
|
LL | const BAD32_1: f32 = 0.123_456_789_f32;
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79_f32`
|
= note: `-D clippy::excessive-precision` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::excessive_precision)]`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:22:26
+ --> $DIR/excessive_precision.rs:21:26
|
LL | const BAD32_2: f32 = 0.123_456_789;
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:23:26
+ --> $DIR/excessive_precision.rs:22:26
|
LL | const BAD32_3: f32 = 0.100_000_000_000_1;
| ^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:24:29
+ --> $DIR/excessive_precision.rs:23:29
|
LL | const BAD32_EDGE: f32 = 1.000_000_9;
| ^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.000_001`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:28:26
+ --> $DIR/excessive_precision.rs:27:26
|
LL | const BAD64_3: f64 = 0.100_000_000_000_000_000_1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:31:22
+ --> $DIR/excessive_precision.rs:30:22
|
LL | println!("{:?}", 8.888_888_888_888_888_888_888);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:42:22
+ --> $DIR/excessive_precision.rs:41:22
|
LL | let bad32: f32 = 1.123_456_789;
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:43:26
+ --> $DIR/excessive_precision.rs:42:26
|
LL | let bad32_suf: f32 = 1.123_456_789_f32;
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8_f32`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:44:21
+ --> $DIR/excessive_precision.rs:43:21
|
LL | let bad32_inf = 1.123_456_789_f32;
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8_f32`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:54:36
+ --> $DIR/excessive_precision.rs:53:36
|
LL | let bad_vec32: Vec<f32> = vec![0.123_456_789];
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:55:36
+ --> $DIR/excessive_precision.rs:54:36
|
LL | let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_123_456_78`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:59:24
+ --> $DIR/excessive_precision.rs:58:24
|
LL | let bad_e32: f32 = 1.123_456_788_888e-10;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8e-10`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:62:27
+ --> $DIR/excessive_precision.rs:61:27
|
LL | let bad_bige32: f32 = 1.123_456_788_888E-10;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8E-10`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:71:13
+ --> $DIR/excessive_precision.rs:70:13
|
LL | let _ = 2.225_073_858_507_201_1e-308_f64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `2.225_073_858_507_201e-308_f64`
error: float has excessive precision
- --> $DIR/excessive_precision.rs:74:13
+ --> $DIR/excessive_precision.rs:73:13
|
LL | let _ = 1.000_000_000_000_001e-324_f64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0_f64`
diff --git a/src/tools/clippy/tests/ui/exhaustive_items.fixed b/src/tools/clippy/tests/ui/exhaustive_items.fixed
index 6c7b1cab6..1bf33a5f2 100644
--- a/src/tools/clippy/tests/ui/exhaustive_items.fixed
+++ b/src/tools/clippy/tests/ui/exhaustive_items.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/exhaustive_items.rs b/src/tools/clippy/tests/ui/exhaustive_items.rs
index d205bac2d..1328791e1 100644
--- a/src/tools/clippy/tests/ui/exhaustive_items.rs
+++ b/src/tools/clippy/tests/ui/exhaustive_items.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/exhaustive_items.stderr b/src/tools/clippy/tests/ui/exhaustive_items.stderr
index f46ebd477..ae43e81c0 100644
--- a/src/tools/clippy/tests/ui/exhaustive_items.stderr
+++ b/src/tools/clippy/tests/ui/exhaustive_items.stderr
@@ -1,5 +1,5 @@
error: exported enums should not be exhaustive
- --> $DIR/exhaustive_items.rs:11:5
+ --> $DIR/exhaustive_items.rs:9:5
|
LL | / pub enum Exhaustive {
LL | | Foo,
@@ -10,7 +10,7 @@ LL | | }
| |_____^
|
note: the lint level is defined here
- --> $DIR/exhaustive_items.rs:3:9
+ --> $DIR/exhaustive_items.rs:1:9
|
LL | #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -21,7 +21,7 @@ LL ~ pub enum Exhaustive {
|
error: exported enums should not be exhaustive
- --> $DIR/exhaustive_items.rs:20:5
+ --> $DIR/exhaustive_items.rs:18:5
|
LL | / pub enum ExhaustiveWithAttrs {
LL | | Foo,
@@ -38,7 +38,7 @@ LL ~ pub enum ExhaustiveWithAttrs {
|
error: exported structs should not be exhaustive
- --> $DIR/exhaustive_items.rs:55:5
+ --> $DIR/exhaustive_items.rs:53:5
|
LL | / pub struct Exhaustive {
LL | | pub foo: u8,
@@ -47,7 +47,7 @@ LL | | }
| |_____^
|
note: the lint level is defined here
- --> $DIR/exhaustive_items.rs:3:35
+ --> $DIR/exhaustive_items.rs:1:35
|
LL | #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/exit1.rs b/src/tools/clippy/tests/ui/exit1.rs
index 4eac6eb74..a89f6dd4c 100644
--- a/src/tools/clippy/tests/ui/exit1.rs
+++ b/src/tools/clippy/tests/ui/exit1.rs
@@ -3,6 +3,8 @@
fn not_main() {
if true {
std::process::exit(4);
+ //~^ ERROR: usage of `process::exit`
+ //~| NOTE: `-D clippy::exit` implied by `-D warnings`
}
}
diff --git a/src/tools/clippy/tests/ui/exit1.stderr b/src/tools/clippy/tests/ui/exit1.stderr
index a8d3956aa..94d8f1e32 100644
--- a/src/tools/clippy/tests/ui/exit1.stderr
+++ b/src/tools/clippy/tests/ui/exit1.stderr
@@ -5,6 +5,7 @@ LL | std::process::exit(4);
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::exit` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::exit)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/exit2.rs b/src/tools/clippy/tests/ui/exit2.rs
index 4b693ed70..d5ff93fb9 100644
--- a/src/tools/clippy/tests/ui/exit2.rs
+++ b/src/tools/clippy/tests/ui/exit2.rs
@@ -2,6 +2,8 @@
fn also_not_main() {
std::process::exit(3);
+ //~^ ERROR: usage of `process::exit`
+ //~| NOTE: `-D clippy::exit` implied by `-D warnings`
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/exit2.stderr b/src/tools/clippy/tests/ui/exit2.stderr
index 7263e156a..cd324f182 100644
--- a/src/tools/clippy/tests/ui/exit2.stderr
+++ b/src/tools/clippy/tests/ui/exit2.stderr
@@ -5,6 +5,7 @@ LL | std::process::exit(3);
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::exit` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::exit)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/expect.rs b/src/tools/clippy/tests/ui/expect.rs
index 1588579bb..f15b3d37e 100644
--- a/src/tools/clippy/tests/ui/expect.rs
+++ b/src/tools/clippy/tests/ui/expect.rs
@@ -4,12 +4,15 @@
fn expect_option() {
let opt = Some(0);
let _ = opt.expect("");
+ //~^ ERROR: used `expect()` on an `Option` value
}
fn expect_result() {
let res: Result<u8, u8> = Ok(0);
let _ = res.expect("");
+ //~^ ERROR: used `expect()` on a `Result` value
let _ = res.expect_err("");
+ //~^ ERROR: used `expect_err()` on a `Result` value
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/expect.stderr b/src/tools/clippy/tests/ui/expect.stderr
index f787fa973..35a258a85 100644
--- a/src/tools/clippy/tests/ui/expect.stderr
+++ b/src/tools/clippy/tests/ui/expect.stderr
@@ -6,9 +6,10 @@ LL | let _ = opt.expect("");
|
= note: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::expect_used)]`
error: used `expect()` on a `Result` value
- --> $DIR/expect.rs:11:13
+ --> $DIR/expect.rs:12:13
|
LL | let _ = res.expect("");
| ^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let _ = res.expect("");
= note: if this value is an `Err`, it will panic
error: used `expect_err()` on a `Result` value
- --> $DIR/expect.rs:12:13
+ --> $DIR/expect.rs:14:13
|
LL | let _ = res.expect_err("");
| ^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.fixed b/src/tools/clippy/tests/ui/expect_fun_call.fixed
index 73c6c97de..6ac3c43ad 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/expect_fun_call.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::expect_fun_call)]
#![allow(
clippy::to_string_in_format_args,
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.rs b/src/tools/clippy/tests/ui/expect_fun_call.rs
index a78613863..22ea2db50 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.rs
+++ b/src/tools/clippy/tests/ui/expect_fun_call.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::expect_fun_call)]
#![allow(
clippy::to_string_in_format_args,
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.stderr b/src/tools/clippy/tests/ui/expect_fun_call.stderr
index a621f681d..dd3976f36 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/expect_fun_call.stderr
@@ -1,91 +1,92 @@
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:38:26
+ --> $DIR/expect_fun_call.rs:37:26
|
LL | with_none_and_format.expect(&format!("Error {}: fake error", error_code));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))`
|
= note: `-D clippy::expect-fun-call` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::expect_fun_call)]`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:41:26
+ --> $DIR/expect_fun_call.rs:40:26
|
LL | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:44:37
+ --> $DIR/expect_fun_call.rs:43:37
|
LL | with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", one!()))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:54:25
+ --> $DIR/expect_fun_call.rs:53:25
|
LL | with_err_and_format.expect(&format!("Error {}: fake error", error_code));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:57:25
+ --> $DIR/expect_fun_call.rs:56:25
|
LL | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:69:17
+ --> $DIR/expect_fun_call.rs:68:17
|
LL | Some("foo").expect(format!("{} {}", 1, 2).as_ref());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{} {}", 1, 2))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:90:21
+ --> $DIR/expect_fun_call.rs:89:21
|
LL | Some("foo").expect(&get_string());
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:91:21
+ --> $DIR/expect_fun_call.rs:90:21
|
LL | Some("foo").expect(get_string().as_ref());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:92:21
+ --> $DIR/expect_fun_call.rs:91:21
|
LL | Some("foo").expect(get_string().as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:94:21
+ --> $DIR/expect_fun_call.rs:93:21
|
LL | Some("foo").expect(get_static_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_static_str()) })`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:95:21
+ --> $DIR/expect_fun_call.rs:94:21
|
LL | Some("foo").expect(get_non_static_str(&0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:99:16
+ --> $DIR/expect_fun_call.rs:98:16
|
LL | Some(true).expect(&format!("key {}, {}", 1, 2));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:105:17
+ --> $DIR/expect_fun_call.rs:104:17
|
LL | opt_ref.expect(&format!("{:?}", opt_ref));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:109:20
+ --> $DIR/expect_fun_call.rs:108:20
|
LL | format_capture.expect(&format!("{error_code}"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))`
error: use of `expect` followed by a function call
- --> $DIR/expect_fun_call.rs:112:30
+ --> $DIR/expect_fun_call.rs:111:30
|
LL | format_capture_and_value.expect(&format!("{error_code}, {}", 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))`
diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs
index 2460f3343..3811421dc 100644
--- a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs
+++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs
@@ -33,10 +33,13 @@ mod rustc_warn {
//! See <https://doc.rust-lang.org/rustc/lints/index.html>
#[expect(dead_code)]
+ //~^ ERROR: this lint expectation is unfulfilled
+ //~| NOTE: `-D unfulfilled-lint-expectations` implied by `-D warnings`
pub fn rustc_lints() {
let x = 42;
#[expect(illegal_floating_point_literal_pattern)]
+ //~^ ERROR: this lint expectation is unfulfilled
match x {
5 => {}
6 => {}
@@ -111,6 +114,7 @@ mod clippy_warn {
//! See <https://rust-lang.github.io/rust-clippy/master/index.html>
#[expect(clippy::almost_swapped)]
+ //~^ ERROR: this lint expectation is unfulfilled
fn foo() {
let mut a = 0;
let mut b = 9;
@@ -118,16 +122,19 @@ mod clippy_warn {
}
#[expect(clippy::bytes_nth)]
+ //~^ ERROR: this lint expectation is unfulfilled
fn bar() {
let _ = "Hello".as_bytes().get(3);
}
#[expect(clippy::if_same_then_else)]
+ //~^ ERROR: this lint expectation is unfulfilled
fn baz() {
let _ = if true { 33 } else { 42 };
}
#[expect(clippy::overly_complex_bool_expr)]
+ //~^ ERROR: this lint expectation is unfulfilled
fn burger() {
let a = false;
let b = true;
diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr
index 7ce9e855b..3f8d0b724 100644
--- a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr
+++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr
@@ -5,33 +5,34 @@ LL | #[expect(dead_code)]
| ^^^^^^^^^
|
= note: `-D unfulfilled-lint-expectations` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`
error: this lint expectation is unfulfilled
- --> $DIR/expect_tool_lint_rfc_2383.rs:39:18
+ --> $DIR/expect_tool_lint_rfc_2383.rs:41:18
|
LL | #[expect(illegal_floating_point_literal_pattern)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this lint expectation is unfulfilled
- --> $DIR/expect_tool_lint_rfc_2383.rs:113:14
+ --> $DIR/expect_tool_lint_rfc_2383.rs:116:14
|
LL | #[expect(clippy::almost_swapped)]
| ^^^^^^^^^^^^^^^^^^^^^^
error: this lint expectation is unfulfilled
- --> $DIR/expect_tool_lint_rfc_2383.rs:120:14
+ --> $DIR/expect_tool_lint_rfc_2383.rs:124:14
|
LL | #[expect(clippy::bytes_nth)]
| ^^^^^^^^^^^^^^^^^
error: this lint expectation is unfulfilled
- --> $DIR/expect_tool_lint_rfc_2383.rs:125:14
+ --> $DIR/expect_tool_lint_rfc_2383.rs:130:14
|
LL | #[expect(clippy::if_same_then_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: this lint expectation is unfulfilled
- --> $DIR/expect_tool_lint_rfc_2383.rs:130:14
+ --> $DIR/expect_tool_lint_rfc_2383.rs:136:14
|
LL | #[expect(clippy::overly_complex_bool_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
index 71a5ed96d..12158d0d1 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(closure_lifetime_binder)]
#![warn(clippy::explicit_auto_deref)]
#![allow(
@@ -207,7 +205,7 @@ fn main() {
}
}
- f_str(&&ref_str); // `needless_borrow` will suggest removing both references
+ f_str(&ref_str); // `needless_borrow` will suggest removing both references
f_str(&ref_str); // `needless_borrow` will suggest removing only one reference
let x = &&40;
@@ -295,4 +293,32 @@ fn main() {
fn return_dyn_assoc<'a>(x: &'a &'a u32) -> &'a <&'a u32 as WithAssoc>::Assoc {
*x
}
+
+ // Issue #11366
+ let _: &mut u32 = match &mut Some(&mut 0u32) {
+ Some(x) => x,
+ None => panic!(),
+ };
+
+ // Issue #11474
+ pub struct Variant {
+ pub anonymous: Variant0,
+ }
+
+ pub union Variant0 {
+ pub anonymous: std::mem::ManuallyDrop<Variant00>,
+ }
+
+ pub struct Variant00 {
+ pub anonymous: Variant000,
+ }
+
+ pub union Variant000 {
+ pub val: i32,
+ }
+
+ unsafe {
+ let mut p = core::mem::zeroed::<Variant>();
+ (*p.anonymous.anonymous).anonymous.val = 1;
+ }
}
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
index 9d0cafa15..dec021c18 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(closure_lifetime_binder)]
#![warn(clippy::explicit_auto_deref)]
#![allow(
@@ -295,4 +293,32 @@ fn main() {
fn return_dyn_assoc<'a>(x: &'a &'a u32) -> &'a <&'a u32 as WithAssoc>::Assoc {
*x
}
+
+ // Issue #11366
+ let _: &mut u32 = match &mut Some(&mut 0u32) {
+ Some(x) => &mut *x,
+ None => panic!(),
+ };
+
+ // Issue #11474
+ pub struct Variant {
+ pub anonymous: Variant0,
+ }
+
+ pub union Variant0 {
+ pub anonymous: std::mem::ManuallyDrop<Variant00>,
+ }
+
+ pub struct Variant00 {
+ pub anonymous: Variant000,
+ }
+
+ pub union Variant000 {
+ pub val: i32,
+ }
+
+ unsafe {
+ let mut p = core::mem::zeroed::<Variant>();
+ (*p.anonymous.anonymous).anonymous.val = 1;
+ }
}
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
index afc311e3f..3d2a7b0d9 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
@@ -1,238 +1,245 @@
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:70:19
+ --> $DIR/explicit_auto_deref.rs:68:19
|
LL | let _: &str = &*s;
| ^^^ help: try: `&s`
|
= note: `-D clippy::explicit-auto-deref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::explicit_auto_deref)]`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:71:19
+ --> $DIR/explicit_auto_deref.rs:69:19
|
LL | let _: &str = &*{ String::new() };
| ^^^^^^^^^^^^^^^^^^^ help: try: `&{ String::new() }`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:72:19
+ --> $DIR/explicit_auto_deref.rs:70:19
|
LL | let _: &str = &mut *{ String::new() };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut { String::new() }`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:76:11
+ --> $DIR/explicit_auto_deref.rs:74:11
|
LL | f_str(&*s);
| ^^^ help: try: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:80:13
+ --> $DIR/explicit_auto_deref.rs:78:13
|
LL | f_str_t(&*s, &*s); // Don't lint second param.
| ^^^ help: try: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:83:24
+ --> $DIR/explicit_auto_deref.rs:81:24
|
LL | let _: &Box<i32> = &**b;
| ^^^^ help: try: `&b`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:89:7
+ --> $DIR/explicit_auto_deref.rs:87:7
|
LL | c(&*s);
| ^^^ help: try: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:95:9
+ --> $DIR/explicit_auto_deref.rs:93:9
|
LL | &**x
| ^^^^ help: try: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:99:11
+ --> $DIR/explicit_auto_deref.rs:97:11
|
LL | { &**x }
| ^^^^ help: try: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:103:9
+ --> $DIR/explicit_auto_deref.rs:101:9
|
LL | &**{ x }
| ^^^^^^^^ help: try: `{ x }`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:107:9
+ --> $DIR/explicit_auto_deref.rs:105:9
|
LL | &***x
| ^^^^^ help: try: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:124:12
+ --> $DIR/explicit_auto_deref.rs:122:12
|
LL | f1(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:125:12
+ --> $DIR/explicit_auto_deref.rs:123:12
|
LL | f2(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:126:12
+ --> $DIR/explicit_auto_deref.rs:124:12
|
LL | f3(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:127:27
+ --> $DIR/explicit_auto_deref.rs:125:27
|
LL | f4.callable_str()(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:128:12
+ --> $DIR/explicit_auto_deref.rs:126:12
|
LL | f5(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:129:12
+ --> $DIR/explicit_auto_deref.rs:127:12
|
LL | f6(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:130:27
+ --> $DIR/explicit_auto_deref.rs:128:27
|
LL | f7.callable_str()(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:131:25
+ --> $DIR/explicit_auto_deref.rs:129:25
|
LL | f8.callable_t()(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:132:12
+ --> $DIR/explicit_auto_deref.rs:130:12
|
LL | f9(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:133:13
+ --> $DIR/explicit_auto_deref.rs:131:13
|
LL | f10(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:134:26
+ --> $DIR/explicit_auto_deref.rs:132:26
|
LL | f11.callable_t()(&*x);
| ^^^ help: try: `&x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:138:16
+ --> $DIR/explicit_auto_deref.rs:136:16
|
LL | let _ = S1(&*s);
| ^^^ help: try: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:143:21
+ --> $DIR/explicit_auto_deref.rs:141:21
|
LL | let _ = S2 { s: &*s };
| ^^^ help: try: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:159:30
+ --> $DIR/explicit_auto_deref.rs:157:30
|
LL | let _ = Self::S1(&**s);
| ^^^^ help: try: `s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:160:35
+ --> $DIR/explicit_auto_deref.rs:158:35
|
LL | let _ = Self::S2 { s: &**s };
| ^^^^ help: try: `s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:163:20
+ --> $DIR/explicit_auto_deref.rs:161:20
|
LL | let _ = E1::S1(&*s);
| ^^^ help: try: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:164:25
+ --> $DIR/explicit_auto_deref.rs:162:25
|
LL | let _ = E1::S2 { s: &*s };
| ^^^ help: try: `&s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:182:13
+ --> $DIR/explicit_auto_deref.rs:180:13
|
LL | let _ = (*b).foo;
| ^^^^ help: try: `b`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:183:13
+ --> $DIR/explicit_auto_deref.rs:181:13
|
LL | let _ = (**b).foo;
| ^^^^^ help: try: `b`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:198:19
+ --> $DIR/explicit_auto_deref.rs:196:19
|
LL | let _ = f_str(*ref_str);
| ^^^^^^^^ help: try: `ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:200:19
+ --> $DIR/explicit_auto_deref.rs:198:19
|
LL | let _ = f_str(**ref_ref_str);
| ^^^^^^^^^^^^^ help: try: `ref_ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:210:13
+ --> $DIR/explicit_auto_deref.rs:208:12
|
LL | f_str(&&*ref_str); // `needless_borrow` will suggest removing both references
- | ^^^^^^^^ help: try: `ref_str`
+ | ^^^^^^^^^ help: try: `ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:211:12
+ --> $DIR/explicit_auto_deref.rs:209:12
|
LL | f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference
| ^^^^^^^^^^ help: try: `ref_str`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:220:41
+ --> $DIR/explicit_auto_deref.rs:218:41
|
LL | let _ = || -> &'static str { return *s };
| ^^ help: try: `s`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:239:9
+ --> $DIR/explicit_auto_deref.rs:237:9
|
LL | &**x
| ^^^^ help: try: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:262:8
+ --> $DIR/explicit_auto_deref.rs:260:8
|
LL | c1(*x);
| ^^ help: try: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:265:20
+ --> $DIR/explicit_auto_deref.rs:263:20
|
LL | return *x;
| ^^ help: try: `x`
error: deref which would be done by auto-deref
- --> $DIR/explicit_auto_deref.rs:267:9
+ --> $DIR/explicit_auto_deref.rs:265:9
|
LL | *x
| ^^ help: try: `x`
-error: aborting due to 39 previous errors
+error: deref which would be done by auto-deref
+ --> $DIR/explicit_auto_deref.rs:299:20
+ |
+LL | Some(x) => &mut *x,
+ | ^^^^^^^ help: try: `x`
+
+error: aborting due to 40 previous errors
diff --git a/src/tools/clippy/tests/ui/explicit_counter_loop.rs b/src/tools/clippy/tests/ui/explicit_counter_loop.rs
index e02b8f62b..c25e79a36 100644
--- a/src/tools/clippy/tests/ui/explicit_counter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_counter_loop.rs
@@ -1,26 +1,31 @@
#![warn(clippy::explicit_counter_loop)]
#![allow(clippy::uninlined_format_args, clippy::useless_vec)]
-
+//@no-rustfix
fn main() {
let mut vec = vec![1, 2, 3, 4];
let mut _index = 0;
for _v in &vec {
+ //~^ ERROR: the variable `_index` is used as a loop counter
+ //~| NOTE: `-D clippy::explicit-counter-loop` implied by `-D warnings`
_index += 1
}
let mut _index = 1;
_index = 0;
for _v in &vec {
+ //~^ ERROR: the variable `_index` is used as a loop counter
_index += 1
}
let mut _index = 0;
for _v in &mut vec {
+ //~^ ERROR: the variable `_index` is used as a loop counter
_index += 1;
}
let mut _index = 0;
for _v in vec {
+ //~^ ERROR: the variable `_index` is used as a loop counter
_index += 1;
}
@@ -108,6 +113,7 @@ mod issue_1219 {
let text = "banana";
let mut count = 0;
for ch in text.chars() {
+ //~^ ERROR: the variable `count` is used as a loop counter
println!("{}", count);
count += 1;
if ch == 'a' {
@@ -119,6 +125,7 @@ mod issue_1219 {
let text = "banana";
let mut count = 0;
for ch in text.chars() {
+ //~^ ERROR: the variable `count` is used as a loop counter
println!("{}", count);
count += 1;
for i in 0..2 {
@@ -177,6 +184,7 @@ mod issue_1670 {
pub fn test() {
let mut count = 0;
for _i in 3..10 {
+ //~^ ERROR: the variable `count` is used as a loop counter
count += 1;
}
}
@@ -217,6 +225,7 @@ mod issue_7920 {
// should suggest `enumerate`
for _item in slice {
+ //~^ ERROR: the variable `idx_usize` is used as a loop counter
if idx_usize == index_usize {
break;
}
@@ -229,6 +238,8 @@ mod issue_7920 {
// should suggest `zip`
for _item in slice {
+ //~^ ERROR: the variable `idx_u32` is used as a loop counter
+ //~| NOTE: `idx_u32` is of type `u32`, making it ineligible for `Iterator::enumera
if idx_u32 == index_u32 {
break;
}
diff --git a/src/tools/clippy/tests/ui/explicit_counter_loop.stderr b/src/tools/clippy/tests/ui/explicit_counter_loop.stderr
index 0677e4d78..aef979072 100644
--- a/src/tools/clippy/tests/ui/explicit_counter_loop.stderr
+++ b/src/tools/clippy/tests/ui/explicit_counter_loop.stderr
@@ -5,51 +5,52 @@ LL | for _v in &vec {
| ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter().enumerate()`
|
= note: `-D clippy::explicit-counter-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::explicit_counter_loop)]`
error: the variable `_index` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:13:5
+ --> $DIR/explicit_counter_loop.rs:15:5
|
LL | for _v in &vec {
| ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter().enumerate()`
error: the variable `_index` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:18:5
+ --> $DIR/explicit_counter_loop.rs:21:5
|
LL | for _v in &mut vec {
| ^^^^^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter_mut().enumerate()`
error: the variable `_index` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:23:5
+ --> $DIR/explicit_counter_loop.rs:27:5
|
LL | for _v in vec {
| ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()`
error: the variable `count` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:110:9
+ --> $DIR/explicit_counter_loop.rs:115:9
|
LL | for ch in text.chars() {
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
error: the variable `count` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:121:9
+ --> $DIR/explicit_counter_loop.rs:127:9
|
LL | for ch in text.chars() {
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
error: the variable `count` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:179:9
+ --> $DIR/explicit_counter_loop.rs:186:9
|
LL | for _i in 3..10 {
| ^^^^^^^^^^^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()`
error: the variable `idx_usize` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:219:9
+ --> $DIR/explicit_counter_loop.rs:227:9
|
LL | for _item in slice {
| ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_usize, _item) in slice.iter().enumerate()`
error: the variable `idx_u32` is used as a loop counter
- --> $DIR/explicit_counter_loop.rs:231:9
+ --> $DIR/explicit_counter_loop.rs:240:9
|
LL | for _item in slice {
| ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_u32, _item) in (0_u32..).zip(slice.iter())`
diff --git a/src/tools/clippy/tests/ui/explicit_deref_methods.fixed b/src/tools/clippy/tests/ui/explicit_deref_methods.fixed
index 4c0b0d8f2..7b2dd2fe6 100644
--- a/src/tools/clippy/tests/ui/explicit_deref_methods.fixed
+++ b/src/tools/clippy/tests/ui/explicit_deref_methods.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::explicit_deref_methods)]
#![allow(unused_variables, unused_must_use)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/explicit_deref_methods.rs b/src/tools/clippy/tests/ui/explicit_deref_methods.rs
index bc5da35e5..eb52cfb0d 100644
--- a/src/tools/clippy/tests/ui/explicit_deref_methods.rs
+++ b/src/tools/clippy/tests/ui/explicit_deref_methods.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::explicit_deref_methods)]
#![allow(unused_variables, unused_must_use)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/explicit_deref_methods.stderr b/src/tools/clippy/tests/ui/explicit_deref_methods.stderr
index e4d2fe3a1..eb7059367 100644
--- a/src/tools/clippy/tests/ui/explicit_deref_methods.stderr
+++ b/src/tools/clippy/tests/ui/explicit_deref_methods.stderr
@@ -1,73 +1,74 @@
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:55:19
+ --> $DIR/explicit_deref_methods.rs:54:19
|
LL | let b: &str = a.deref();
| ^^^^^^^^^ help: try: `&*a`
|
= note: `-D clippy::explicit-deref-methods` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::explicit_deref_methods)]`
error: explicit `deref_mut` method call
- --> $DIR/explicit_deref_methods.rs:57:23
+ --> $DIR/explicit_deref_methods.rs:56:23
|
LL | let b: &mut str = a.deref_mut();
| ^^^^^^^^^^^^^ help: try: `&mut **a`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:60:39
+ --> $DIR/explicit_deref_methods.rs:59:39
|
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
| ^^^^^^^^^ help: try: `&*a`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:60:50
+ --> $DIR/explicit_deref_methods.rs:59:50
|
LL | let b: String = format!("{}, {}", a.deref(), a.deref());
| ^^^^^^^^^ help: try: `&*a`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:62:20
+ --> $DIR/explicit_deref_methods.rs:61:20
|
LL | println!("{}", a.deref());
| ^^^^^^^^^ help: try: `&*a`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:65:11
+ --> $DIR/explicit_deref_methods.rs:64:11
|
LL | match a.deref() {
| ^^^^^^^^^ help: try: `&*a`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:69:28
+ --> $DIR/explicit_deref_methods.rs:68:28
|
LL | let b: String = concat(a.deref());
| ^^^^^^^^^ help: try: `&*a`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:71:13
+ --> $DIR/explicit_deref_methods.rs:70:13
|
LL | let b = just_return(a).deref();
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:73:28
+ --> $DIR/explicit_deref_methods.rs:72:28
|
LL | let b: String = concat(just_return(a).deref());
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:75:19
+ --> $DIR/explicit_deref_methods.rs:74:19
|
LL | let b: &str = a.deref().deref();
| ^^^^^^^^^^^^^^^^^ help: try: `&**a`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:78:13
+ --> $DIR/explicit_deref_methods.rs:77:13
|
LL | let b = opt_a.unwrap().deref();
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*opt_a.unwrap()`
error: explicit `deref` method call
- --> $DIR/explicit_deref_methods.rs:115:31
+ --> $DIR/explicit_deref_methods.rs:114:31
|
LL | let b: &str = expr_deref!(a.deref());
| ^^^^^^^^^ help: try: `&*a`
diff --git a/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed
index dcef63403..2521bce6a 100644
--- a/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_into_iter_loop.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::explicit_into_iter_loop)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs
index bc048ed30..9eac96d18 100644
--- a/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_into_iter_loop.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::explicit_into_iter_loop)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr b/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr
index fa89b884f..c03647ab4 100644
--- a/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr
+++ b/src/tools/clippy/tests/ui/explicit_into_iter_loop.stderr
@@ -1,37 +1,38 @@
error: it is more concise to loop over containers instead of using explicit iteration methods
- --> $DIR/explicit_into_iter_loop.rs:10:18
+ --> $DIR/explicit_into_iter_loop.rs:9:18
|
LL | for _ in iterator.into_iter() {}
| ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator`
|
= note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::explicit_into_iter_loop)]`
error: it is more concise to loop over containers instead of using explicit iteration methods
- --> $DIR/explicit_into_iter_loop.rs:23:14
+ --> $DIR/explicit_into_iter_loop.rs:22:14
|
LL | for _ in t.into_iter() {}
| ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t`
error: it is more concise to loop over containers instead of using explicit iteration methods
- --> $DIR/explicit_into_iter_loop.rs:26:14
+ --> $DIR/explicit_into_iter_loop.rs:25:14
|
LL | for _ in r.into_iter() {}
| ^^^^^^^^^^^^^ help: to write this more concisely, try: `r`
error: it is more concise to loop over containers instead of using explicit iteration methods
- --> $DIR/explicit_into_iter_loop.rs:34:14
+ --> $DIR/explicit_into_iter_loop.rs:33:14
|
LL | for _ in mr.into_iter() {}
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&*mr`
error: it is more concise to loop over containers instead of using explicit iteration methods
- --> $DIR/explicit_into_iter_loop.rs:46:14
+ --> $DIR/explicit_into_iter_loop.rs:45:14
|
LL | for _ in u.into_iter() {}
| ^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut u`
error: it is more concise to loop over containers instead of using explicit iteration methods
- --> $DIR/explicit_into_iter_loop.rs:49:14
+ --> $DIR/explicit_into_iter_loop.rs:48:14
|
LL | for _ in mr.into_iter() {}
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *mr`
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
index 746ef813c..f08397def 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
@@ -1,10 +1,10 @@
-//@run-rustfix
#![deny(clippy::explicit_iter_loop)]
#![allow(
clippy::linkedlist,
clippy::similar_names,
clippy::needless_borrow,
clippy::deref_addrof,
+ clippy::unnecessary_mut_passed,
dead_code
)]
@@ -21,15 +21,15 @@ fn main() {
for _ in rvec {}
let rmvec = &mut vec;
- for _ in &*rmvec {}
- for _ in &mut *rmvec {}
+ for _ in rmvec.iter() {}
+ for _ in rmvec.iter_mut() {}
for _ in &vec {} // these are fine
for _ in &mut vec {} // these are fine
for _ in &[1, 2, 3] {}
- for _ in &*(&mut [1, 2, 3]) {}
+ for _ in (&mut [1, 2, 3]).iter() {}
for _ in &[0; 32] {}
for _ in &[0; 33] {}
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
index fba230ee0..2ee6825d4 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
@@ -1,10 +1,10 @@
-//@run-rustfix
#![deny(clippy::explicit_iter_loop)]
#![allow(
clippy::linkedlist,
clippy::similar_names,
clippy::needless_borrow,
clippy::deref_addrof,
+ clippy::unnecessary_mut_passed,
dead_code
)]
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.stderr b/src/tools/clippy/tests/ui/explicit_iter_loop.stderr
index 94a264dce..725d9b63c 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.stderr
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.stderr
@@ -5,7 +5,7 @@ LL | for _ in vec.iter() {}
| ^^^^^^^^^^ help: to write this more concisely, try: `&vec`
|
note: the lint level is defined here
- --> $DIR/explicit_iter_loop.rs:2:9
+ --> $DIR/explicit_iter_loop.rs:1:9
|
LL | #![deny(clippy::explicit_iter_loop)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,38 +23,12 @@ LL | for _ in rvec.iter() {}
| ^^^^^^^^^^^ help: to write this more concisely, try: `rvec`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
- --> $DIR/explicit_iter_loop.rs:24:14
- |
-LL | for _ in rmvec.iter() {}
- | ^^^^^^^^^^^^ help: to write this more concisely, try: `&*rmvec`
-
-error: it is more concise to loop over references to containers instead of using explicit iteration methods
- --> $DIR/explicit_iter_loop.rs:25:14
- |
-LL | for _ in rmvec.iter_mut() {}
- | ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *rmvec`
-
-error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/explicit_iter_loop.rs:30:14
|
LL | for _ in [1, 2, 3].iter() {}
| ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
- --> $DIR/explicit_iter_loop.rs:32:14
- |
-LL | for _ in (&mut [1, 2, 3]).iter() {}
- | ^^^^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&*(&mut [1, 2, 3])`
-
-error: the method `iter` doesn't need a mutable reference
- --> $DIR/explicit_iter_loop.rs:32:14
- |
-LL | for _ in (&mut [1, 2, 3]).iter() {}
- | ^^^^^^^^^^^^^^^^
- |
- = note: `-D clippy::unnecessary-mut-passed` implied by `-D warnings`
-
-error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/explicit_iter_loop.rs:34:14
|
LL | for _ in [0; 32].iter() {}
@@ -138,5 +112,5 @@ error: it is more concise to loop over references to containers instead of using
LL | for _ in r.iter() {}
| ^^^^^^^^ help: to write this more concisely, try: `r`
-error: aborting due to 22 previous errors
+error: aborting due to 18 previous errors
diff --git a/src/tools/clippy/tests/ui/explicit_write.fixed b/src/tools/clippy/tests/ui/explicit_write.fixed
index 213485bc2..77a910dc1 100644
--- a/src/tools/clippy/tests/ui/explicit_write.fixed
+++ b/src/tools/clippy/tests/ui/explicit_write.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::explicit_write)]
#![allow(unused_imports)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/explicit_write.rs b/src/tools/clippy/tests/ui/explicit_write.rs
index 64acd7108..c77956264 100644
--- a/src/tools/clippy/tests/ui/explicit_write.rs
+++ b/src/tools/clippy/tests/ui/explicit_write.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::explicit_write)]
#![allow(unused_imports)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/explicit_write.stderr b/src/tools/clippy/tests/ui/explicit_write.stderr
index b3aa7274c..26aad266b 100644
--- a/src/tools/clippy/tests/ui/explicit_write.stderr
+++ b/src/tools/clippy/tests/ui/explicit_write.stderr
@@ -1,79 +1,80 @@
error: use of `write!(stdout(), ...).unwrap()`
- --> $DIR/explicit_write.rs:24:9
+ --> $DIR/explicit_write.rs:23:9
|
LL | write!(std::io::stdout(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `print!("test")`
|
= note: `-D clippy::explicit-write` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::explicit_write)]`
error: use of `write!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:25:9
+ --> $DIR/explicit_write.rs:24:9
|
LL | write!(std::io::stderr(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!("test")`
error: use of `writeln!(stdout(), ...).unwrap()`
- --> $DIR/explicit_write.rs:26:9
+ --> $DIR/explicit_write.rs:25:9
|
LL | writeln!(std::io::stdout(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!("test")`
error: use of `writeln!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:27:9
+ --> $DIR/explicit_write.rs:26:9
|
LL | writeln!(std::io::stderr(), "test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("test")`
error: use of `stdout().write_fmt(...).unwrap()`
- --> $DIR/explicit_write.rs:28:9
+ --> $DIR/explicit_write.rs:27:9
|
LL | std::io::stdout().write_fmt(format_args!("test")).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `print!("test")`
error: use of `stderr().write_fmt(...).unwrap()`
- --> $DIR/explicit_write.rs:29:9
+ --> $DIR/explicit_write.rs:28:9
|
LL | std::io::stderr().write_fmt(format_args!("test")).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!("test")`
error: use of `writeln!(stdout(), ...).unwrap()`
- --> $DIR/explicit_write.rs:32:9
+ --> $DIR/explicit_write.rs:31:9
|
-LL | writeln!(std::io::stdout(), "test/ntest").unwrap();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!("test/ntest")`
+LL | writeln!(std::io::stdout(), "test\ntest").unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!("test\ntest")`
error: use of `writeln!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:33:9
+ --> $DIR/explicit_write.rs:32:9
|
-LL | writeln!(std::io::stderr(), "test/ntest").unwrap();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("test/ntest")`
+LL | writeln!(std::io::stderr(), "test\ntest").unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("test\ntest")`
error: use of `writeln!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:36:9
+ --> $DIR/explicit_write.rs:35:9
|
LL | writeln!(std::io::stderr(), "with {}", value).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {}", value)`
error: use of `writeln!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:37:9
+ --> $DIR/explicit_write.rs:36:9
|
LL | writeln!(std::io::stderr(), "with {} {}", 2, value).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {} {}", 2, value)`
error: use of `writeln!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:38:9
+ --> $DIR/explicit_write.rs:37:9
|
LL | writeln!(std::io::stderr(), "with {value}").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("with {value}")`
error: use of `writeln!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:39:9
+ --> $DIR/explicit_write.rs:38:9
|
LL | writeln!(std::io::stderr(), "macro arg {}", one!()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("macro arg {}", one!())`
error: use of `writeln!(stderr(), ...).unwrap()`
- --> $DIR/explicit_write.rs:41:9
+ --> $DIR/explicit_write.rs:40:9
|
LL | writeln!(std::io::stderr(), "{:w$}", value, w = width).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!("{:w$}", value, w = width)`
diff --git a/src/tools/clippy/tests/ui/extend_with_drain.fixed b/src/tools/clippy/tests/ui/extend_with_drain.fixed
index 594f2f6d4..856c1a42d 100644
--- a/src/tools/clippy/tests/ui/extend_with_drain.fixed
+++ b/src/tools/clippy/tests/ui/extend_with_drain.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::extend_with_drain)]
#![allow(clippy::iter_with_drain)]
use std::collections::BinaryHeap;
diff --git a/src/tools/clippy/tests/ui/extend_with_drain.rs b/src/tools/clippy/tests/ui/extend_with_drain.rs
index 3e2ad0205..7d5380976 100644
--- a/src/tools/clippy/tests/ui/extend_with_drain.rs
+++ b/src/tools/clippy/tests/ui/extend_with_drain.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::extend_with_drain)]
#![allow(clippy::iter_with_drain)]
use std::collections::BinaryHeap;
diff --git a/src/tools/clippy/tests/ui/extend_with_drain.stderr b/src/tools/clippy/tests/ui/extend_with_drain.stderr
index eb2dd304d..e0bd5a620 100644
--- a/src/tools/clippy/tests/ui/extend_with_drain.stderr
+++ b/src/tools/clippy/tests/ui/extend_with_drain.stderr
@@ -1,25 +1,26 @@
error: use of `extend` instead of `append` for adding the full range of a second vector
- --> $DIR/extend_with_drain.rs:9:5
+ --> $DIR/extend_with_drain.rs:8:5
|
LL | vec2.extend(vec1.drain(..));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec2.append(&mut vec1)`
|
= note: `-D clippy::extend-with-drain` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::extend_with_drain)]`
error: use of `extend` instead of `append` for adding the full range of a second vector
- --> $DIR/extend_with_drain.rs:14:5
+ --> $DIR/extend_with_drain.rs:13:5
|
LL | vec4.extend(vec3.drain(..));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec4.append(&mut vec3)`
error: use of `extend` instead of `append` for adding the full range of a second vector
- --> $DIR/extend_with_drain.rs:18:5
+ --> $DIR/extend_with_drain.rs:17:5
|
LL | vec11.extend(return_vector().drain(..));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec11.append(&mut return_vector())`
error: use of `extend` instead of `append` for adding the full range of a second vector
- --> $DIR/extend_with_drain.rs:49:5
+ --> $DIR/extend_with_drain.rs:48:5
|
LL | y.extend(ref_x.drain(..));
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `y.append(ref_x)`
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
index 50abe89da..cdfaf8d3a 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
index 26ebc3976..8790fe5a5 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
@@ -5,6 +5,7 @@ LL | fn unused_lt<'a>(x: u8) {}
| ^^
|
= note: `-D clippy::extra-unused-lifetimes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::extra_unused_lifetimes)]`
error: this lifetime isn't used in the function definition
--> $DIR/extra_unused_lifetimes.rs:46:10
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
index 8420df663..c9bebabdf 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused, clippy::needless_lifetimes)]
#![warn(clippy::extra_unused_type_parameters)]
@@ -114,4 +113,19 @@ with_span!(
}
);
+mod issue11302 {
+ use std::fmt::Debug;
+ use std::marker::PhantomData;
+
+ #[derive(Debug)]
+ struct Wrapper<T>(PhantomData<T>);
+
+ fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)
+ where
+ Wrapper<T>: Debug,
+ {
+ v.push(Box::new(Wrapper(PhantomData)));
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
index f63535d7a..1bc0047ad 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused, clippy::needless_lifetimes)]
#![warn(clippy::extra_unused_type_parameters)]
@@ -114,4 +113,19 @@ with_span!(
}
);
+mod issue11302 {
+ use std::fmt::Debug;
+ use std::marker::PhantomData;
+
+ #[derive(Debug)]
+ struct Wrapper<T>(PhantomData<T>);
+
+ fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)
+ where
+ Wrapper<T>: Debug,
+ {
+ v.push(Box::new(Wrapper(PhantomData)));
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr b/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr
index b5277d498..9a179076c 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.stderr
@@ -1,25 +1,26 @@
error: type parameter `T` goes unused in function definition
- --> $DIR/extra_unused_type_parameters.rs:10:13
+ --> $DIR/extra_unused_type_parameters.rs:9:13
|
LL | fn unused_ty<T>(x: u8) {
| ^^^ help: consider removing the parameter
|
= note: `-D clippy::extra-unused-type-parameters` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::extra_unused_type_parameters)]`
error: type parameters go unused in function definition: T, U
- --> $DIR/extra_unused_type_parameters.rs:14:16
+ --> $DIR/extra_unused_type_parameters.rs:13:16
|
LL | fn unused_multi<T, U>(x: u8) {
| ^^^^^^ help: consider removing the parameters
error: type parameter `T` goes unused in function definition
- --> $DIR/extra_unused_type_parameters.rs:18:21
+ --> $DIR/extra_unused_type_parameters.rs:17:21
|
LL | fn unused_with_lt<'a, T>(x: &'a u8) {
| ^^^ help: consider removing the parameter
error: type parameters go unused in function definition: T, V
- --> $DIR/extra_unused_type_parameters.rs:30:19
+ --> $DIR/extra_unused_type_parameters.rs:29:19
|
LL | fn unused_bounded<T: Default, U, V: Default>(x: U) {
| ^^^^^^^^^^^^ ^^^^^^^^^^^^
@@ -31,7 +32,7 @@ LL + fn unused_bounded<U>(x: U) {
|
error: type parameters go unused in function definition: A, D, E
- --> $DIR/extra_unused_type_parameters.rs:34:16
+ --> $DIR/extra_unused_type_parameters.rs:33:16
|
LL | fn some_unused<A, B, C, D: Iterator<Item = (B, C)>, E>(b: B, c: C) {
| ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,19 +44,19 @@ LL + fn some_unused<B, C>(b: B, c: C) {
|
error: type parameter `T` goes unused in function definition
- --> $DIR/extra_unused_type_parameters.rs:59:22
+ --> $DIR/extra_unused_type_parameters.rs:58:22
|
LL | fn unused_ty_impl<T>(&self) {
| ^^^ help: consider removing the parameter
error: type parameters go unused in function definition: A, B
- --> $DIR/extra_unused_type_parameters.rs:81:17
+ --> $DIR/extra_unused_type_parameters.rs:80:17
|
LL | fn unused_opaque<A, B>(dummy: impl Default) {
| ^^^^^^ help: consider removing the parameters
error: type parameter `U` goes unused in function definition
- --> $DIR/extra_unused_type_parameters.rs:94:56
+ --> $DIR/extra_unused_type_parameters.rs:93:56
|
LL | fn unused_with_priv_trait_bound<T: private::Private, U>() {
| ^^^ help: consider removing the parameter
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs
index 10b39aa8f..65b53eb2e 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.rs
@@ -1,6 +1,7 @@
#![warn(clippy::extra_unused_type_parameters)]
fn unused_where_clause<T, U>(x: U)
+//~^ ERROR: type parameter `T` goes unused in function definition
where
T: Default,
{
@@ -8,6 +9,7 @@ where
}
fn unused_multi_where_clause<T, U, V: Default>(x: U)
+//~^ ERROR: type parameters go unused in function definition: T, V
where
T: Default,
{
@@ -15,6 +17,7 @@ where
}
fn unused_all_where_clause<T, U: Default, V: Default>()
+//~^ ERROR: type parameters go unused in function definition: T, U, V
where
T: Default,
{
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr
index a9580cc89..a216c4363 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters_unfixable.stderr
@@ -6,9 +6,10 @@ LL | fn unused_where_clause<T, U>(x: U)
|
= help: consider removing the parameter
= note: `-D clippy::extra-unused-type-parameters` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::extra_unused_type_parameters)]`
error: type parameters go unused in function definition: T, V
- --> $DIR/extra_unused_type_parameters_unfixable.rs:10:30
+ --> $DIR/extra_unused_type_parameters_unfixable.rs:11:30
|
LL | fn unused_multi_where_clause<T, U, V: Default>(x: U)
| ^ ^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | fn unused_multi_where_clause<T, U, V: Default>(x: U)
= help: consider removing the parameters
error: type parameters go unused in function definition: T, U, V
- --> $DIR/extra_unused_type_parameters_unfixable.rs:17:28
+ --> $DIR/extra_unused_type_parameters_unfixable.rs:19:28
|
LL | fn unused_all_where_clause<T, U: Default, V: Default>()
| ^ ^^^^^^^^^^ ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/fallible_impl_from.rs b/src/tools/clippy/tests/ui/fallible_impl_from.rs
index fb6e8ec70..a81e51fca 100644
--- a/src/tools/clippy/tests/ui/fallible_impl_from.rs
+++ b/src/tools/clippy/tests/ui/fallible_impl_from.rs
@@ -4,6 +4,7 @@
// docs example
struct Foo(i32);
impl From<String> for Foo {
+ //~^ ERROR: consider implementing `TryFrom` instead
fn from(s: String) -> Self {
Foo(s.parse().unwrap())
}
@@ -25,6 +26,7 @@ impl From<usize> for Valid {
struct Invalid;
impl From<usize> for Invalid {
+ //~^ ERROR: consider implementing `TryFrom` instead
fn from(i: usize) -> Invalid {
if i != 42 {
panic!();
@@ -34,6 +36,7 @@ impl From<usize> for Invalid {
}
impl From<Option<String>> for Invalid {
+ //~^ ERROR: consider implementing `TryFrom` instead
fn from(s: Option<String>) -> Invalid {
let s = s.unwrap();
if !s.is_empty() {
@@ -52,6 +55,7 @@ impl<T> ProjStrTrait for Box<T> {
type ProjString = String;
}
impl<'a> From<&'a mut <Box<u32> as ProjStrTrait>::ProjString> for Invalid {
+ //~^ ERROR: consider implementing `TryFrom` instead
fn from(s: &'a mut <Box<u32> as ProjStrTrait>::ProjString) -> Invalid {
if s.parse::<u32>().ok().unwrap() != 42 {
panic!("{:?}", s);
diff --git a/src/tools/clippy/tests/ui/fallible_impl_from.stderr b/src/tools/clippy/tests/ui/fallible_impl_from.stderr
index 21761484f..96074ca89 100644
--- a/src/tools/clippy/tests/ui/fallible_impl_from.stderr
+++ b/src/tools/clippy/tests/ui/fallible_impl_from.stderr
@@ -2,6 +2,7 @@ error: consider implementing `TryFrom` instead
--> $DIR/fallible_impl_from.rs:6:1
|
LL | / impl From<String> for Foo {
+LL | |
LL | | fn from(s: String) -> Self {
LL | | Foo(s.parse().unwrap())
LL | | }
@@ -10,7 +11,7 @@ LL | | }
|
= help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
note: potential failure(s)
- --> $DIR/fallible_impl_from.rs:8:13
+ --> $DIR/fallible_impl_from.rs:9:13
|
LL | Foo(s.parse().unwrap())
| ^^^^^^^^^^^^^^^^^^
@@ -21,12 +22,12 @@ LL | #![deny(clippy::fallible_impl_from)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: consider implementing `TryFrom` instead
- --> $DIR/fallible_impl_from.rs:27:1
+ --> $DIR/fallible_impl_from.rs:28:1
|
LL | / impl From<usize> for Invalid {
+LL | |
LL | | fn from(i: usize) -> Invalid {
LL | | if i != 42 {
-LL | | panic!();
... |
LL | | }
LL | | }
@@ -34,19 +35,19 @@ LL | | }
|
= help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
note: potential failure(s)
- --> $DIR/fallible_impl_from.rs:30:13
+ --> $DIR/fallible_impl_from.rs:32:13
|
LL | panic!();
| ^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: consider implementing `TryFrom` instead
- --> $DIR/fallible_impl_from.rs:36:1
+ --> $DIR/fallible_impl_from.rs:38:1
|
LL | / impl From<Option<String>> for Invalid {
+LL | |
LL | | fn from(s: Option<String>) -> Invalid {
LL | | let s = s.unwrap();
-LL | | if !s.is_empty() {
... |
LL | | }
LL | | }
@@ -54,7 +55,7 @@ LL | | }
|
= help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
note: potential failure(s)
- --> $DIR/fallible_impl_from.rs:38:17
+ --> $DIR/fallible_impl_from.rs:41:17
|
LL | let s = s.unwrap();
| ^^^^^^^^^^
@@ -68,12 +69,12 @@ LL | panic!("{:?}", s);
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: consider implementing `TryFrom` instead
- --> $DIR/fallible_impl_from.rs:54:1
+ --> $DIR/fallible_impl_from.rs:57:1
|
LL | / impl<'a> From<&'a mut <Box<u32> as ProjStrTrait>::ProjString> for Invalid {
+LL | |
LL | | fn from(s: &'a mut <Box<u32> as ProjStrTrait>::ProjString) -> Invalid {
LL | | if s.parse::<u32>().ok().unwrap() != 42 {
-LL | | panic!("{:?}", s);
... |
LL | | }
LL | | }
@@ -81,7 +82,7 @@ LL | | }
|
= help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
note: potential failure(s)
- --> $DIR/fallible_impl_from.rs:56:12
+ --> $DIR/fallible_impl_from.rs:60:12
|
LL | if s.parse::<u32>().ok().unwrap() != 42 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.rs b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
index d6df114b8..2045b1eeb 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.rs
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
@@ -1,5 +1,5 @@
-//@aux-build:proc_macro_derive.rs:proc-macro
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
+//@aux-build:proc_macros.rs
#![warn(clippy::field_reassign_with_default)]
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
index da74f9ef9..a8cf84bd4 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
@@ -10,6 +10,7 @@ note: consider initializing the variable with `main::A { i: 42, ..Default::defau
LL | let mut a: A = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::field_reassign_with_default)]`
error: field assignment outside of initializer for an instance created with Default::default()
--> $DIR/field_reassign_with_default.rs:96:5
diff --git a/src/tools/clippy/tests/ui/filetype_is_file.rs b/src/tools/clippy/tests/ui/filetype_is_file.rs
index d3ad36e40..9e8a4c043 100644
--- a/src/tools/clippy/tests/ui/filetype_is_file.rs
+++ b/src/tools/clippy/tests/ui/filetype_is_file.rs
@@ -7,16 +7,19 @@ fn main() -> std::io::Result<()> {
// !filetype.is_dir()
if fs::metadata("foo.txt")?.file_type().is_file() {
+ //~^ ERROR: `FileType::is_file()` only covers regular files
// read file
}
// positive of filetype.is_dir()
if !fs::metadata("foo.txt")?.file_type().is_file() {
+ //~^ ERROR: `!FileType::is_file()` only denies regular files
// handle dir
}
// false positive of filetype.is_dir()
if !fs::metadata("foo.txt")?.file_type().is_file().bitor(true) {
+ //~^ ERROR: `FileType::is_file()` only covers regular files
// ...
}
diff --git a/src/tools/clippy/tests/ui/filetype_is_file.stderr b/src/tools/clippy/tests/ui/filetype_is_file.stderr
index 36142deb3..8876ad5c9 100644
--- a/src/tools/clippy/tests/ui/filetype_is_file.stderr
+++ b/src/tools/clippy/tests/ui/filetype_is_file.stderr
@@ -6,9 +6,10 @@ LL | if fs::metadata("foo.txt")?.file_type().is_file() {
|
= help: use `!FileType::is_dir()` instead
= note: `-D clippy::filetype-is-file` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filetype_is_file)]`
error: `!FileType::is_file()` only denies regular files
- --> $DIR/filetype_is_file.rs:14:8
+ --> $DIR/filetype_is_file.rs:15:8
|
LL | if !fs::metadata("foo.txt")?.file_type().is_file() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | if !fs::metadata("foo.txt")?.file_type().is_file() {
= help: use `FileType::is_dir()` instead
error: `FileType::is_file()` only covers regular files
- --> $DIR/filetype_is_file.rs:19:9
+ --> $DIR/filetype_is_file.rs:21:9
|
LL | if !fs::metadata("foo.txt")?.file_type().is_file().bitor(true) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
index e5c9f783f..6a1b81fdb 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(
clippy::clone_on_copy,
clippy::map_identity,
@@ -56,3 +55,27 @@ fn main() {
fn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {
iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()
}
+
+fn issue11503() {
+ let bools: &[bool] = &[true, false, false, true];
+ let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| *b).map(|(i, b)| i).collect();
+
+ // Need to insert multiple derefs if there is more than one layer of references
+ let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];
+ let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ***b).map(|(i, b)| i).collect();
+
+ // Should also suggest derefs when going through a mutable reference
+ let bools: &[&mut bool] = &[&mut true];
+ let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| **b).map(|(i, b)| i).collect();
+
+ // Should also suggest derefs when going through a custom deref
+ struct DerefToBool;
+ impl std::ops::Deref for DerefToBool {
+ type Target = bool;
+ fn deref(&self) -> &Self::Target {
+ &true
+ }
+ }
+ let bools: &[&&DerefToBool] = &[&&DerefToBool];
+ let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ****b).map(|(i, b)| i).collect();
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.rs b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
index 7c9b99df7..a41e88f88 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.rs
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(
clippy::clone_on_copy,
clippy::map_identity,
@@ -56,3 +55,27 @@ fn main() {
fn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {
iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()
}
+
+fn issue11503() {
+ let bools: &[bool] = &[true, false, false, true];
+ let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+ // Need to insert multiple derefs if there is more than one layer of references
+ let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];
+ let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+ // Should also suggest derefs when going through a mutable reference
+ let bools: &[&mut bool] = &[&mut true];
+ let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+ // Should also suggest derefs when going through a custom deref
+ struct DerefToBool;
+ impl std::ops::Deref for DerefToBool {
+ type Target = bool;
+ fn deref(&self) -> &Self::Target {
+ &true
+ }
+ }
+ let bools: &[&&DerefToBool] = &[&&DerefToBool];
+ let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
index fffa5252e..fab698791 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
@@ -1,40 +1,65 @@
error: usage of `bool::then` in `filter_map`
- --> $DIR/filter_map_bool_then.rs:20:22
+ --> $DIR/filter_map_bool_then.rs:19:22
|
LL | v.clone().iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`
|
= note: `-D clippy::filter-map-bool-then` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filter_map_bool_then)]`
error: usage of `bool::then` in `filter_map`
- --> $DIR/filter_map_bool_then.rs:21:27
+ --> $DIR/filter_map_bool_then.rs:20:27
|
LL | v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`
error: usage of `bool::then` in `filter_map`
- --> $DIR/filter_map_bool_then.rs:24:10
+ --> $DIR/filter_map_bool_then.rs:23:10
|
LL | .filter_map(|i| -> Option<_> { (i % 2 == 0).then(|| i + 1) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`
error: usage of `bool::then` in `filter_map`
- --> $DIR/filter_map_bool_then.rs:28:10
+ --> $DIR/filter_map_bool_then.rs:27:10
|
LL | .filter_map(|i| (i % 2 == 0).then(|| i + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`
error: usage of `bool::then` in `filter_map`
- --> $DIR/filter_map_bool_then.rs:32:10
+ --> $DIR/filter_map_bool_then.rs:31:10
|
LL | .filter_map(|i| (i.clone() % 2 == 0).then(|| i + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i.clone() % 2 == 0)).map(|i| i + 1)`
error: usage of `bool::then` in `filter_map`
- --> $DIR/filter_map_bool_then.rs:38:22
+ --> $DIR/filter_map_bool_then.rs:37:22
|
LL | v.clone().iter().filter_map(|i| (i == &NonCopy).then(|| i));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i == &NonCopy)).map(|i| i)`
-error: aborting due to 6 previous errors
+error: usage of `bool::then` in `filter_map`
+ --> $DIR/filter_map_bool_then.rs:61:50
+ |
+LL | let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| *b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+ --> $DIR/filter_map_bool_then.rs:65:50
+ |
+LL | let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ***b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+ --> $DIR/filter_map_bool_then.rs:69:50
+ |
+LL | let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| **b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+ --> $DIR/filter_map_bool_then.rs:80:50
+ |
+LL | let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ****b).map(|(i, b)| i)`
+
+error: aborting due to 10 previous errors
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.fixed b/src/tools/clippy/tests/ui/filter_map_identity.fixed
index 44665b451..ad438afac 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_identity.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::filter_map_identity)]
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.rs b/src/tools/clippy/tests/ui/filter_map_identity.rs
index 9832acb01..d74232768 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.rs
+++ b/src/tools/clippy/tests/ui/filter_map_identity.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::filter_map_identity)]
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.stderr b/src/tools/clippy/tests/ui/filter_map_identity.stderr
index 43c9fdca4..a08477695 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_identity.stderr
@@ -1,25 +1,26 @@
error: use of `filter_map` with an identity function
- --> $DIR/filter_map_identity.rs:8:22
+ --> $DIR/filter_map_identity.rs:6:22
|
LL | let _ = iterator.filter_map(|x| x);
| ^^^^^^^^^^^^^^^^^ help: try: `flatten()`
|
= note: `-D clippy::filter-map-identity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filter_map_identity)]`
error: use of `filter_map` with an identity function
- --> $DIR/filter_map_identity.rs:11:22
+ --> $DIR/filter_map_identity.rs:9:22
|
LL | let _ = iterator.filter_map(std::convert::identity);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
error: use of `filter_map` with an identity function
- --> $DIR/filter_map_identity.rs:15:22
+ --> $DIR/filter_map_identity.rs:13:22
|
LL | let _ = iterator.filter_map(identity);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
error: use of `filter_map` with an identity function
- --> $DIR/filter_map_identity.rs:18:22
+ --> $DIR/filter_map_identity.rs:16:22
|
LL | let _ = iterator.filter_map(|x| return x);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
diff --git a/src/tools/clippy/tests/ui/filter_map_next.rs b/src/tools/clippy/tests/ui/filter_map_next.rs
index dbeb23543..9077b8fca 100644
--- a/src/tools/clippy/tests/ui/filter_map_next.rs
+++ b/src/tools/clippy/tests/ui/filter_map_next.rs
@@ -5,6 +5,8 @@ fn main() {
#[rustfmt::skip]
let _: Option<u32> = vec![1, 2, 3, 4, 5, 6]
+ //~^ ERROR: called `filter_map(..).next()` on an `Iterator`. This is more succinctly e
+ //~| NOTE: `-D clippy::filter-map-next` implied by `-D warnings`
.into_iter()
.filter_map(|x| {
if x == 2 {
diff --git a/src/tools/clippy/tests/ui/filter_map_next.stderr b/src/tools/clippy/tests/ui/filter_map_next.stderr
index ddc982c93..184155391 100644
--- a/src/tools/clippy/tests/ui/filter_map_next.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_next.stderr
@@ -3,15 +3,16 @@ error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly
|
LL | let _: Option<u32> = vec![1, 2, 3, 4, 5, 6]
| __________________________^
+LL | |
+LL | |
LL | | .into_iter()
-LL | | .filter_map(|x| {
-LL | | if x == 2 {
... |
LL | | })
LL | | .next();
| |_______________^
|
= note: `-D clippy::filter-map-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filter_map_next)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed b/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed
index efb37f8b1..193ac3aea 100644
--- a/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all, clippy::pedantic)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/filter_map_next_fixable.rs b/src/tools/clippy/tests/ui/filter_map_next_fixable.rs
index b10e20d35..dab8d2898 100644
--- a/src/tools/clippy/tests/ui/filter_map_next_fixable.rs
+++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all, clippy::pedantic)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/filter_map_next_fixable.stderr b/src/tools/clippy/tests/ui/filter_map_next_fixable.stderr
index 26d9c5e19..0edf4e6e0 100644
--- a/src/tools/clippy/tests/ui/filter_map_next_fixable.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.stderr
@@ -1,13 +1,14 @@
error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead
- --> $DIR/filter_map_next_fixable.rs:9:32
+ --> $DIR/filter_map_next_fixable.rs:7:32
|
LL | let element: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.iter().find_map(|s| s.parse().ok())`
|
= note: `-D clippy::filter-map-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filter_map_next)]`
error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead
- --> $DIR/filter_map_next_fixable.rs:22:26
+ --> $DIR/filter_map_next_fixable.rs:20:26
|
LL | let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.iter().find_map(|s| s.parse().ok())`
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.fixed b/src/tools/clippy/tests/ui/flat_map_identity.fixed
index 97091d6f1..c142cf719 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.fixed
+++ b/src/tools/clippy/tests/ui/flat_map_identity.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::flat_map_identity)]
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.rs b/src/tools/clippy/tests/ui/flat_map_identity.rs
index 5607683a5..8505ba900 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.rs
+++ b/src/tools/clippy/tests/ui/flat_map_identity.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::flat_map_identity)]
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.stderr b/src/tools/clippy/tests/ui/flat_map_identity.stderr
index e776c9fdf..d6fcc14fc 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.stderr
+++ b/src/tools/clippy/tests/ui/flat_map_identity.stderr
@@ -1,19 +1,20 @@
error: use of `flat_map` with an identity function
- --> $DIR/flat_map_identity.rs:10:22
+ --> $DIR/flat_map_identity.rs:8:22
|
LL | let _ = iterator.flat_map(|x| x);
| ^^^^^^^^^^^^^^^ help: try: `flatten()`
|
= note: `-D clippy::flat-map-identity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::flat_map_identity)]`
error: use of `flat_map` with an identity function
- --> $DIR/flat_map_identity.rs:13:22
+ --> $DIR/flat_map_identity.rs:11:22
|
LL | let _ = iterator.flat_map(convert::identity);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
error: use of `flat_map` with an identity function
- --> $DIR/flat_map_identity.rs:16:22
+ --> $DIR/flat_map_identity.rs:14:22
|
LL | let _ = iterator.flat_map(|x| return x);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
diff --git a/src/tools/clippy/tests/ui/flat_map_option.fixed b/src/tools/clippy/tests/ui/flat_map_option.fixed
index eeab864c4..e08d9a145 100644
--- a/src/tools/clippy/tests/ui/flat_map_option.fixed
+++ b/src/tools/clippy/tests/ui/flat_map_option.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::flat_map_option)]
#![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)]
diff --git a/src/tools/clippy/tests/ui/flat_map_option.rs b/src/tools/clippy/tests/ui/flat_map_option.rs
index ebc389f7f..4d0f32ac0 100644
--- a/src/tools/clippy/tests/ui/flat_map_option.rs
+++ b/src/tools/clippy/tests/ui/flat_map_option.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::flat_map_option)]
#![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)]
diff --git a/src/tools/clippy/tests/ui/flat_map_option.stderr b/src/tools/clippy/tests/ui/flat_map_option.stderr
index a9d8056de..e0a59daf6 100644
--- a/src/tools/clippy/tests/ui/flat_map_option.stderr
+++ b/src/tools/clippy/tests/ui/flat_map_option.stderr
@@ -1,13 +1,14 @@
error: used `flat_map` where `filter_map` could be used instead
- --> $DIR/flat_map_option.rs:8:24
+ --> $DIR/flat_map_option.rs:7:24
|
LL | let _ = [1].iter().flat_map(c);
| ^^^^^^^^ help: try: `filter_map`
|
= note: `-D clippy::flat-map-option` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::flat_map_option)]`
error: used `flat_map` where `filter_map` could be used instead
- --> $DIR/flat_map_option.rs:9:24
+ --> $DIR/flat_map_option.rs:8:24
|
LL | let _ = [1].iter().flat_map(Some);
| ^^^^^^^^ help: try: `filter_map`
diff --git a/src/tools/clippy/tests/ui/float_arithmetic.rs b/src/tools/clippy/tests/ui/float_arithmetic.rs
index a928c35e8..1647273c4 100644
--- a/src/tools/clippy/tests/ui/float_arithmetic.rs
+++ b/src/tools/clippy/tests/ui/float_arithmetic.rs
@@ -13,40 +13,58 @@ fn main() {
let mut f = 1.0f32;
f * 2.0;
+ //~^ ERROR: floating-point arithmetic detected
+ //~| NOTE: `-D clippy::float-arithmetic` implied by `-D warnings`
1.0 + f;
+ //~^ ERROR: floating-point arithmetic detected
f * 2.0;
+ //~^ ERROR: floating-point arithmetic detected
f / 2.0;
+ //~^ ERROR: floating-point arithmetic detected
f - 2.0 * 4.2;
+ //~^ ERROR: floating-point arithmetic detected
-f;
+ //~^ ERROR: floating-point arithmetic detected
f += 1.0;
+ //~^ ERROR: floating-point arithmetic detected
f -= 1.0;
+ //~^ ERROR: floating-point arithmetic detected
f *= 2.0;
+ //~^ ERROR: floating-point arithmetic detected
f /= 2.0;
+ //~^ ERROR: floating-point arithmetic detected
}
// also warn about floating point arith with references involved
pub fn float_arith_ref() {
3.1_f32 + &1.2_f32;
+ //~^ ERROR: floating-point arithmetic detected
&3.4_f32 + 1.5_f32;
+ //~^ ERROR: floating-point arithmetic detected
&3.5_f32 + &1.3_f32;
+ //~^ ERROR: floating-point arithmetic detected
}
pub fn float_foo(f: &f32) -> f32 {
let a = 5.1;
a + f
+ //~^ ERROR: floating-point arithmetic detected
}
pub fn float_bar(f1: &f32, f2: &f32) -> f32 {
f1 + f2
+ //~^ ERROR: floating-point arithmetic detected
}
pub fn float_baz(f1: f32, f2: &f32) -> f32 {
f1 + f2
+ //~^ ERROR: floating-point arithmetic detected
}
pub fn float_qux(f1: f32, f2: f32) -> f32 {
(&f1 + &f2)
+ //~^ ERROR: floating-point arithmetic detected
}
diff --git a/src/tools/clippy/tests/ui/float_arithmetic.stderr b/src/tools/clippy/tests/ui/float_arithmetic.stderr
index 1ceffb35b..da4ca9767 100644
--- a/src/tools/clippy/tests/ui/float_arithmetic.stderr
+++ b/src/tools/clippy/tests/ui/float_arithmetic.stderr
@@ -5,99 +5,100 @@ LL | f * 2.0;
| ^^^^^^^
|
= note: `-D clippy::float-arithmetic` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::float_arithmetic)]`
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:17:5
+ --> $DIR/float_arithmetic.rs:19:5
|
LL | 1.0 + f;
| ^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:18:5
+ --> $DIR/float_arithmetic.rs:21:5
|
LL | f * 2.0;
| ^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:19:5
+ --> $DIR/float_arithmetic.rs:23:5
|
LL | f / 2.0;
| ^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:20:5
+ --> $DIR/float_arithmetic.rs:25:5
|
LL | f - 2.0 * 4.2;
| ^^^^^^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:21:5
+ --> $DIR/float_arithmetic.rs:27:5
|
LL | -f;
| ^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:23:5
+ --> $DIR/float_arithmetic.rs:30:5
|
LL | f += 1.0;
| ^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:24:5
+ --> $DIR/float_arithmetic.rs:32:5
|
LL | f -= 1.0;
| ^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:25:5
+ --> $DIR/float_arithmetic.rs:34:5
|
LL | f *= 2.0;
| ^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:26:5
+ --> $DIR/float_arithmetic.rs:36:5
|
LL | f /= 2.0;
| ^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:32:5
+ --> $DIR/float_arithmetic.rs:43:5
|
LL | 3.1_f32 + &1.2_f32;
| ^^^^^^^^^^^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:33:5
+ --> $DIR/float_arithmetic.rs:45:5
|
LL | &3.4_f32 + 1.5_f32;
| ^^^^^^^^^^^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:34:5
+ --> $DIR/float_arithmetic.rs:47:5
|
LL | &3.5_f32 + &1.3_f32;
| ^^^^^^^^^^^^^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:39:5
+ --> $DIR/float_arithmetic.rs:53:5
|
LL | a + f
| ^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:43:5
+ --> $DIR/float_arithmetic.rs:58:5
|
LL | f1 + f2
| ^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:47:5
+ --> $DIR/float_arithmetic.rs:63:5
|
LL | f1 + f2
| ^^^^^^^
error: floating-point arithmetic detected
- --> $DIR/float_arithmetic.rs:51:5
+ --> $DIR/float_arithmetic.rs:68:5
|
LL | (&f1 + &f2)
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/float_cmp.rs b/src/tools/clippy/tests/ui/float_cmp.rs
index a34458b94..5057c6437 100644
--- a/src/tools/clippy/tests/ui/float_cmp.rs
+++ b/src/tools/clippy/tests/ui/float_cmp.rs
@@ -6,7 +6,7 @@
clippy::unnecessary_operation,
clippy::cast_lossless
)]
-
+//@no-rustfix
use std::ops::Add;
const ZERO: f32 = 0.0;
@@ -41,6 +41,16 @@ impl PartialEq for X {
}
}
+impl PartialEq<f32> for X {
+ fn eq(&self, o: &f32) -> bool {
+ if self.val.is_nan() {
+ o.is_nan()
+ } else {
+ self.val == *o // no error, inside "eq" fn
+ }
+ }
+}
+
fn main() {
ZERO == 0f32; //no error, comparison with zero is ok
1.0f32 != f32::INFINITY; // also comparison with infinity
@@ -48,6 +58,9 @@ fn main() {
ZERO == 0.0; //no error, comparison with zero is ok
ZERO + ZERO != 1.0; //no error, comparison with zero is ok
+ let x = X { val: 1.0 };
+ x == 1.0; // no error, custom type that implement PartialOrder for float is not checked
+
ONE == 1f32;
ONE == 1.0 + 0.0;
ONE + ONE == ZERO + ONE + ONE;
@@ -55,14 +68,20 @@ fn main() {
ONE != 0.0; // no error, comparison with zero is ok
twice(ONE) != ONE;
ONE as f64 != 2.0;
+ //~^ ERROR: strict comparison of `f32` or `f64`
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
ONE as f64 != 0.0; // no error, comparison with zero is ok
let x: f64 = 1.0;
x == 1.0;
+ //~^ ERROR: strict comparison of `f32` or `f64`
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
x != 0f64; // no error, comparison with zero is ok
twice(x) != twice(ONE as f64);
+ //~^ ERROR: strict comparison of `f32` or `f64`
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
x < 0.0; // no errors, lower or greater comparisons need no fuzzyness
x > 0.0;
@@ -83,12 +102,18 @@ fn main() {
ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; // ok, because lhs is zero regardless of i
NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];
+ //~^ ERROR: strict comparison of `f32` or `f64`
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
let a1: [f32; 1] = [0.0];
let a2: [f32; 1] = [1.1];
a1 == a2;
+ //~^ ERROR: strict comparison of `f32` or `f64` arrays
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
a1[0] == a2[0];
+ //~^ ERROR: strict comparison of `f32` or `f64`
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
// no errors - comparing signums is ok
let x32 = 3.21f32;
diff --git a/src/tools/clippy/tests/ui/float_cmp.stderr b/src/tools/clippy/tests/ui/float_cmp.stderr
index e3e9f3949..217e29879 100644
--- a/src/tools/clippy/tests/ui/float_cmp.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp.stderr
@@ -1,14 +1,15 @@
error: strict comparison of `f32` or `f64`
- --> $DIR/float_cmp.rs:57:5
+ --> $DIR/float_cmp.rs:70:5
|
LL | ONE as f64 != 2.0;
| ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin`
|
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
= note: `-D clippy::float-cmp` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::float_cmp)]`
error: strict comparison of `f32` or `f64`
- --> $DIR/float_cmp.rs:62:5
+ --> $DIR/float_cmp.rs:77:5
|
LL | x == 1.0;
| ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin`
@@ -16,7 +17,7 @@ LL | x == 1.0;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64`
- --> $DIR/float_cmp.rs:65:5
+ --> $DIR/float_cmp.rs:82:5
|
LL | twice(x) != twice(ONE as f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin`
@@ -24,7 +25,7 @@ LL | twice(x) != twice(ONE as f64);
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64`
- --> $DIR/float_cmp.rs:85:5
+ --> $DIR/float_cmp.rs:104:5
|
LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin`
@@ -32,7 +33,7 @@ LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64` arrays
- --> $DIR/float_cmp.rs:90:5
+ --> $DIR/float_cmp.rs:111:5
|
LL | a1 == a2;
| ^^^^^^^^
@@ -40,7 +41,7 @@ LL | a1 == a2;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64`
- --> $DIR/float_cmp.rs:91:5
+ --> $DIR/float_cmp.rs:114:5
|
LL | a1[0] == a2[0];
| ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin`
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.rs b/src/tools/clippy/tests/ui/float_cmp_const.rs
index 86ce3bf3b..47ea0e19c 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.rs
+++ b/src/tools/clippy/tests/ui/float_cmp_const.rs
@@ -1,5 +1,5 @@
// does not test any rustfixable lints
-
+//@no-rustfix
#![warn(clippy::float_cmp_const)]
#![allow(clippy::float_cmp)]
#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]
@@ -14,15 +14,29 @@ fn eq_one(x: f32) -> bool {
fn main() {
// has errors
1f32 == ONE;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
TWO == ONE;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
TWO != ONE;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
ONE + ONE == TWO;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
let x = 1;
x as f32 == ONE;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
let v = 0.9;
v == ONE;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
v != ONE;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
// no errors, lower than or greater than comparisons
v < ONE;
@@ -55,4 +69,6 @@ fn main() {
// has errors
NON_ZERO_ARRAY == NON_ZERO_ARRAY2;
+ //~^ ERROR: strict comparison of `f32` or `f64` constant arrays
+ //~| NOTE: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
}
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.stderr b/src/tools/clippy/tests/ui/float_cmp_const.stderr
index 65c45648a..856aaa2ea 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp_const.stderr
@@ -6,9 +6,10 @@ LL | 1f32 == ONE;
|
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
= note: `-D clippy::float-cmp-const` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::float_cmp_const)]`
error: strict comparison of `f32` or `f64` constant
- --> $DIR/float_cmp_const.rs:17:5
+ --> $DIR/float_cmp_const.rs:19:5
|
LL | TWO == ONE;
| ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin`
@@ -16,7 +17,7 @@ LL | TWO == ONE;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64` constant
- --> $DIR/float_cmp_const.rs:18:5
+ --> $DIR/float_cmp_const.rs:22:5
|
LL | TWO != ONE;
| ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin`
@@ -24,7 +25,7 @@ LL | TWO != ONE;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64` constant
- --> $DIR/float_cmp_const.rs:19:5
+ --> $DIR/float_cmp_const.rs:25:5
|
LL | ONE + ONE == TWO;
| ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin`
@@ -32,7 +33,7 @@ LL | ONE + ONE == TWO;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64` constant
- --> $DIR/float_cmp_const.rs:21:5
+ --> $DIR/float_cmp_const.rs:29:5
|
LL | x as f32 == ONE;
| ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin`
@@ -40,7 +41,7 @@ LL | x as f32 == ONE;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64` constant
- --> $DIR/float_cmp_const.rs:24:5
+ --> $DIR/float_cmp_const.rs:34:5
|
LL | v == ONE;
| ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin`
@@ -48,7 +49,7 @@ LL | v == ONE;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64` constant
- --> $DIR/float_cmp_const.rs:25:5
+ --> $DIR/float_cmp_const.rs:37:5
|
LL | v != ONE;
| ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin`
@@ -56,7 +57,7 @@ LL | v != ONE;
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
error: strict comparison of `f32` or `f64` constant arrays
- --> $DIR/float_cmp_const.rs:57:5
+ --> $DIR/float_cmp_const.rs:71:5
|
LL | NON_ZERO_ARRAY == NON_ZERO_ARRAY2;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/float_equality_without_abs.rs b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
index d40fa00c3..6363472d8 100644
--- a/src/tools/clippy/tests/ui/float_equality_without_abs.rs
+++ b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
@@ -1,7 +1,9 @@
#![warn(clippy::float_equality_without_abs)]
-
+//@no-rustfix
pub fn is_roughly_equal(a: f32, b: f32) -> bool {
(a - b) < f32::EPSILON
+ //~^ ERROR: float equality check without `.abs()`
+ //~| NOTE: `-D clippy::float-equality-without-abs` implied by `-D warnings`
}
pub fn main() {
@@ -11,16 +13,26 @@ pub fn main() {
let b = 0.0500001;
let _ = (a - b) < f32::EPSILON;
+ //~^ ERROR: float equality check without `.abs()`
let _ = a - b < f32::EPSILON;
+ //~^ ERROR: float equality check without `.abs()`
let _ = a - b.abs() < f32::EPSILON;
+ //~^ ERROR: float equality check without `.abs()`
let _ = (a as f64 - b as f64) < f64::EPSILON;
+ //~^ ERROR: float equality check without `.abs()`
let _ = 1.0 - 2.0 < f32::EPSILON;
+ //~^ ERROR: float equality check without `.abs()`
let _ = f32::EPSILON > (a - b);
+ //~^ ERROR: float equality check without `.abs()`
let _ = f32::EPSILON > a - b;
+ //~^ ERROR: float equality check without `.abs()`
let _ = f32::EPSILON > a - b.abs();
+ //~^ ERROR: float equality check without `.abs()`
let _ = f64::EPSILON > (a as f64 - b as f64);
+ //~^ ERROR: float equality check without `.abs()`
let _ = f32::EPSILON > 1.0 - 2.0;
+ //~^ ERROR: float equality check without `.abs()`
// those are correct
let _ = (a - b).abs() < f32::EPSILON;
diff --git a/src/tools/clippy/tests/ui/float_equality_without_abs.stderr b/src/tools/clippy/tests/ui/float_equality_without_abs.stderr
index b34c8159d..155699f6f 100644
--- a/src/tools/clippy/tests/ui/float_equality_without_abs.stderr
+++ b/src/tools/clippy/tests/ui/float_equality_without_abs.stderr
@@ -7,9 +7,10 @@ LL | (a - b) < f32::EPSILON
| help: add `.abs()`: `(a - b).abs()`
|
= note: `-D clippy::float-equality-without-abs` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::float_equality_without_abs)]`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:13:13
+ --> $DIR/float_equality_without_abs.rs:15:13
|
LL | let _ = (a - b) < f32::EPSILON;
| -------^^^^^^^^^^^^^^^
@@ -17,7 +18,7 @@ LL | let _ = (a - b) < f32::EPSILON;
| help: add `.abs()`: `(a - b).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:14:13
+ --> $DIR/float_equality_without_abs.rs:17:13
|
LL | let _ = a - b < f32::EPSILON;
| -----^^^^^^^^^^^^^^^
@@ -25,7 +26,7 @@ LL | let _ = a - b < f32::EPSILON;
| help: add `.abs()`: `(a - b).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:15:13
+ --> $DIR/float_equality_without_abs.rs:19:13
|
LL | let _ = a - b.abs() < f32::EPSILON;
| -----------^^^^^^^^^^^^^^^
@@ -33,7 +34,7 @@ LL | let _ = a - b.abs() < f32::EPSILON;
| help: add `.abs()`: `(a - b.abs()).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:16:13
+ --> $DIR/float_equality_without_abs.rs:21:13
|
LL | let _ = (a as f64 - b as f64) < f64::EPSILON;
| ---------------------^^^^^^^^^^^^^^^
@@ -41,7 +42,7 @@ LL | let _ = (a as f64 - b as f64) < f64::EPSILON;
| help: add `.abs()`: `(a as f64 - b as f64).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:17:13
+ --> $DIR/float_equality_without_abs.rs:23:13
|
LL | let _ = 1.0 - 2.0 < f32::EPSILON;
| ---------^^^^^^^^^^^^^^^
@@ -49,7 +50,7 @@ LL | let _ = 1.0 - 2.0 < f32::EPSILON;
| help: add `.abs()`: `(1.0 - 2.0).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:19:13
+ --> $DIR/float_equality_without_abs.rs:26:13
|
LL | let _ = f32::EPSILON > (a - b);
| ^^^^^^^^^^^^^^^-------
@@ -57,7 +58,7 @@ LL | let _ = f32::EPSILON > (a - b);
| help: add `.abs()`: `(a - b).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:20:13
+ --> $DIR/float_equality_without_abs.rs:28:13
|
LL | let _ = f32::EPSILON > a - b;
| ^^^^^^^^^^^^^^^-----
@@ -65,7 +66,7 @@ LL | let _ = f32::EPSILON > a - b;
| help: add `.abs()`: `(a - b).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:21:13
+ --> $DIR/float_equality_without_abs.rs:30:13
|
LL | let _ = f32::EPSILON > a - b.abs();
| ^^^^^^^^^^^^^^^-----------
@@ -73,7 +74,7 @@ LL | let _ = f32::EPSILON > a - b.abs();
| help: add `.abs()`: `(a - b.abs()).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:22:13
+ --> $DIR/float_equality_without_abs.rs:32:13
|
LL | let _ = f64::EPSILON > (a as f64 - b as f64);
| ^^^^^^^^^^^^^^^---------------------
@@ -81,7 +82,7 @@ LL | let _ = f64::EPSILON > (a as f64 - b as f64);
| help: add `.abs()`: `(a as f64 - b as f64).abs()`
error: float equality check without `.abs()`
- --> $DIR/float_equality_without_abs.rs:23:13
+ --> $DIR/float_equality_without_abs.rs:34:13
|
LL | let _ = f32::EPSILON > 1.0 - 2.0;
| ^^^^^^^^^^^^^^^---------
diff --git a/src/tools/clippy/tests/ui/floating_point_abs.fixed b/src/tools/clippy/tests/ui/floating_point_abs.fixed
index 0cc572822..5312a8b29 100644
--- a/src/tools/clippy/tests/ui/floating_point_abs.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_abs.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_abs.rs b/src/tools/clippy/tests/ui/floating_point_abs.rs
index 6c732d398..861917713 100644
--- a/src/tools/clippy/tests/ui/floating_point_abs.rs
+++ b/src/tools/clippy/tests/ui/floating_point_abs.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_abs.stderr b/src/tools/clippy/tests/ui/floating_point_abs.stderr
index db8290423..fbc578382 100644
--- a/src/tools/clippy/tests/ui/floating_point_abs.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_abs.stderr
@@ -1,49 +1,50 @@
error: manual implementation of `abs` method
- --> $DIR/floating_point_abs.rs:16:5
+ --> $DIR/floating_point_abs.rs:15:5
|
LL | if num >= 0.0 { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
|
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
error: manual implementation of `abs` method
- --> $DIR/floating_point_abs.rs:20:5
+ --> $DIR/floating_point_abs.rs:19:5
|
LL | if 0.0 < num { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
error: manual implementation of `abs` method
- --> $DIR/floating_point_abs.rs:24:5
+ --> $DIR/floating_point_abs.rs:23:5
|
LL | if a.a > 0.0 { a.a } else { -a.a }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`
error: manual implementation of `abs` method
- --> $DIR/floating_point_abs.rs:28:5
+ --> $DIR/floating_point_abs.rs:27:5
|
LL | if 0.0 >= num { -num } else { num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
error: manual implementation of `abs` method
- --> $DIR/floating_point_abs.rs:32:5
+ --> $DIR/floating_point_abs.rs:31:5
|
LL | if a.a < 0.0 { -a.a } else { a.a }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`
error: manual implementation of negation of `abs` method
- --> $DIR/floating_point_abs.rs:36:5
+ --> $DIR/floating_point_abs.rs:35:5
|
LL | if num < 0.0 { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`
error: manual implementation of negation of `abs` method
- --> $DIR/floating_point_abs.rs:40:5
+ --> $DIR/floating_point_abs.rs:39:5
|
LL | if 0.0 >= num { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`
error: manual implementation of negation of `abs` method
- --> $DIR/floating_point_abs.rs:45:12
+ --> $DIR/floating_point_abs.rs:44:12
|
LL | a: if a.a >= 0.0 { -a.a } else { a.a },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-a.a.abs()`
diff --git a/src/tools/clippy/tests/ui/floating_point_exp.fixed b/src/tools/clippy/tests/ui/floating_point_exp.fixed
index 1a33b8153..15072bb1e 100644
--- a/src/tools/clippy/tests/ui/floating_point_exp.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_exp.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::imprecise_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_exp.rs b/src/tools/clippy/tests/ui/floating_point_exp.rs
index 4f4a5ec81..7d8b17946 100644
--- a/src/tools/clippy/tests/ui/floating_point_exp.rs
+++ b/src/tools/clippy/tests/ui/floating_point_exp.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::imprecise_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_exp.stderr b/src/tools/clippy/tests/ui/floating_point_exp.stderr
index b92fae56e..6b64b9b60 100644
--- a/src/tools/clippy/tests/ui/floating_point_exp.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_exp.stderr
@@ -1,31 +1,32 @@
error: (e.pow(x) - 1) can be computed more accurately
- --> $DIR/floating_point_exp.rs:7:13
+ --> $DIR/floating_point_exp.rs:6:13
|
LL | let _ = x.exp() - 1.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
|
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`
error: (e.pow(x) - 1) can be computed more accurately
- --> $DIR/floating_point_exp.rs:8:13
+ --> $DIR/floating_point_exp.rs:7:13
|
LL | let _ = x.exp() - 1.0 + 2.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
error: (e.pow(x) - 1) can be computed more accurately
- --> $DIR/floating_point_exp.rs:9:13
+ --> $DIR/floating_point_exp.rs:8:13
|
LL | let _ = (x as f32).exp() - 1.0 + 2.0;
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).exp_m1()`
error: (e.pow(x) - 1) can be computed more accurately
- --> $DIR/floating_point_exp.rs:15:13
+ --> $DIR/floating_point_exp.rs:14:13
|
LL | let _ = x.exp() - 1.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
error: (e.pow(x) - 1) can be computed more accurately
- --> $DIR/floating_point_exp.rs:16:13
+ --> $DIR/floating_point_exp.rs:15:13
|
LL | let _ = x.exp() - 1.0 + 2.0;
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`
diff --git a/src/tools/clippy/tests/ui/floating_point_hypot.fixed b/src/tools/clippy/tests/ui/floating_point_hypot.fixed
index 431cb2709..75a224440 100644
--- a/src/tools/clippy/tests/ui/floating_point_hypot.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_hypot.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::imprecise_flops)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/floating_point_hypot.rs b/src/tools/clippy/tests/ui/floating_point_hypot.rs
index e5506ed39..ed4dbf638 100644
--- a/src/tools/clippy/tests/ui/floating_point_hypot.rs
+++ b/src/tools/clippy/tests/ui/floating_point_hypot.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::imprecise_flops)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/floating_point_hypot.stderr b/src/tools/clippy/tests/ui/floating_point_hypot.stderr
index 42069d9ee..21e0bd8b5 100644
--- a/src/tools/clippy/tests/ui/floating_point_hypot.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_hypot.stderr
@@ -1,19 +1,20 @@
error: hypotenuse can be computed more accurately
- --> $DIR/floating_point_hypot.rs:7:13
+ --> $DIR/floating_point_hypot.rs:6:13
|
LL | let _ = (x * x + y * y).sqrt();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)`
|
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`
error: hypotenuse can be computed more accurately
- --> $DIR/floating_point_hypot.rs:8:13
+ --> $DIR/floating_point_hypot.rs:7:13
|
LL | let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 1f32).hypot(y)`
error: hypotenuse can be computed more accurately
- --> $DIR/floating_point_hypot.rs:9:13
+ --> $DIR/floating_point_hypot.rs:8:13
|
LL | let _ = (x.powi(2) + y.powi(2)).sqrt();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)`
diff --git a/src/tools/clippy/tests/ui/floating_point_log.fixed b/src/tools/clippy/tests/ui/floating_point_log.fixed
index 6582c0a0f..01f0fc5c6 100644
--- a/src/tools/clippy/tests/ui/floating_point_log.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_log.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)]
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_log.rs b/src/tools/clippy/tests/ui/floating_point_log.rs
index 854d269ff..197e3e1ff 100644
--- a/src/tools/clippy/tests/ui/floating_point_log.rs
+++ b/src/tools/clippy/tests/ui/floating_point_log.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)]
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_log.stderr b/src/tools/clippy/tests/ui/floating_point_log.stderr
index 89800a13a..a426f4c3d 100644
--- a/src/tools/clippy/tests/ui/floating_point_log.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_log.stderr
@@ -1,177 +1,179 @@
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:10:13
+ --> $DIR/floating_point_log.rs:9:13
|
LL | let _ = x.log(2f32);
| ^^^^^^^^^^^ help: consider using: `x.log2()`
|
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:11:13
+ --> $DIR/floating_point_log.rs:10:13
|
LL | let _ = x.log(10f32);
| ^^^^^^^^^^^^ help: consider using: `x.log10()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:12:13
+ --> $DIR/floating_point_log.rs:11:13
|
LL | let _ = x.log(std::f32::consts::E);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:13:13
+ --> $DIR/floating_point_log.rs:12:13
|
LL | let _ = x.log(TWO);
| ^^^^^^^^^^ help: consider using: `x.log2()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:14:13
+ --> $DIR/floating_point_log.rs:13:13
|
LL | let _ = x.log(E);
| ^^^^^^^^ help: consider using: `x.ln()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:15:13
+ --> $DIR/floating_point_log.rs:14:13
|
LL | let _ = (x as f32).log(2f32);
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log2()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:18:13
+ --> $DIR/floating_point_log.rs:17:13
|
LL | let _ = x.log(2f64);
| ^^^^^^^^^^^ help: consider using: `x.log2()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:19:13
+ --> $DIR/floating_point_log.rs:18:13
|
LL | let _ = x.log(10f64);
| ^^^^^^^^^^^^ help: consider using: `x.log10()`
error: logarithm for bases 2, 10 and e can be computed more accurately
- --> $DIR/floating_point_log.rs:20:13
+ --> $DIR/floating_point_log.rs:19:13
|
LL | let _ = x.log(std::f64::consts::E);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:25:13
+ --> $DIR/floating_point_log.rs:24:13
|
LL | let _ = (1f32 + 2.).ln();
| ^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()`
|
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:26:13
+ --> $DIR/floating_point_log.rs:25:13
|
LL | let _ = (1f32 + 2.0).ln();
| ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:27:13
+ --> $DIR/floating_point_log.rs:26:13
|
LL | let _ = (1.0 + x).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:28:13
+ --> $DIR/floating_point_log.rs:27:13
|
LL | let _ = (1.0 + x / 2.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:29:13
+ --> $DIR/floating_point_log.rs:28:13
|
LL | let _ = (1.0 + x.powi(3)).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:30:13
+ --> $DIR/floating_point_log.rs:29:13
|
LL | let _ = (1.0 + x.powi(3) / 2.0).ln();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(3) / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:31:13
+ --> $DIR/floating_point_log.rs:30:13
|
LL | let _ = (1.0 + (std::f32::consts::E - 1.0)).ln();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(std::f32::consts::E - 1.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:32:13
+ --> $DIR/floating_point_log.rs:31:13
|
LL | let _ = (x + 1.0).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:33:13
+ --> $DIR/floating_point_log.rs:32:13
|
LL | let _ = (x.powi(3) + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:34:13
+ --> $DIR/floating_point_log.rs:33:13
|
LL | let _ = (x + 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:35:13
+ --> $DIR/floating_point_log.rs:34:13
|
LL | let _ = (x / 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:43:13
+ --> $DIR/floating_point_log.rs:42:13
|
LL | let _ = (1f64 + 2.).ln();
| ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:44:13
+ --> $DIR/floating_point_log.rs:43:13
|
LL | let _ = (1f64 + 2.0).ln();
| ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:45:13
+ --> $DIR/floating_point_log.rs:44:13
|
LL | let _ = (1.0 + x).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:46:13
+ --> $DIR/floating_point_log.rs:45:13
|
LL | let _ = (1.0 + x / 2.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:47:13
+ --> $DIR/floating_point_log.rs:46:13
|
LL | let _ = (1.0 + x.powi(3)).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:48:13
+ --> $DIR/floating_point_log.rs:47:13
|
LL | let _ = (x + 1.0).ln();
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:49:13
+ --> $DIR/floating_point_log.rs:48:13
|
LL | let _ = (x.powi(3) + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:50:13
+ --> $DIR/floating_point_log.rs:49:13
|
LL | let _ = (x + 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()`
error: ln(1 + x) can be computed more accurately
- --> $DIR/floating_point_log.rs:51:13
+ --> $DIR/floating_point_log.rs:50:13
|
LL | let _ = (x / 2.0 + 1.0).ln();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`
diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.fixed b/src/tools/clippy/tests/ui/floating_point_logbase.fixed
index 0783ecee1..451673d10 100644
--- a/src/tools/clippy/tests/ui/floating_point_logbase.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_logbase.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suboptimal_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.rs b/src/tools/clippy/tests/ui/floating_point_logbase.rs
index 80fcfab68..c30911459 100644
--- a/src/tools/clippy/tests/ui/floating_point_logbase.rs
+++ b/src/tools/clippy/tests/ui/floating_point_logbase.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suboptimal_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.stderr b/src/tools/clippy/tests/ui/floating_point_logbase.stderr
index 9d736b5e1..463bdb84c 100644
--- a/src/tools/clippy/tests/ui/floating_point_logbase.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_logbase.stderr
@@ -1,31 +1,32 @@
error: log base can be expressed more clearly
- --> $DIR/floating_point_logbase.rs:8:13
+ --> $DIR/floating_point_logbase.rs:7:13
|
LL | let _ = x.ln() / y.ln();
| ^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
|
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
error: log base can be expressed more clearly
- --> $DIR/floating_point_logbase.rs:9:13
+ --> $DIR/floating_point_logbase.rs:8:13
|
LL | let _ = (x as f32).ln() / y.ln();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log(y)`
error: log base can be expressed more clearly
- --> $DIR/floating_point_logbase.rs:10:13
+ --> $DIR/floating_point_logbase.rs:9:13
|
LL | let _ = x.log2() / y.log2();
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
error: log base can be expressed more clearly
- --> $DIR/floating_point_logbase.rs:11:13
+ --> $DIR/floating_point_logbase.rs:10:13
|
LL | let _ = x.log10() / y.log10();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
error: log base can be expressed more clearly
- --> $DIR/floating_point_logbase.rs:12:13
+ --> $DIR/floating_point_logbase.rs:11:13
|
LL | let _ = x.log(5f32) / y.log(5f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
index 8848981a1..c23f4d7c4 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
index b0edf5cb2..431badc8d 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
index a79ae94e8..81b7126db 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
@@ -1,73 +1,74 @@
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:21:13
+ --> $DIR/floating_point_mul_add.rs:20:13
|
LL | let _ = a * b + c;
| ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
|
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:22:13
+ --> $DIR/floating_point_mul_add.rs:21:13
|
LL | let _ = a * b - c;
| ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:23:13
+ --> $DIR/floating_point_mul_add.rs:22:13
|
LL | let _ = c + a * b;
| ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:24:13
+ --> $DIR/floating_point_mul_add.rs:23:13
|
LL | let _ = c - a * b;
| ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:25:13
+ --> $DIR/floating_point_mul_add.rs:24:13
|
LL | let _ = a + 2.0 * 4.0;
| ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:26:13
+ --> $DIR/floating_point_mul_add.rs:25:13
|
LL | let _ = a + 2. * 4.;
| ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:28:13
+ --> $DIR/floating_point_mul_add.rs:27:13
|
LL | let _ = (a * b) + c;
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:29:13
+ --> $DIR/floating_point_mul_add.rs:28:13
|
LL | let _ = c + (a * b);
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:30:13
+ --> $DIR/floating_point_mul_add.rs:29:13
|
LL | let _ = a * b * c + d;
| ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:32:13
+ --> $DIR/floating_point_mul_add.rs:31:13
|
LL | let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:33:13
+ --> $DIR/floating_point_mul_add.rs:32:13
|
LL | let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_mul_add.rs:35:13
+ --> $DIR/floating_point_mul_add.rs:34:13
|
LL | let _ = (a * a + b).sqrt();
| ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`
diff --git a/src/tools/clippy/tests/ui/floating_point_powf.fixed b/src/tools/clippy/tests/ui/floating_point_powf.fixed
index 1e660b140..c2884ca31 100644
--- a/src/tools/clippy/tests/ui/floating_point_powf.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_powf.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_powf.rs b/src/tools/clippy/tests/ui/floating_point_powf.rs
index 71c2f5292..37d58af05 100644
--- a/src/tools/clippy/tests/ui/floating_point_powf.rs
+++ b/src/tools/clippy/tests/ui/floating_point_powf.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_powf.stderr b/src/tools/clippy/tests/ui/floating_point_powf.stderr
index 7c9d50db2..0ff8f82d9 100644
--- a/src/tools/clippy/tests/ui/floating_point_powf.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_powf.stderr
@@ -1,189 +1,191 @@
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:7:13
+ --> $DIR/floating_point_powf.rs:6:13
|
LL | let _ = 2f32.powf(x);
| ^^^^^^^^^^^^ help: consider using: `x.exp2()`
|
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:8:13
+ --> $DIR/floating_point_powf.rs:7:13
|
LL | let _ = 2f32.powf(3.1);
| ^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:9:13
+ --> $DIR/floating_point_powf.rs:8:13
|
LL | let _ = 2f32.powf(-3.1);
| ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:10:13
+ --> $DIR/floating_point_powf.rs:9:13
|
LL | let _ = std::f32::consts::E.powf(x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:11:13
+ --> $DIR/floating_point_powf.rs:10:13
|
LL | let _ = std::f32::consts::E.powf(3.1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:12:13
+ --> $DIR/floating_point_powf.rs:11:13
|
LL | let _ = std::f32::consts::E.powf(-3.1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp()`
error: square-root of a number can be computed more efficiently and accurately
- --> $DIR/floating_point_powf.rs:13:13
+ --> $DIR/floating_point_powf.rs:12:13
|
LL | let _ = x.powf(1.0 / 2.0);
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`
error: cube-root of a number can be computed more accurately
- --> $DIR/floating_point_powf.rs:14:13
+ --> $DIR/floating_point_powf.rs:13:13
|
LL | let _ = x.powf(1.0 / 3.0);
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`
|
= note: `-D clippy::imprecise-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`
error: cube-root of a number can be computed more accurately
- --> $DIR/floating_point_powf.rs:15:13
+ --> $DIR/floating_point_powf.rs:14:13
|
LL | let _ = (x as f32).powf(1.0 / 3.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).cbrt()`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:16:13
+ --> $DIR/floating_point_powf.rs:15:13
|
LL | let _ = x.powf(3.0);
| ^^^^^^^^^^^ help: consider using: `x.powi(3)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:17:13
+ --> $DIR/floating_point_powf.rs:16:13
|
LL | let _ = x.powf(-2.0);
| ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:18:13
+ --> $DIR/floating_point_powf.rs:17:13
|
LL | let _ = x.powf(16_777_215.0);
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:19:13
+ --> $DIR/floating_point_powf.rs:18:13
|
LL | let _ = x.powf(-16_777_215.0);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:20:13
+ --> $DIR/floating_point_powf.rs:19:13
|
LL | let _ = (x as f32).powf(-16_777_215.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(-16_777_215)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:21:13
+ --> $DIR/floating_point_powf.rs:20:13
|
LL | let _ = (x as f32).powf(3.0);
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(3)`
error: cube-root of a number can be computed more accurately
- --> $DIR/floating_point_powf.rs:22:13
+ --> $DIR/floating_point_powf.rs:21:13
|
LL | let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1.5_f32 + 1.0).cbrt()`
error: cube-root of a number can be computed more accurately
- --> $DIR/floating_point_powf.rs:23:13
+ --> $DIR/floating_point_powf.rs:22:13
|
LL | let _ = 1.5_f64.powf(1.0 / 3.0);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.cbrt()`
error: square-root of a number can be computed more efficiently and accurately
- --> $DIR/floating_point_powf.rs:24:13
+ --> $DIR/floating_point_powf.rs:23:13
|
LL | let _ = 1.5_f64.powf(1.0 / 2.0);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.sqrt()`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:25:13
+ --> $DIR/floating_point_powf.rs:24:13
|
LL | let _ = 1.5_f64.powf(3.0);
| ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:34:13
+ --> $DIR/floating_point_powf.rs:33:13
|
LL | let _ = 2f64.powf(x);
| ^^^^^^^^^^^^ help: consider using: `x.exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:35:13
+ --> $DIR/floating_point_powf.rs:34:13
|
LL | let _ = 2f64.powf(3.1);
| ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:36:13
+ --> $DIR/floating_point_powf.rs:35:13
|
LL | let _ = 2f64.powf(-3.1);
| ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:37:13
+ --> $DIR/floating_point_powf.rs:36:13
|
LL | let _ = std::f64::consts::E.powf(x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:38:13
+ --> $DIR/floating_point_powf.rs:37:13
|
LL | let _ = std::f64::consts::E.powf(3.1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()`
error: exponent for bases 2 and e can be computed more accurately
- --> $DIR/floating_point_powf.rs:39:13
+ --> $DIR/floating_point_powf.rs:38:13
|
LL | let _ = std::f64::consts::E.powf(-3.1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()`
error: square-root of a number can be computed more efficiently and accurately
- --> $DIR/floating_point_powf.rs:40:13
+ --> $DIR/floating_point_powf.rs:39:13
|
LL | let _ = x.powf(1.0 / 2.0);
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`
error: cube-root of a number can be computed more accurately
- --> $DIR/floating_point_powf.rs:41:13
+ --> $DIR/floating_point_powf.rs:40:13
|
LL | let _ = x.powf(1.0 / 3.0);
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:42:13
+ --> $DIR/floating_point_powf.rs:41:13
|
LL | let _ = x.powf(3.0);
| ^^^^^^^^^^^ help: consider using: `x.powi(3)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:43:13
+ --> $DIR/floating_point_powf.rs:42:13
|
LL | let _ = x.powf(-2.0);
| ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:44:13
+ --> $DIR/floating_point_powf.rs:43:13
|
LL | let _ = x.powf(-2_147_483_648.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)`
error: exponentiation with integer powers can be computed more efficiently
- --> $DIR/floating_point_powf.rs:45:13
+ --> $DIR/floating_point_powf.rs:44:13
|
LL | let _ = x.powf(2_147_483_647.0);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)`
diff --git a/src/tools/clippy/tests/ui/floating_point_powi.fixed b/src/tools/clippy/tests/ui/floating_point_powi.fixed
index 41d5288d6..cb033c899 100644
--- a/src/tools/clippy/tests/ui/floating_point_powi.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_powi.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suboptimal_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_powi.rs b/src/tools/clippy/tests/ui/floating_point_powi.rs
index 7951aab31..f02e0e8dd 100644
--- a/src/tools/clippy/tests/ui/floating_point_powi.rs
+++ b/src/tools/clippy/tests/ui/floating_point_powi.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suboptimal_flops)]
#![allow(clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/floating_point_powi.stderr b/src/tools/clippy/tests/ui/floating_point_powi.stderr
index fdf6d0880..ddf20ff40 100644
--- a/src/tools/clippy/tests/ui/floating_point_powi.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_powi.stderr
@@ -1,85 +1,86 @@
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:10:13
+ --> $DIR/floating_point_powi.rs:9:13
|
LL | let _ = x.powi(2) + y;
| ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
|
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:11:13
+ --> $DIR/floating_point_powi.rs:10:13
|
LL | let _ = x.powi(2) - y;
| ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, -y)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:12:13
+ --> $DIR/floating_point_powi.rs:11:13
|
LL | let _ = x + y.powi(2);
| ^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:13:13
+ --> $DIR/floating_point_powi.rs:12:13
|
LL | let _ = x - y.powi(2);
| ^^^^^^^^^^^^^ help: consider using: `y.mul_add(-y, x)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:14:13
+ --> $DIR/floating_point_powi.rs:13:13
|
LL | let _ = x + (y as f32).powi(2);
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y as f32).mul_add(y as f32, x)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:15:13
+ --> $DIR/floating_point_powi.rs:14:13
|
LL | let _ = (x.powi(2) + y).sqrt();
| ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:16:13
+ --> $DIR/floating_point_powi.rs:15:13
|
LL | let _ = (x + y.powi(2)).sqrt();
| ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:18:13
+ --> $DIR/floating_point_powi.rs:17:13
|
LL | let _ = (x - 1.0).powi(2) - y;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -y)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:19:13
+ --> $DIR/floating_point_powi.rs:18:13
|
LL | let _ = (x - 1.0).powi(2) - y + 3.0;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -y)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:20:13
+ --> $DIR/floating_point_powi.rs:19:13
|
LL | let _ = (x - 1.0).powi(2) - (y + 3.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -(y + 3.0))`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:21:13
+ --> $DIR/floating_point_powi.rs:20:13
|
LL | let _ = x - (y + 1.0).powi(2);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0).mul_add(-(y + 1.0), x)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:22:13
+ --> $DIR/floating_point_powi.rs:21:13
|
LL | let _ = x - (3.0 * y).powi(2);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(3.0 * y).mul_add(-(3.0 * y), x)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:23:13
+ --> $DIR/floating_point_powi.rs:22:13
|
LL | let _ = x - (y + 1.0 + x).powi(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0 + x).mul_add(-(y + 1.0 + x), x)`
error: multiply and add expressions can be calculated more efficiently and accurately
- --> $DIR/floating_point_powi.rs:24:13
+ --> $DIR/floating_point_powi.rs:23:13
|
LL | let _ = x - (y + 1.0 + 2.0).powi(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0 + 2.0).mul_add(-(y + 1.0 + 2.0), x)`
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.fixed b/src/tools/clippy/tests/ui/floating_point_rad.fixed
index af2364527..a710bd9bd 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_rad.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.rs b/src/tools/clippy/tests/ui/floating_point_rad.rs
index d7612c56a..14656f021 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.rs
+++ b/src/tools/clippy/tests/ui/floating_point_rad.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]
diff --git a/src/tools/clippy/tests/ui/floating_point_rad.stderr b/src/tools/clippy/tests/ui/floating_point_rad.stderr
index 979442f2c..e7b42de04 100644
--- a/src/tools/clippy/tests/ui/floating_point_rad.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_rad.stderr
@@ -1,49 +1,50 @@
error: conversion to radians can be done more accurately
- --> $DIR/floating_point_rad.rs:12:13
+ --> $DIR/floating_point_rad.rs:11:13
|
LL | let _ = degrees as f64 * std::f64::consts::PI / 180.0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_radians()`
|
= note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
error: conversion to degrees can be done more accurately
- --> $DIR/floating_point_rad.rs:13:13
+ --> $DIR/floating_point_rad.rs:12:13
|
LL | let _ = degrees as f64 * 180.0 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()`
error: conversion to degrees can be done more accurately
- --> $DIR/floating_point_rad.rs:18:13
+ --> $DIR/floating_point_rad.rs:17:13
|
LL | let _ = x * 180f32 / std::f32::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()`
error: conversion to degrees can be done more accurately
- --> $DIR/floating_point_rad.rs:19:13
+ --> $DIR/floating_point_rad.rs:18:13
|
LL | let _ = 90. * 180f64 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()`
error: conversion to degrees can be done more accurately
- --> $DIR/floating_point_rad.rs:20:13
+ --> $DIR/floating_point_rad.rs:19:13
|
LL | let _ = 90.5 * 180f64 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()`
error: conversion to radians can be done more accurately
- --> $DIR/floating_point_rad.rs:21:13
+ --> $DIR/floating_point_rad.rs:20:13
|
LL | let _ = x * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()`
error: conversion to radians can be done more accurately
- --> $DIR/floating_point_rad.rs:22:13
+ --> $DIR/floating_point_rad.rs:21:13
|
LL | let _ = 90. * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()`
error: conversion to radians can be done more accurately
- --> $DIR/floating_point_rad.rs:23:13
+ --> $DIR/floating_point_rad.rs:22:13
|
LL | let _ = 90.5 * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()`
diff --git a/src/tools/clippy/tests/ui/fn_address_comparisons.rs b/src/tools/clippy/tests/ui/fn_address_comparisons.rs
index 362dcb4fd..35535bd4f 100644
--- a/src/tools/clippy/tests/ui/fn_address_comparisons.rs
+++ b/src/tools/clippy/tests/ui/fn_address_comparisons.rs
@@ -13,7 +13,10 @@ fn main() {
// These should fail:
let _ = f == a;
+ //~^ ERROR: comparing with a non-unique address of a function item
+ //~| NOTE: `-D clippy::fn-address-comparisons` implied by `-D warnings`
let _ = f != a;
+ //~^ ERROR: comparing with a non-unique address of a function item
// These should be fine:
let _ = f == g;
diff --git a/src/tools/clippy/tests/ui/fn_address_comparisons.stderr b/src/tools/clippy/tests/ui/fn_address_comparisons.stderr
index 9c1b5419a..be7fa62f1 100644
--- a/src/tools/clippy/tests/ui/fn_address_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/fn_address_comparisons.stderr
@@ -5,9 +5,10 @@ LL | let _ = f == a;
| ^^^^^^
|
= note: `-D clippy::fn-address-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_address_comparisons)]`
error: comparing with a non-unique address of a function item
- --> $DIR/fn_address_comparisons.rs:16:13
+ --> $DIR/fn_address_comparisons.rs:18:13
|
LL | let _ = f != a;
| ^^^^^^
diff --git a/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs b/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
index f53e53162..cc18708d2 100644
--- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
+++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
@@ -17,22 +17,27 @@ foo!();
#[no_mangle]
extern "C" fn k(_: bool, _: bool, _: bool, _: bool) {}
fn g(_: bool, _: bool, _: bool, _: bool) {}
+//~^ ERROR: more than 3 bools in function parameters
fn h(_: bool, _: bool, _: bool) {}
fn e(_: S, _: S, _: Box<S>, _: Vec<u32>) {}
fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}
+//~^ ERROR: more than 3 bools in function parameters
struct S;
trait Trait {
// should warn for trait functions with and without body
fn f(_: bool, _: bool, _: bool, _: bool);
+ //~^ ERROR: more than 3 bools in function parameters
fn g(_: bool, _: bool, _: bool, _: Vec<u32>);
#[allow(clippy::fn_params_excessive_bools)]
fn h(_: bool, _: bool, _: bool, _: bool, _: bool, _: bool);
fn i(_: bool, _: bool, _: bool, _: bool) {}
+ //~^ ERROR: more than 3 bools in function parameters
}
impl S {
fn f(&self, _: bool, _: bool, _: bool, _: bool) {}
+ //~^ ERROR: more than 3 bools in function parameters
fn g(&self, _: bool, _: bool, _: bool) {}
#[no_mangle]
extern "C" fn h(_: bool, _: bool, _: bool, _: bool) {}
@@ -48,6 +53,8 @@ impl Trait for S {
fn main() {
fn n(_: bool, _: u32, _: bool, _: Box<u32>, _: bool, _: bool) {
+ //~^ ERROR: more than 3 bools in function parameters
fn nn(_: bool, _: bool, _: bool, _: bool) {}
+ //~^ ERROR: more than 3 bools in function parameters
}
}
diff --git a/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr b/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
index 43363b469..f529d8cc4 100644
--- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
+++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
@@ -6,9 +6,10 @@ LL | fn g(_: bool, _: bool, _: bool, _: bool) {}
|
= help: consider refactoring bools into two-variant enums
= note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_params_excessive_bools)]`
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:22:1
+ --> $DIR/fn_params_excessive_bools.rs:23:1
|
LL | fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool
= help: consider refactoring bools into two-variant enums
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:27:5
+ --> $DIR/fn_params_excessive_bools.rs:29:5
|
LL | fn f(_: bool, _: bool, _: bool, _: bool);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | fn f(_: bool, _: bool, _: bool, _: bool);
= help: consider refactoring bools into two-variant enums
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:31:5
+ --> $DIR/fn_params_excessive_bools.rs:34:5
|
LL | fn i(_: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | fn i(_: bool, _: bool, _: bool, _: bool) {}
= help: consider refactoring bools into two-variant enums
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:35:5
+ --> $DIR/fn_params_excessive_bools.rs:39:5
|
LL | fn f(&self, _: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,17 +41,19 @@ LL | fn f(&self, _: bool, _: bool, _: bool, _: bool) {}
= help: consider refactoring bools into two-variant enums
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:50:5
+ --> $DIR/fn_params_excessive_bools.rs:55:5
|
LL | / fn n(_: bool, _: u32, _: bool, _: Box<u32>, _: bool, _: bool) {
+LL | |
LL | | fn nn(_: bool, _: bool, _: bool, _: bool) {}
+LL | |
LL | | }
| |_____^
|
= help: consider refactoring bools into two-variant enums
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:51:9
+ --> $DIR/fn_params_excessive_bools.rs:57:9
|
LL | fn nn(_: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast.32bit.stderr
index 671347d2b..ea08d8c9c 100644
--- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.stderr
+++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast.32bit.stderr
@@ -1,141 +1,143 @@
error: casting function pointer `foo` to `i8`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:10:13
+ --> $DIR/fn_to_numeric_cast.rs:10:13
|
LL | let _ = foo as i8;
| ^^^^^^^^^ help: try: `foo as usize`
|
= note: `-D clippy::fn-to-numeric-cast-with-truncation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]`
error: casting function pointer `foo` to `i16`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:11:13
+ --> $DIR/fn_to_numeric_cast.rs:11:13
|
LL | let _ = foo as i16;
| ^^^^^^^^^^ help: try: `foo as usize`
-error: casting function pointer `foo` to `i32`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:12:13
+error: casting function pointer `foo` to `i32`
+ --> $DIR/fn_to_numeric_cast.rs:12:13
|
LL | let _ = foo as i32;
| ^^^^^^^^^^ help: try: `foo as usize`
+ |
+ = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]`
error: casting function pointer `foo` to `i64`
- --> $DIR/fn_to_numeric_cast_32bit.rs:13:13
+ --> $DIR/fn_to_numeric_cast.rs:13:13
|
LL | let _ = foo as i64;
| ^^^^^^^^^^ help: try: `foo as usize`
- |
- = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings`
error: casting function pointer `foo` to `i128`
- --> $DIR/fn_to_numeric_cast_32bit.rs:14:13
+ --> $DIR/fn_to_numeric_cast.rs:14:13
|
LL | let _ = foo as i128;
| ^^^^^^^^^^^ help: try: `foo as usize`
error: casting function pointer `foo` to `isize`
- --> $DIR/fn_to_numeric_cast_32bit.rs:15:13
+ --> $DIR/fn_to_numeric_cast.rs:15:13
|
LL | let _ = foo as isize;
| ^^^^^^^^^^^^ help: try: `foo as usize`
error: casting function pointer `foo` to `u8`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:17:13
+ --> $DIR/fn_to_numeric_cast.rs:17:13
|
LL | let _ = foo as u8;
| ^^^^^^^^^ help: try: `foo as usize`
error: casting function pointer `foo` to `u16`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:18:13
+ --> $DIR/fn_to_numeric_cast.rs:18:13
|
LL | let _ = foo as u16;
| ^^^^^^^^^^ help: try: `foo as usize`
-error: casting function pointer `foo` to `u32`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:19:13
+error: casting function pointer `foo` to `u32`
+ --> $DIR/fn_to_numeric_cast.rs:19:13
|
LL | let _ = foo as u32;
| ^^^^^^^^^^ help: try: `foo as usize`
error: casting function pointer `foo` to `u64`
- --> $DIR/fn_to_numeric_cast_32bit.rs:20:13
+ --> $DIR/fn_to_numeric_cast.rs:20:13
|
LL | let _ = foo as u64;
| ^^^^^^^^^^ help: try: `foo as usize`
error: casting function pointer `foo` to `u128`
- --> $DIR/fn_to_numeric_cast_32bit.rs:21:13
+ --> $DIR/fn_to_numeric_cast.rs:21:13
|
LL | let _ = foo as u128;
| ^^^^^^^^^^^ help: try: `foo as usize`
error: casting function pointer `abc` to `i8`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:34:13
+ --> $DIR/fn_to_numeric_cast.rs:34:13
|
LL | let _ = abc as i8;
| ^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `i16`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:35:13
+ --> $DIR/fn_to_numeric_cast.rs:35:13
|
LL | let _ = abc as i16;
| ^^^^^^^^^^ help: try: `abc as usize`
-error: casting function pointer `abc` to `i32`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:36:13
+error: casting function pointer `abc` to `i32`
+ --> $DIR/fn_to_numeric_cast.rs:36:13
|
LL | let _ = abc as i32;
| ^^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `i64`
- --> $DIR/fn_to_numeric_cast_32bit.rs:37:13
+ --> $DIR/fn_to_numeric_cast.rs:37:13
|
LL | let _ = abc as i64;
| ^^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `i128`
- --> $DIR/fn_to_numeric_cast_32bit.rs:38:13
+ --> $DIR/fn_to_numeric_cast.rs:38:13
|
LL | let _ = abc as i128;
| ^^^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `isize`
- --> $DIR/fn_to_numeric_cast_32bit.rs:39:13
+ --> $DIR/fn_to_numeric_cast.rs:39:13
|
LL | let _ = abc as isize;
| ^^^^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `u8`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:41:13
+ --> $DIR/fn_to_numeric_cast.rs:41:13
|
LL | let _ = abc as u8;
| ^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `u16`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:42:13
+ --> $DIR/fn_to_numeric_cast.rs:42:13
|
LL | let _ = abc as u16;
| ^^^^^^^^^^ help: try: `abc as usize`
-error: casting function pointer `abc` to `u32`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:43:13
+error: casting function pointer `abc` to `u32`
+ --> $DIR/fn_to_numeric_cast.rs:43:13
|
LL | let _ = abc as u32;
| ^^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `u64`
- --> $DIR/fn_to_numeric_cast_32bit.rs:44:13
+ --> $DIR/fn_to_numeric_cast.rs:44:13
|
LL | let _ = abc as u64;
| ^^^^^^^^^^ help: try: `abc as usize`
error: casting function pointer `abc` to `u128`
- --> $DIR/fn_to_numeric_cast_32bit.rs:45:13
+ --> $DIR/fn_to_numeric_cast.rs:45:13
|
LL | let _ = abc as u128;
| ^^^^^^^^^^^ help: try: `abc as usize`
-error: casting function pointer `f` to `i32`, which truncates the value
- --> $DIR/fn_to_numeric_cast_32bit.rs:52:5
+error: casting function pointer `f` to `i32`
+ --> $DIR/fn_to_numeric_cast.rs:52:5
|
LL | f as i32
| ^^^^^^^^ help: try: `f as usize`
diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast.64bit.stderr
index e9549e157..62f3bfa70 100644
--- a/src/tools/clippy/tests/ui/fn_to_numeric_cast.stderr
+++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast.64bit.stderr
@@ -5,6 +5,7 @@ LL | let _ = foo as i8;
| ^^^^^^^^^ help: try: `foo as usize`
|
= note: `-D clippy::fn-to-numeric-cast-with-truncation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]`
error: casting function pointer `foo` to `i16`, which truncates the value
--> $DIR/fn_to_numeric_cast.rs:11:13
@@ -25,6 +26,7 @@ LL | let _ = foo as i64;
| ^^^^^^^^^^ help: try: `foo as usize`
|
= note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]`
error: casting function pointer `foo` to `i128`
--> $DIR/fn_to_numeric_cast.rs:14:13
diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs b/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs
index 4f6af8708..9501eb5da 100644
--- a/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs
+++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs
@@ -1,5 +1,5 @@
-//@ignore-32bit
-
+//@stderr-per-bitwidth
+//@no-rustfix
#![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)]
fn foo() -> String {
diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs b/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs
deleted file mode 100644
index 62ce97f09..000000000
--- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-//@ignore-64bit
-
-#![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)]
-
-fn foo() -> String {
- String::new()
-}
-
-fn test_function_to_numeric_cast() {
- let _ = foo as i8;
- let _ = foo as i16;
- let _ = foo as i32;
- let _ = foo as i64;
- let _ = foo as i128;
- let _ = foo as isize;
-
- let _ = foo as u8;
- let _ = foo as u16;
- let _ = foo as u32;
- let _ = foo as u64;
- let _ = foo as u128;
-
- // Casting to usize is OK and should not warn
- let _ = foo as usize;
-
- // Cast `f` (a `FnDef`) to `fn()` should not warn
- fn f() {}
- let _ = f as fn();
-}
-
-fn test_function_var_to_numeric_cast() {
- let abc: fn() -> String = foo;
-
- let _ = abc as i8;
- let _ = abc as i16;
- let _ = abc as i32;
- let _ = abc as i64;
- let _ = abc as i128;
- let _ = abc as isize;
-
- let _ = abc as u8;
- let _ = abc as u16;
- let _ = abc as u32;
- let _ = abc as u64;
- let _ = abc as u128;
-
- // Casting to usize is OK and should not warn
- let _ = abc as usize;
-}
-
-fn fn_with_fn_args(f: fn(i32) -> i32) -> i32 {
- f as i32
-}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs
index 467046839..95abc0ac6 100644
--- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs
+++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.rs
@@ -1,6 +1,6 @@
#![warn(clippy::fn_to_numeric_cast_any)]
#![allow(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)]
-
+//@no-rustfix
fn foo() -> u8 {
0
}
@@ -21,40 +21,58 @@ impl Trait for Struct {}
fn fn_pointer_to_integer() {
let _ = foo as i8;
+ //~^ ERROR: casting function pointer `foo` to `i8`
+ //~| NOTE: `-D clippy::fn-to-numeric-cast-any` implied by `-D warnings`
let _ = foo as i16;
+ //~^ ERROR: casting function pointer `foo` to `i16`
let _ = foo as i32;
+ //~^ ERROR: casting function pointer `foo` to `i32`
let _ = foo as i64;
+ //~^ ERROR: casting function pointer `foo` to `i64`
let _ = foo as i128;
+ //~^ ERROR: casting function pointer `foo` to `i128`
let _ = foo as isize;
+ //~^ ERROR: casting function pointer `foo` to `isize`
let _ = foo as u8;
+ //~^ ERROR: casting function pointer `foo` to `u8`
let _ = foo as u16;
+ //~^ ERROR: casting function pointer `foo` to `u16`
let _ = foo as u32;
+ //~^ ERROR: casting function pointer `foo` to `u32`
let _ = foo as u64;
+ //~^ ERROR: casting function pointer `foo` to `u64`
let _ = foo as u128;
+ //~^ ERROR: casting function pointer `foo` to `u128`
let _ = foo as usize;
+ //~^ ERROR: casting function pointer `foo` to `usize`
}
fn static_method_to_integer() {
let _ = Struct::static_method as usize;
+ //~^ ERROR: casting function pointer `Struct::static_method` to `usize`
}
fn fn_with_fn_arg(f: fn(i32) -> u32) -> usize {
f as usize
+ //~^ ERROR: casting function pointer `f` to `usize`
}
fn fn_with_generic_static_trait_method<T: Trait>() -> usize {
T::static_method as usize
+ //~^ ERROR: casting function pointer `T::static_method` to `usize`
}
fn closure_to_fn_to_integer() {
let clos = |x| x * 2_u32;
let _ = (clos as fn(u32) -> u32) as usize;
+ //~^ ERROR: casting function pointer `(clos as fn(u32) -> u32)` to `usize`
}
fn fn_to_raw_ptr() {
let _ = foo as *const ();
+ //~^ ERROR: casting function pointer `foo` to `*const ()`
}
fn cast_fn_to_self() {
diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr
index a6c4a7767..a1514c87b 100644
--- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr
+++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr
@@ -5,99 +5,100 @@ LL | let _ = foo as i8;
| ^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i8`
|
= note: `-D clippy::fn-to-numeric-cast-any` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]`
error: casting function pointer `foo` to `i16`
- --> $DIR/fn_to_numeric_cast_any.rs:24:13
+ --> $DIR/fn_to_numeric_cast_any.rs:26:13
|
LL | let _ = foo as i16;
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i16`
error: casting function pointer `foo` to `i32`
- --> $DIR/fn_to_numeric_cast_any.rs:25:13
+ --> $DIR/fn_to_numeric_cast_any.rs:28:13
|
LL | let _ = foo as i32;
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i32`
error: casting function pointer `foo` to `i64`
- --> $DIR/fn_to_numeric_cast_any.rs:26:13
+ --> $DIR/fn_to_numeric_cast_any.rs:30:13
|
LL | let _ = foo as i64;
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i64`
error: casting function pointer `foo` to `i128`
- --> $DIR/fn_to_numeric_cast_any.rs:27:13
+ --> $DIR/fn_to_numeric_cast_any.rs:32:13
|
LL | let _ = foo as i128;
| ^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as i128`
error: casting function pointer `foo` to `isize`
- --> $DIR/fn_to_numeric_cast_any.rs:28:13
+ --> $DIR/fn_to_numeric_cast_any.rs:34:13
|
LL | let _ = foo as isize;
| ^^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as isize`
error: casting function pointer `foo` to `u8`
- --> $DIR/fn_to_numeric_cast_any.rs:30:13
+ --> $DIR/fn_to_numeric_cast_any.rs:37:13
|
LL | let _ = foo as u8;
| ^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u8`
error: casting function pointer `foo` to `u16`
- --> $DIR/fn_to_numeric_cast_any.rs:31:13
+ --> $DIR/fn_to_numeric_cast_any.rs:39:13
|
LL | let _ = foo as u16;
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u16`
error: casting function pointer `foo` to `u32`
- --> $DIR/fn_to_numeric_cast_any.rs:32:13
+ --> $DIR/fn_to_numeric_cast_any.rs:41:13
|
LL | let _ = foo as u32;
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u32`
error: casting function pointer `foo` to `u64`
- --> $DIR/fn_to_numeric_cast_any.rs:33:13
+ --> $DIR/fn_to_numeric_cast_any.rs:43:13
|
LL | let _ = foo as u64;
| ^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u64`
error: casting function pointer `foo` to `u128`
- --> $DIR/fn_to_numeric_cast_any.rs:34:13
+ --> $DIR/fn_to_numeric_cast_any.rs:45:13
|
LL | let _ = foo as u128;
| ^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as u128`
error: casting function pointer `foo` to `usize`
- --> $DIR/fn_to_numeric_cast_any.rs:35:13
+ --> $DIR/fn_to_numeric_cast_any.rs:47:13
|
LL | let _ = foo as usize;
| ^^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as usize`
error: casting function pointer `Struct::static_method` to `usize`
- --> $DIR/fn_to_numeric_cast_any.rs:39:13
+ --> $DIR/fn_to_numeric_cast_any.rs:52:13
|
LL | let _ = Struct::static_method as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `Struct::static_method() as usize`
error: casting function pointer `f` to `usize`
- --> $DIR/fn_to_numeric_cast_any.rs:43:5
+ --> $DIR/fn_to_numeric_cast_any.rs:57:5
|
LL | f as usize
| ^^^^^^^^^^ help: did you mean to invoke the function?: `f() as usize`
error: casting function pointer `T::static_method` to `usize`
- --> $DIR/fn_to_numeric_cast_any.rs:47:5
+ --> $DIR/fn_to_numeric_cast_any.rs:62:5
|
LL | T::static_method as usize
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `T::static_method() as usize`
error: casting function pointer `(clos as fn(u32) -> u32)` to `usize`
- --> $DIR/fn_to_numeric_cast_any.rs:53:13
+ --> $DIR/fn_to_numeric_cast_any.rs:69:13
|
LL | let _ = (clos as fn(u32) -> u32) as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `(clos as fn(u32) -> u32)() as usize`
error: casting function pointer `foo` to `*const ()`
- --> $DIR/fn_to_numeric_cast_any.rs:57:13
+ --> $DIR/fn_to_numeric_cast_any.rs:74:13
|
LL | let _ = foo as *const ();
| ^^^^^^^^^^^^^^^^ help: did you mean to invoke the function?: `foo() as *const ()`
diff --git a/src/tools/clippy/tests/ui/for_kv_map.fixed b/src/tools/clippy/tests/ui/for_kv_map.fixed
new file mode 100644
index 000000000..a2112d7b7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/for_kv_map.fixed
@@ -0,0 +1,56 @@
+#![warn(clippy::for_kv_map)]
+#![allow(clippy::used_underscore_binding)]
+
+use std::collections::*;
+use std::rc::Rc;
+
+fn main() {
+ let m: HashMap<u64, u64> = HashMap::new();
+ for v in m.values() {
+ //~^ ERROR: you seem to want to iterate on a map's values
+ //~| NOTE: `-D clippy::for-kv-map` implied by `-D warnings`
+ let _v = v;
+ }
+
+ let m: Rc<HashMap<u64, u64>> = Rc::new(HashMap::new());
+ for v in (*m).values() {
+ //~^ ERROR: you seem to want to iterate on a map's values
+ let _v = v;
+ // Here the `*` is not actually necessary, but the test tests that we don't
+ // suggest
+ // `in *m.values()` as we used to
+ }
+
+ let mut m: HashMap<u64, u64> = HashMap::new();
+ for v in m.values_mut() {
+ //~^ ERROR: you seem to want to iterate on a map's values
+ let _v = v;
+ }
+
+ let m: &mut HashMap<u64, u64> = &mut HashMap::new();
+ for v in (*m).values_mut() {
+ //~^ ERROR: you seem to want to iterate on a map's values
+ let _v = v;
+ }
+
+ let m: HashMap<u64, u64> = HashMap::new();
+ let rm = &m;
+ for k in rm.keys() {
+ //~^ ERROR: you seem to want to iterate on a map's keys
+ let _k = k;
+ }
+
+ // The following should not produce warnings.
+
+ let m: HashMap<u64, u64> = HashMap::new();
+ // No error, _value is actually used
+ for (k, _value) in &m {
+ let _ = _value;
+ let _k = k;
+ }
+
+ let m: HashMap<u64, String> = Default::default();
+ for (_, v) in m {
+ let _v = v;
+ }
+}
diff --git a/src/tools/clippy/tests/ui/for_kv_map.rs b/src/tools/clippy/tests/ui/for_kv_map.rs
index 39a8d960a..1b7959b8f 100644
--- a/src/tools/clippy/tests/ui/for_kv_map.rs
+++ b/src/tools/clippy/tests/ui/for_kv_map.rs
@@ -7,11 +7,14 @@ use std::rc::Rc;
fn main() {
let m: HashMap<u64, u64> = HashMap::new();
for (_, v) in &m {
+ //~^ ERROR: you seem to want to iterate on a map's values
+ //~| NOTE: `-D clippy::for-kv-map` implied by `-D warnings`
let _v = v;
}
let m: Rc<HashMap<u64, u64>> = Rc::new(HashMap::new());
for (_, v) in &*m {
+ //~^ ERROR: you seem to want to iterate on a map's values
let _v = v;
// Here the `*` is not actually necessary, but the test tests that we don't
// suggest
@@ -20,17 +23,20 @@ fn main() {
let mut m: HashMap<u64, u64> = HashMap::new();
for (_, v) in &mut m {
+ //~^ ERROR: you seem to want to iterate on a map's values
let _v = v;
}
let m: &mut HashMap<u64, u64> = &mut HashMap::new();
for (_, v) in &mut *m {
+ //~^ ERROR: you seem to want to iterate on a map's values
let _v = v;
}
let m: HashMap<u64, u64> = HashMap::new();
let rm = &m;
for (k, _value) in rm {
+ //~^ ERROR: you seem to want to iterate on a map's keys
let _k = k;
}
diff --git a/src/tools/clippy/tests/ui/for_kv_map.stderr b/src/tools/clippy/tests/ui/for_kv_map.stderr
index e5cc7c146..d29617e24 100644
--- a/src/tools/clippy/tests/ui/for_kv_map.stderr
+++ b/src/tools/clippy/tests/ui/for_kv_map.stderr
@@ -5,13 +5,14 @@ LL | for (_, v) in &m {
| ^^
|
= note: `-D clippy::for-kv-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::for_kv_map)]`
help: use the corresponding method
|
LL | for v in m.values() {
| ~ ~~~~~~~~~~
error: you seem to want to iterate on a map's values
- --> $DIR/for_kv_map.rs:14:19
+ --> $DIR/for_kv_map.rs:16:19
|
LL | for (_, v) in &*m {
| ^^^
@@ -22,7 +23,7 @@ LL | for v in (*m).values() {
| ~ ~~~~~~~~~~~~~
error: you seem to want to iterate on a map's values
- --> $DIR/for_kv_map.rs:22:19
+ --> $DIR/for_kv_map.rs:25:19
|
LL | for (_, v) in &mut m {
| ^^^^^^
@@ -33,7 +34,7 @@ LL | for v in m.values_mut() {
| ~ ~~~~~~~~~~~~~~
error: you seem to want to iterate on a map's values
- --> $DIR/for_kv_map.rs:27:19
+ --> $DIR/for_kv_map.rs:31:19
|
LL | for (_, v) in &mut *m {
| ^^^^^^^
@@ -44,7 +45,7 @@ LL | for v in (*m).values_mut() {
| ~ ~~~~~~~~~~~~~~~~~
error: you seem to want to iterate on a map's keys
- --> $DIR/for_kv_map.rs:33:24
+ --> $DIR/for_kv_map.rs:38:24
|
LL | for (k, _value) in rm {
| ^^
diff --git a/src/tools/clippy/tests/ui/forget_non_drop.rs b/src/tools/clippy/tests/ui/forget_non_drop.rs
index 7580cf95e..2459f51a3 100644
--- a/src/tools/clippy/tests/ui/forget_non_drop.rs
+++ b/src/tools/clippy/tests/ui/forget_non_drop.rs
@@ -11,6 +11,7 @@ fn main() {
struct Foo;
// Lint
forget(Foo);
+ //~^ ERROR: call to `std::mem::forget` with a value that does not implement `Drop`. Fo
struct Bar;
impl Drop for Bar {
@@ -22,6 +23,7 @@ fn main() {
struct Baz<T>(T);
// Lint
forget(Baz(Foo));
+ //~^ ERROR: call to `std::mem::forget` with a value that does not implement `Drop`. Fo
// Don't lint
forget(Baz(Bar));
}
diff --git a/src/tools/clippy/tests/ui/forget_non_drop.stderr b/src/tools/clippy/tests/ui/forget_non_drop.stderr
index 194e37c8b..c0fa433c4 100644
--- a/src/tools/clippy/tests/ui/forget_non_drop.stderr
+++ b/src/tools/clippy/tests/ui/forget_non_drop.stderr
@@ -10,15 +10,16 @@ note: argument has type `main::Foo`
LL | forget(Foo);
| ^^^
= note: `-D clippy::forget-non-drop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::forget_non_drop)]`
error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it
- --> $DIR/forget_non_drop.rs:24:5
+ --> $DIR/forget_non_drop.rs:25:5
|
LL | forget(Baz(Foo));
| ^^^^^^^^^^^^^^^^
|
note: argument has type `main::Baz<main::Foo>`
- --> $DIR/forget_non_drop.rs:24:12
+ --> $DIR/forget_non_drop.rs:25:12
|
LL | forget(Baz(Foo));
| ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/format.fixed b/src/tools/clippy/tests/ui/format.fixed
index 2e24e07ea..36679a9c8 100644
--- a/src/tools/clippy/tests/ui/format.fixed
+++ b/src/tools/clippy/tests/ui/format.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::useless_format)]
#![allow(
unused_tuple_struct_fields,
diff --git a/src/tools/clippy/tests/ui/format.rs b/src/tools/clippy/tests/ui/format.rs
index 0e64a310b..b0920daf0 100644
--- a/src/tools/clippy/tests/ui/format.rs
+++ b/src/tools/clippy/tests/ui/format.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::useless_format)]
#![allow(
unused_tuple_struct_fields,
diff --git a/src/tools/clippy/tests/ui/format.stderr b/src/tools/clippy/tests/ui/format.stderr
index 78a11a335..d4630a8f1 100644
--- a/src/tools/clippy/tests/ui/format.stderr
+++ b/src/tools/clippy/tests/ui/format.stderr
@@ -1,25 +1,26 @@
error: useless use of `format!`
- --> $DIR/format.rs:21:5
+ --> $DIR/format.rs:20:5
|
LL | format!("foo");
| ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
|
= note: `-D clippy::useless-format` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::useless_format)]`
error: useless use of `format!`
- --> $DIR/format.rs:22:5
+ --> $DIR/format.rs:21:5
|
LL | format!("{{}}");
| ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:23:5
+ --> $DIR/format.rs:22:5
|
LL | format!("{{}} abc {{}}");
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:24:5
+ --> $DIR/format.rs:23:5
|
LL | / format!(
LL | | r##"foo {{}}
@@ -34,67 +35,67 @@ LL ~ " bar"##.to_string();
|
error: useless use of `format!`
- --> $DIR/format.rs:29:13
+ --> $DIR/format.rs:28:13
|
LL | let _ = format!("");
| ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`
error: useless use of `format!`
- --> $DIR/format.rs:31:5
+ --> $DIR/format.rs:30:5
|
LL | format!("{}", "foo");
| ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:39:5
+ --> $DIR/format.rs:38:5
|
LL | format!("{}", arg);
| ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:69:5
+ --> $DIR/format.rs:68:5
|
LL | format!("{}", 42.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:71:5
+ --> $DIR/format.rs:70:5
|
LL | format!("{}", x.display().to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:75:18
+ --> $DIR/format.rs:74:18
|
LL | let _ = Some(format!("{}", a + "bar"));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`
error: useless use of `format!`
- --> $DIR/format.rs:79:22
+ --> $DIR/format.rs:78:22
|
-LL | let _s: String = format!("{}", &*v.join("/n"));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()`
+LL | let _s: String = format!("{}", &*v.join("\n"));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("\n")).to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:85:13
+ --> $DIR/format.rs:84:13
|
LL | let _ = format!("{x}");
| ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:87:13
+ --> $DIR/format.rs:86:13
|
LL | let _ = format!("{y}", y = x);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:91:13
+ --> $DIR/format.rs:90:13
|
LL | let _ = format!("{abc}");
| ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()`
error: useless use of `format!`
- --> $DIR/format.rs:93:13
+ --> $DIR/format.rs:92:13
|
LL | let _ = format!("{xx}");
| ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()`
diff --git a/src/tools/clippy/tests/ui/format_args.fixed b/src/tools/clippy/tests/ui/format_args.fixed
index ea3836861..ddd5976c4 100644
--- a/src/tools/clippy/tests/ui/format_args.fixed
+++ b/src/tools/clippy/tests/ui/format_args.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::to_string_in_format_args)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/format_args.rs b/src/tools/clippy/tests/ui/format_args.rs
index bfb324492..18e1bc1af 100644
--- a/src/tools/clippy/tests/ui/format_args.rs
+++ b/src/tools/clippy/tests/ui/format_args.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::to_string_in_format_args)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/format_args.stderr b/src/tools/clippy/tests/ui/format_args.stderr
index f1832b970..dcdfa668a 100644
--- a/src/tools/clippy/tests/ui/format_args.stderr
+++ b/src/tools/clippy/tests/ui/format_args.stderr
@@ -1,151 +1,152 @@
error: `to_string` applied to a type that implements `Display` in `format!` args
- --> $DIR/format_args.rs:77:72
+ --> $DIR/format_args.rs:76:72
|
LL | let _ = format!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
|
= note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::to_string_in_format_args)]`
error: `to_string` applied to a type that implements `Display` in `write!` args
- --> $DIR/format_args.rs:81:27
+ --> $DIR/format_args.rs:80:27
|
LL | Location::caller().to_string()
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `writeln!` args
- --> $DIR/format_args.rs:86:27
+ --> $DIR/format_args.rs:85:27
|
LL | Location::caller().to_string()
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `print!` args
- --> $DIR/format_args.rs:88:63
+ --> $DIR/format_args.rs:87:63
|
LL | print!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:89:65
+ --> $DIR/format_args.rs:88:65
|
LL | println!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `eprint!` args
- --> $DIR/format_args.rs:90:64
+ --> $DIR/format_args.rs:89:64
|
LL | eprint!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `eprintln!` args
- --> $DIR/format_args.rs:91:66
+ --> $DIR/format_args.rs:90:66
|
LL | eprintln!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `format_args!` args
- --> $DIR/format_args.rs:92:77
+ --> $DIR/format_args.rs:91:77
|
LL | let _ = format_args!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `assert!` args
- --> $DIR/format_args.rs:93:70
+ --> $DIR/format_args.rs:92:70
|
LL | assert!(true, "error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `assert_eq!` args
- --> $DIR/format_args.rs:94:73
+ --> $DIR/format_args.rs:93:73
|
LL | assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `assert_ne!` args
- --> $DIR/format_args.rs:95:73
+ --> $DIR/format_args.rs:94:73
|
LL | assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `panic!` args
- --> $DIR/format_args.rs:96:63
+ --> $DIR/format_args.rs:95:63
|
LL | panic!("error: something failed at {}", Location::caller().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:97:20
+ --> $DIR/format_args.rs:96:20
|
LL | println!("{}", X(1).to_string());
| ^^^^^^^^^^^^^^^^ help: use this: `*X(1)`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:98:20
+ --> $DIR/format_args.rs:97:20
|
LL | println!("{}", Y(&X(1)).to_string());
| ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:99:24
+ --> $DIR/format_args.rs:98:24
|
LL | println!("{}", Z(1).to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:100:20
+ --> $DIR/format_args.rs:99:20
|
LL | println!("{}", x.to_string());
| ^^^^^^^^^^^^^ help: use this: `**x`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:101:20
+ --> $DIR/format_args.rs:100:20
|
LL | println!("{}", x_ref.to_string());
| ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref`
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:103:39
+ --> $DIR/format_args.rs:102:39
|
LL | println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar");
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:104:52
+ --> $DIR/format_args.rs:103:52
|
LL | println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:105:39
+ --> $DIR/format_args.rs:104:39
|
LL | println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:106:52
+ --> $DIR/format_args.rs:105:52
|
LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `print!` args
- --> $DIR/format_args.rs:118:37
+ --> $DIR/format_args.rs:117:37
|
LL | print!("{}", (Location::caller().to_string()));
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `print!` args
- --> $DIR/format_args.rs:119:39
+ --> $DIR/format_args.rs:118:39
|
LL | print!("{}", ((Location::caller()).to_string()));
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `format!` args
- --> $DIR/format_args.rs:147:38
+ --> $DIR/format_args.rs:146:38
|
LL | let x = format!("{} {}", a, b.to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
- --> $DIR/format_args.rs:161:24
+ --> $DIR/format_args.rs:160:24
|
LL | println!("{}", original[..10].to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]`
diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.rs b/src/tools/clippy/tests/ui/format_args_unfixable.rs
index 423bfaf97..b7492e38b 100644
--- a/src/tools/clippy/tests/ui/format_args_unfixable.rs
+++ b/src/tools/clippy/tests/ui/format_args_unfixable.rs
@@ -24,31 +24,49 @@ fn main() {
let x = 'x';
println!("error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `println!` args
println!("{}: {}", error, format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `println!` args
println!("{:?}: {}", error, format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `println!` args
println!("{{}}: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `println!` args
println!(r#"error: "{}""#, format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `println!` args
println!("error: {}", format!(r#"something failed at "{}""#, Location::caller()));
+ //~^ ERROR: `format!` in `println!` args
println!("error: {}", format!("something failed at {} {0}", Location::caller()));
+ //~^ ERROR: `format!` in `println!` args
let _ = format!("error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `format!` args
let _ = write!(
+ //~^ ERROR: `format!` in `write!` args
stdout(),
"error: {}",
format!("something failed at {}", Location::caller())
);
let _ = writeln!(
+ //~^ ERROR: `format!` in `writeln!` args
stdout(),
"error: {}",
format!("something failed at {}", Location::caller())
);
print!("error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `print!` args
eprint!("error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `eprint!` args
eprintln!("error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `eprintln!` args
let _ = format_args!("error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `format_args!` args
assert!(true, "error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `assert!` args
assert_eq!(0, 0, "error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `assert_eq!` args
assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `assert_ne!` args
panic!("error: {}", format!("something failed at {}", Location::caller()));
+ //~^ ERROR: `format!` in `panic!` args
// negative tests
println!("error: {}", format_args!("something failed at {}", Location::caller()));
diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.stderr b/src/tools/clippy/tests/ui/format_args_unfixable.stderr
index c1be48c3b..3ffe2f6c8 100644
--- a/src/tools/clippy/tests/ui/format_args_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/format_args_unfixable.stderr
@@ -7,9 +7,10 @@ LL | println!("error: {}", format!("something failed at {}", Location::calle
= help: combine the `format!(..)` arguments with the outer `println!(..)` call
= help: or consider changing `format!` to `format_args!`
= note: `-D clippy::format-in-format-args` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::format_in_format_args)]`
error: `format!` in `println!` args
- --> $DIR/format_args_unfixable.rs:27:5
+ --> $DIR/format_args_unfixable.rs:28:5
|
LL | println!("{}: {}", error, format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -18,7 +19,7 @@ LL | println!("{}: {}", error, format!("something failed at {}", Location::c
= help: or consider changing `format!` to `format_args!`
error: `format!` in `println!` args
- --> $DIR/format_args_unfixable.rs:28:5
+ --> $DIR/format_args_unfixable.rs:30:5
|
LL | println!("{:?}: {}", error, format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,7 +28,7 @@ LL | println!("{:?}: {}", error, format!("something failed at {}", Location:
= help: or consider changing `format!` to `format_args!`
error: `format!` in `println!` args
- --> $DIR/format_args_unfixable.rs:29:5
+ --> $DIR/format_args_unfixable.rs:32:5
|
LL | println!("{{}}: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL | println!("{{}}: {}", format!("something failed at {}", Location::caller
= help: or consider changing `format!` to `format_args!`
error: `format!` in `println!` args
- --> $DIR/format_args_unfixable.rs:30:5
+ --> $DIR/format_args_unfixable.rs:34:5
|
LL | println!(r#"error: "{}""#, format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | println!(r#"error: "{}""#, format!("something failed at {}", Location::
= help: or consider changing `format!` to `format_args!`
error: `format!` in `println!` args
- --> $DIR/format_args_unfixable.rs:31:5
+ --> $DIR/format_args_unfixable.rs:36:5
|
LL | println!("error: {}", format!(r#"something failed at "{}""#, Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,7 +55,7 @@ LL | println!("error: {}", format!(r#"something failed at "{}""#, Location::
= help: or consider changing `format!` to `format_args!`
error: `format!` in `println!` args
- --> $DIR/format_args_unfixable.rs:32:5
+ --> $DIR/format_args_unfixable.rs:38:5
|
LL | println!("error: {}", format!("something failed at {} {0}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -63,7 +64,7 @@ LL | println!("error: {}", format!("something failed at {} {0}", Location::c
= help: or consider changing `format!` to `format_args!`
error: `format!` in `format!` args
- --> $DIR/format_args_unfixable.rs:33:13
+ --> $DIR/format_args_unfixable.rs:40:13
|
LL | let _ = format!("error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,10 +73,11 @@ LL | let _ = format!("error: {}", format!("something failed at {}", Location
= help: or consider changing `format!` to `format_args!`
error: `format!` in `write!` args
- --> $DIR/format_args_unfixable.rs:34:13
+ --> $DIR/format_args_unfixable.rs:42:13
|
LL | let _ = write!(
| _____________^
+LL | |
LL | | stdout(),
LL | | "error: {}",
LL | | format!("something failed at {}", Location::caller())
@@ -86,10 +88,11 @@ LL | | );
= help: or consider changing `format!` to `format_args!`
error: `format!` in `writeln!` args
- --> $DIR/format_args_unfixable.rs:39:13
+ --> $DIR/format_args_unfixable.rs:48:13
|
LL | let _ = writeln!(
| _____________^
+LL | |
LL | | stdout(),
LL | | "error: {}",
LL | | format!("something failed at {}", Location::caller())
@@ -100,7 +103,7 @@ LL | | );
= help: or consider changing `format!` to `format_args!`
error: `format!` in `print!` args
- --> $DIR/format_args_unfixable.rs:44:5
+ --> $DIR/format_args_unfixable.rs:54:5
|
LL | print!("error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -109,7 +112,7 @@ LL | print!("error: {}", format!("something failed at {}", Location::caller(
= help: or consider changing `format!` to `format_args!`
error: `format!` in `eprint!` args
- --> $DIR/format_args_unfixable.rs:45:5
+ --> $DIR/format_args_unfixable.rs:56:5
|
LL | eprint!("error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +121,7 @@ LL | eprint!("error: {}", format!("something failed at {}", Location::caller
= help: or consider changing `format!` to `format_args!`
error: `format!` in `eprintln!` args
- --> $DIR/format_args_unfixable.rs:46:5
+ --> $DIR/format_args_unfixable.rs:58:5
|
LL | eprintln!("error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +130,7 @@ LL | eprintln!("error: {}", format!("something failed at {}", Location::call
= help: or consider changing `format!` to `format_args!`
error: `format!` in `format_args!` args
- --> $DIR/format_args_unfixable.rs:47:13
+ --> $DIR/format_args_unfixable.rs:60:13
|
LL | let _ = format_args!("error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -136,7 +139,7 @@ LL | let _ = format_args!("error: {}", format!("something failed at {}", Loc
= help: or consider changing `format!` to `format_args!`
error: `format!` in `assert!` args
- --> $DIR/format_args_unfixable.rs:48:5
+ --> $DIR/format_args_unfixable.rs:62:5
|
LL | assert!(true, "error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +148,7 @@ LL | assert!(true, "error: {}", format!("something failed at {}", Location::
= help: or consider changing `format!` to `format_args!`
error: `format!` in `assert_eq!` args
- --> $DIR/format_args_unfixable.rs:49:5
+ --> $DIR/format_args_unfixable.rs:64:5
|
LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,7 +157,7 @@ LL | assert_eq!(0, 0, "error: {}", format!("something failed at {}", Locatio
= help: or consider changing `format!` to `format_args!`
error: `format!` in `assert_ne!` args
- --> $DIR/format_args_unfixable.rs:50:5
+ --> $DIR/format_args_unfixable.rs:66:5
|
LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -163,7 +166,7 @@ LL | assert_ne!(0, 0, "error: {}", format!("something failed at {}", Locatio
= help: or consider changing `format!` to `format_args!`
error: `format!` in `panic!` args
- --> $DIR/format_args_unfixable.rs:51:5
+ --> $DIR/format_args_unfixable.rs:68:5
|
LL | panic!("error: {}", format!("something failed at {}", Location::caller()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/format_collect.rs b/src/tools/clippy/tests/ui/format_collect.rs
index c7f2b7b69..26ebdc6c0 100644
--- a/src/tools/clippy/tests/ui/format_collect.rs
+++ b/src/tools/clippy/tests/ui/format_collect.rs
@@ -3,11 +3,13 @@
fn hex_encode(bytes: &[u8]) -> String {
bytes.iter().map(|b| format!("{b:02X}")).collect()
+ //~^ ERROR: use of `format!` to build up a string from an iterator
}
#[rustfmt::skip]
fn hex_encode_deep(bytes: &[u8]) -> String {
bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect()
+ //~^ ERROR: use of `format!` to build up a string from an iterator
}
macro_rules! fmt {
@@ -22,6 +24,7 @@ fn from_macro(bytes: &[u8]) -> String {
fn with_block() -> String {
(1..10)
+ //~^ ERROR: use of `format!` to build up a string from an iterator
.map(|s| {
let y = 1;
format!("{s} {y}")
diff --git a/src/tools/clippy/tests/ui/format_collect.stderr b/src/tools/clippy/tests/ui/format_collect.stderr
index d918f1ed4..340218ccf 100644
--- a/src/tools/clippy/tests/ui/format_collect.stderr
+++ b/src/tools/clippy/tests/ui/format_collect.stderr
@@ -16,29 +16,31 @@ LL | bytes.iter().map(|b| format!("{b:02X}")).collect()
| ^^^^^^^^^^^^^^^^^^
= note: this can be written more efficiently by appending to a `String` directly
= note: `-D clippy::format-collect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::format_collect)]`
error: use of `format!` to build up a string from an iterator
- --> $DIR/format_collect.rs:10:5
+ --> $DIR/format_collect.rs:11:5
|
LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: call `fold` instead
- --> $DIR/format_collect.rs:10:18
+ --> $DIR/format_collect.rs:11:18
|
LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect()
| ^^^
help: ... and use the `write!` macro here
- --> $DIR/format_collect.rs:10:32
+ --> $DIR/format_collect.rs:11:32
|
LL | bytes.iter().map(|b| {{{{{ format!("{b:02X}") }}}}}).collect()
| ^^^^^^^^^^^^^^^^^^
= note: this can be written more efficiently by appending to a `String` directly
error: use of `format!` to build up a string from an iterator
- --> $DIR/format_collect.rs:24:5
+ --> $DIR/format_collect.rs:26:5
|
LL | / (1..10)
+LL | |
LL | | .map(|s| {
LL | | let y = 1;
LL | | format!("{s} {y}")
@@ -47,12 +49,12 @@ LL | | .collect()
| |__________________^
|
help: call `fold` instead
- --> $DIR/format_collect.rs:25:10
+ --> $DIR/format_collect.rs:28:10
|
LL | .map(|s| {
| ^^^
help: ... and use the `write!` macro here
- --> $DIR/format_collect.rs:27:13
+ --> $DIR/format_collect.rs:30:13
|
LL | format!("{s} {y}")
| ^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/format_push_string.rs b/src/tools/clippy/tests/ui/format_push_string.rs
index 89423ffe1..735ae3393 100644
--- a/src/tools/clippy/tests/ui/format_push_string.rs
+++ b/src/tools/clippy/tests/ui/format_push_string.rs
@@ -3,7 +3,9 @@
fn main() {
let mut string = String::new();
string += &format!("{:?}", 1234);
+ //~^ ERROR: `format!(..)` appended to existing `String`
string.push_str(&format!("{:?}", 5678));
+ //~^ ERROR: `format!(..)` appended to existing `String`
}
mod issue9493 {
@@ -11,6 +13,7 @@ mod issue9493 {
let mut hex = String::with_capacity(vector.len() * 2);
for byte in vector {
hex += &(if upper {
+ //~^ ERROR: `format!(..)` appended to existing `String`
format!("{byte:02X}")
} else {
format!("{byte:02x}")
@@ -23,12 +26,14 @@ mod issue9493 {
let mut s = String::new();
// if let
s += &(if let Some(_a) = Some(1234) {
+ //~^ ERROR: `format!(..)` appended to existing `String`
format!("{}", 1234)
} else {
format!("{}", 1234)
});
// match
s += &(match Some(1234) {
+ //~^ ERROR: `format!(..)` appended to existing `String`
Some(_) => format!("{}", 1234),
None => format!("{}", 1234),
});
diff --git a/src/tools/clippy/tests/ui/format_push_string.stderr b/src/tools/clippy/tests/ui/format_push_string.stderr
index 76762c4a1..545915b56 100644
--- a/src/tools/clippy/tests/ui/format_push_string.stderr
+++ b/src/tools/clippy/tests/ui/format_push_string.stderr
@@ -6,9 +6,10 @@ LL | string += &format!("{:?}", 1234);
|
= help: consider using `write!` to avoid the extra allocation
= note: `-D clippy::format-push-string` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]`
error: `format!(..)` appended to existing `String`
- --> $DIR/format_push_string.rs:6:5
+ --> $DIR/format_push_string.rs:7:5
|
LL | string.push_str(&format!("{:?}", 5678));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,9 +17,10 @@ LL | string.push_str(&format!("{:?}", 5678));
= help: consider using `write!` to avoid the extra allocation
error: `format!(..)` appended to existing `String`
- --> $DIR/format_push_string.rs:13:13
+ --> $DIR/format_push_string.rs:15:13
|
LL | / hex += &(if upper {
+LL | |
LL | | format!("{byte:02X}")
LL | | } else {
LL | | format!("{byte:02x}")
@@ -28,9 +30,10 @@ LL | | });
= help: consider using `write!` to avoid the extra allocation
error: `format!(..)` appended to existing `String`
- --> $DIR/format_push_string.rs:25:9
+ --> $DIR/format_push_string.rs:28:9
|
LL | / s += &(if let Some(_a) = Some(1234) {
+LL | |
LL | | format!("{}", 1234)
LL | | } else {
LL | | format!("{}", 1234)
@@ -40,9 +43,10 @@ LL | | });
= help: consider using `write!` to avoid the extra allocation
error: `format!(..)` appended to existing `String`
- --> $DIR/format_push_string.rs:31:9
+ --> $DIR/format_push_string.rs:35:9
|
LL | / s += &(match Some(1234) {
+LL | |
LL | | Some(_) => format!("{}", 1234),
LL | | None => format!("{}", 1234),
LL | | });
diff --git a/src/tools/clippy/tests/ui/formatting.rs b/src/tools/clippy/tests/ui/formatting.rs
index 471a8e0de..312fa2aa4 100644
--- a/src/tools/clippy/tests/ui/formatting.rs
+++ b/src/tools/clippy/tests/ui/formatting.rs
@@ -14,10 +14,16 @@ fn main() {
// weird op_eq formatting:
let mut a = 42;
a =- 35;
+ //~^ ERROR: this looks like you are trying to use `.. -= ..`, but you really are doing
+ //~| NOTE: to remove this lint, use either `-=` or `= -`
a =* &191;
+ //~^ ERROR: this looks like you are trying to use `.. *= ..`, but you really are doing
+ //~| NOTE: to remove this lint, use either `*=` or `= *`
let mut b = true;
b =! false;
+ //~^ ERROR: this looks like you are trying to use `.. != ..`, but you really are doing
+ //~| NOTE: to remove this lint, use either `!=` or `= !`
// those are ok:
a = -35;
@@ -27,10 +33,14 @@ fn main() {
// possible missing comma in an array
let _ = &[
-1, -2, -3 // <= no comma here
+ //~^ ERROR: possibly missing a comma here
+ //~| NOTE: to remove this lint, add a comma or write the expr in a single line
-4, -5, -6
];
let _ = &[
-1, -2, -3 // <= no comma here
+ //~^ ERROR: possibly missing a comma here
+ //~| NOTE: to remove this lint, add a comma or write the expr in a single line
*4, -5, -6
];
@@ -68,6 +78,8 @@ fn main() {
// lint if it doesn't
let _ = &[
-1
+ //~^ ERROR: possibly missing a comma here
+ //~| NOTE: to remove this lint, add a comma or write the expr in a single line
-4,
];
}
diff --git a/src/tools/clippy/tests/ui/formatting.stderr b/src/tools/clippy/tests/ui/formatting.stderr
index caccd5cba..d4eb8e511 100644
--- a/src/tools/clippy/tests/ui/formatting.stderr
+++ b/src/tools/clippy/tests/ui/formatting.stderr
@@ -6,9 +6,10 @@ LL | a =- 35;
|
= note: to remove this lint, use either `-=` or `= -`
= note: `-D clippy::suspicious-assignment-formatting` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_assignment_formatting)]`
error: this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)`
- --> $DIR/formatting.rs:17:6
+ --> $DIR/formatting.rs:19:6
|
LL | a =* &191;
| ^^^^
@@ -16,7 +17,7 @@ LL | a =* &191;
= note: to remove this lint, use either `*=` or `= *`
error: this looks like you are trying to use `.. != ..`, but you really are doing `.. = (! ..)`
- --> $DIR/formatting.rs:20:6
+ --> $DIR/formatting.rs:24:6
|
LL | b =! false;
| ^^^^
@@ -24,16 +25,17 @@ LL | b =! false;
= note: to remove this lint, use either `!=` or `= !`
error: possibly missing a comma here
- --> $DIR/formatting.rs:29:19
+ --> $DIR/formatting.rs:35:19
|
LL | -1, -2, -3 // <= no comma here
| ^
|
= note: to remove this lint, add a comma or write the expr in a single line
= note: `-D clippy::possible-missing-comma` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::possible_missing_comma)]`
error: possibly missing a comma here
- --> $DIR/formatting.rs:33:19
+ --> $DIR/formatting.rs:41:19
|
LL | -1, -2, -3 // <= no comma here
| ^
@@ -41,7 +43,7 @@ LL | -1, -2, -3 // <= no comma here
= note: to remove this lint, add a comma or write the expr in a single line
error: possibly missing a comma here
- --> $DIR/formatting.rs:70:11
+ --> $DIR/formatting.rs:80:11
|
LL | -1
| ^
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes.fixed b/src/tools/clippy/tests/ui/four_forward_slashes.fixed
index 54b2c414b..6d31c543d 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes.fixed
+++ b/src/tools/clippy/tests/ui/four_forward_slashes.fixed
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(unused)]
#![warn(clippy::four_forward_slashes)]
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes.rs b/src/tools/clippy/tests/ui/four_forward_slashes.rs
index facdc8cb1..458b8de53 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes.rs
+++ b/src/tools/clippy/tests/ui/four_forward_slashes.rs
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(unused)]
#![warn(clippy::four_forward_slashes)]
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes.stderr b/src/tools/clippy/tests/ui/four_forward_slashes.stderr
index 89162e6b0..6450c5f94 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes.stderr
+++ b/src/tools/clippy/tests/ui/four_forward_slashes.stderr
@@ -6,6 +6,7 @@ LL | | fn a() {}
| |_
|
= note: `-D clippy::four-forward-slashes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`
help: make this a doc comment by removing one `/`
|
LL + /// whoops
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.fixed b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.fixed
index ce272b4c6..5ef40015d 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.fixed
+++ b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.fixed
@@ -1,7 +1,6 @@
/// borked doc comment on the first line. doesn't combust!
fn a() {}
-//@run-rustfix
// This test's entire purpose is to make sure we don't panic if the comment with four slashes
// extends to the first line of the file. This is likely pretty rare in production, but an ICE is an
// ICE.
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.rs b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.rs
index d8f82d441..9c835e745 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.rs
+++ b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.rs
@@ -1,7 +1,6 @@
//// borked doc comment on the first line. doesn't combust!
fn a() {}
-//@run-rustfix
// This test's entire purpose is to make sure we don't panic if the comment with four slashes
// extends to the first line of the file. This is likely pretty rare in production, but an ICE is an
// ICE.
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
index 7944da14f..afb7c6b4d 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
+++ b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
@@ -6,6 +6,7 @@ LL | | fn a() {}
| |_
|
= note: `-D clippy::four-forward-slashes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`
help: make this a doc comment by removing one `/`
|
LL + /// borked doc comment on the first line. doesn't combust!
diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
index 1671987cb..82c8e1d8a 100644
--- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
+++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::from_iter_instead_of_collect)]
#![allow(unused_imports, unused_tuple_struct_fields)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
index 48509b32f..2aed6b14b 100644
--- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
+++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::from_iter_instead_of_collect)]
#![allow(unused_imports, unused_tuple_struct_fields)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.stderr b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.stderr
index 8f08ac8c3..6e86341d1 100644
--- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.stderr
+++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.stderr
@@ -1,91 +1,92 @@
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:19:9
+ --> $DIR/from_iter_instead_of_collect.rs:17:9
|
LL | <Self as FromIterator<bool>>::from_iter(iter.into_iter().copied())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.into_iter().copied().collect::<Self>()`
|
= note: `-D clippy::from-iter-instead-of-collect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::from_iter_instead_of_collect)]`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:25:13
+ --> $DIR/from_iter_instead_of_collect.rs:23:13
|
LL | let _ = Vec::from_iter(iter_expr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect::<Vec<_>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:27:13
+ --> $DIR/from_iter_instead_of_collect.rs:25:13
|
LL | let _ = HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect::<HashMap<usize, &i8>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:32:19
+ --> $DIR/from_iter_instead_of_collect.rs:30:19
|
LL | assert_eq!(a, Vec::from_iter(0..3));
| ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<_>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:33:19
+ --> $DIR/from_iter_instead_of_collect.rs:31:19
|
LL | assert_eq!(a, Vec::<i32>::from_iter(0..3));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<i32>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:35:17
+ --> $DIR/from_iter_instead_of_collect.rs:33:17
|
LL | let mut b = VecDeque::from_iter(0..3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<_>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:38:17
+ --> $DIR/from_iter_instead_of_collect.rs:36:17
|
LL | let mut b = VecDeque::<i32>::from_iter(0..3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<i32>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:43:21
+ --> $DIR/from_iter_instead_of_collect.rs:41:21
|
LL | let mut b = collections::VecDeque::<i32>::from_iter(0..3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::VecDeque<i32>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:48:14
+ --> $DIR/from_iter_instead_of_collect.rs:46:14
|
LL | let bm = BTreeMap::from_iter(values.iter().cloned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `values.iter().cloned().collect::<BTreeMap<_, _>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:49:19
+ --> $DIR/from_iter_instead_of_collect.rs:47:19
|
LL | let mut bar = BTreeMap::from_iter(bm.range(0..2));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `bm.range(0..2).collect::<BTreeMap<_, _>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:52:19
+ --> $DIR/from_iter_instead_of_collect.rs:50:19
|
LL | let mut bts = BTreeSet::from_iter(0..3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<BTreeSet<_>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:56:17
+ --> $DIR/from_iter_instead_of_collect.rs:54:17
|
LL | let _ = collections::BTreeSet::from_iter(0..3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<_>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:57:17
+ --> $DIR/from_iter_instead_of_collect.rs:55:17
|
LL | let _ = collections::BTreeSet::<u32>::from_iter(0..3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<u32>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:60:15
+ --> $DIR/from_iter_instead_of_collect.rs:58:15
|
LL | for _i in Vec::from_iter([1, 2, 3].iter()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<_>>()`
error: usage of `FromIterator::from_iter`
- --> $DIR/from_iter_instead_of_collect.rs:61:15
+ --> $DIR/from_iter_instead_of_collect.rs:59:15
|
LL | for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<&i32>>()`
diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed
index d96b68a91..18d285693 100644
--- a/src/tools/clippy/tests/ui/from_over_into.fixed
+++ b/src/tools/clippy/tests/ui/from_over_into.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(type_alias_impl_trait)]
#![warn(clippy::from_over_into)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs
index da8fe04f4..779ef709e 100644
--- a/src/tools/clippy/tests/ui/from_over_into.rs
+++ b/src/tools/clippy/tests/ui/from_over_into.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(type_alias_impl_trait)]
#![warn(clippy::from_over_into)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index 498b00de5..784843ce5 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -1,10 +1,11 @@
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into.rs:10:1
+ --> $DIR/from_over_into.rs:8:1
|
LL | impl Into<StringWrapper> for String {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::from-over-into` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::from_over_into)]`
help: replace the `Into` implementation with `From<std::string::String>`
|
LL ~ impl From<String> for StringWrapper {
@@ -13,7 +14,7 @@ LL ~ StringWrapper(val)
|
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into.rs:18:1
+ --> $DIR/from_over_into.rs:16:1
|
LL | impl Into<SelfType> for String {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +27,7 @@ LL ~ SelfType(String::new())
|
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into.rs:33:1
+ --> $DIR/from_over_into.rs:31:1
|
LL | impl Into<SelfKeywords> for X {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +42,7 @@ LL ~ let _: X = val;
|
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into.rs:45:1
+ --> $DIR/from_over_into.rs:43:1
|
LL | impl core::convert::Into<bool> for crate::ExplicitPaths {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,7 +60,7 @@ LL ~ val.0
|
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into.rs:65:1
+ --> $DIR/from_over_into.rs:63:1
|
LL | impl Into<String> for PathInExpansion {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +74,7 @@ LL ~ fn from(val: PathInExpansion) -> Self {
|
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into.rs:87:5
+ --> $DIR/from_over_into.rs:85:5
|
LL | impl<T> Into<FromOverInto<T>> for Vec<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/from_over_into_unfixable.rs b/src/tools/clippy/tests/ui/from_over_into_unfixable.rs
index c769e38eb..0c1f39f93 100644
--- a/src/tools/clippy/tests/ui/from_over_into_unfixable.rs
+++ b/src/tools/clippy/tests/ui/from_over_into_unfixable.rs
@@ -9,6 +9,7 @@ macro_rules! in_macro {
}
impl Into<InMacro> for String {
+ //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free
fn into(self) -> InMacro {
InMacro(in_macro!())
}
@@ -17,6 +18,7 @@ impl Into<InMacro> for String {
struct WeirdUpperSelf;
impl Into<WeirdUpperSelf> for &'static [u8] {
+ //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free
fn into(self) -> WeirdUpperSelf {
let _ = Self::default();
WeirdUpperSelf
@@ -26,6 +28,7 @@ impl Into<WeirdUpperSelf> for &'static [u8] {
struct ContainsVal;
impl Into<u8> for ContainsVal {
+ //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free
fn into(self) -> u8 {
let val = 1;
val + 1
@@ -37,6 +40,7 @@ pub struct Lval<T>(T);
pub struct Rval<T>(T);
impl<T> Into<Rval<Self>> for Lval<T> {
+ //~^ ERROR: an implementation of `From` is preferred since it gives you `Into<_>` for free
fn into(self) -> Rval<Self> {
Rval(self)
}
diff --git a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr
index 2ab9b9d6b..8ef36f082 100644
--- a/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into_unfixable.stderr
@@ -6,9 +6,10 @@ LL | impl Into<InMacro> for String {
|
= help: replace the `Into` implementation with `From<std::string::String>`
= note: `-D clippy::from-over-into` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::from_over_into)]`
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into_unfixable.rs:19:1
+ --> $DIR/from_over_into_unfixable.rs:20:1
|
LL | impl Into<WeirdUpperSelf> for &'static [u8] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | impl Into<WeirdUpperSelf> for &'static [u8] {
= help: replace the `Into` implementation with `From<&'static [u8]>`
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into_unfixable.rs:28:1
+ --> $DIR/from_over_into_unfixable.rs:30:1
|
LL | impl Into<u8> for ContainsVal {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +27,7 @@ LL | impl Into<u8> for ContainsVal {
= help: replace the `Into` implementation with `From<ContainsVal>`
error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
- --> $DIR/from_over_into_unfixable.rs:39:1
+ --> $DIR/from_over_into_unfixable.rs:42:1
|
LL | impl<T> Into<Rval<Self>> for Lval<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/from_raw_with_void_ptr.rs b/src/tools/clippy/tests/ui/from_raw_with_void_ptr.rs
index 95ef6425f..81472070e 100644
--- a/src/tools/clippy/tests/ui/from_raw_with_void_ptr.rs
+++ b/src/tools/clippy/tests/ui/from_raw_with_void_ptr.rs
@@ -9,6 +9,7 @@ fn main() {
// must lint
let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
let _ = unsafe { Box::from_raw(ptr) };
+ //~^ ERROR: creating a `Box` from a void raw pointer
// shouldn't be linted
let _ = unsafe { Box::from_raw(ptr as *mut usize) };
@@ -20,16 +21,20 @@ fn main() {
// must lint
let ptr = Rc::into_raw(Rc::new(42usize)) as *mut c_void;
let _ = unsafe { Rc::from_raw(ptr) };
+ //~^ ERROR: creating a `Rc` from a void raw pointer
// must lint
let ptr = Arc::into_raw(Arc::new(42usize)) as *mut c_void;
let _ = unsafe { Arc::from_raw(ptr) };
+ //~^ ERROR: creating a `Arc` from a void raw pointer
// must lint
let ptr = std::rc::Weak::into_raw(Rc::downgrade(&Rc::new(42usize))) as *mut c_void;
let _ = unsafe { std::rc::Weak::from_raw(ptr) };
+ //~^ ERROR: creating a `Weak` from a void raw pointer
// must lint
let ptr = std::sync::Weak::into_raw(Arc::downgrade(&Arc::new(42usize))) as *mut c_void;
let _ = unsafe { std::sync::Weak::from_raw(ptr) };
+ //~^ ERROR: creating a `Weak` from a void raw pointer
}
diff --git a/src/tools/clippy/tests/ui/from_raw_with_void_ptr.stderr b/src/tools/clippy/tests/ui/from_raw_with_void_ptr.stderr
index 1963d0801..6e1ad0d99 100644
--- a/src/tools/clippy/tests/ui/from_raw_with_void_ptr.stderr
+++ b/src/tools/clippy/tests/ui/from_raw_with_void_ptr.stderr
@@ -10,51 +10,52 @@ help: cast this to a pointer of the appropriate type
LL | let _ = unsafe { Box::from_raw(ptr) };
| ^^^
= note: `-D clippy::from-raw-with-void-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::from_raw_with_void_ptr)]`
error: creating a `Rc` from a void raw pointer
- --> $DIR/from_raw_with_void_ptr.rs:22:22
+ --> $DIR/from_raw_with_void_ptr.rs:23:22
|
LL | let _ = unsafe { Rc::from_raw(ptr) };
| ^^^^^^^^^^^^^^^^^
|
help: cast this to a pointer of the appropriate type
- --> $DIR/from_raw_with_void_ptr.rs:22:35
+ --> $DIR/from_raw_with_void_ptr.rs:23:35
|
LL | let _ = unsafe { Rc::from_raw(ptr) };
| ^^^
error: creating a `Arc` from a void raw pointer
- --> $DIR/from_raw_with_void_ptr.rs:26:22
+ --> $DIR/from_raw_with_void_ptr.rs:28:22
|
LL | let _ = unsafe { Arc::from_raw(ptr) };
| ^^^^^^^^^^^^^^^^^^
|
help: cast this to a pointer of the appropriate type
- --> $DIR/from_raw_with_void_ptr.rs:26:36
+ --> $DIR/from_raw_with_void_ptr.rs:28:36
|
LL | let _ = unsafe { Arc::from_raw(ptr) };
| ^^^
error: creating a `Weak` from a void raw pointer
- --> $DIR/from_raw_with_void_ptr.rs:30:22
+ --> $DIR/from_raw_with_void_ptr.rs:33:22
|
LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: cast this to a pointer of the appropriate type
- --> $DIR/from_raw_with_void_ptr.rs:30:46
+ --> $DIR/from_raw_with_void_ptr.rs:33:46
|
LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) };
| ^^^
error: creating a `Weak` from a void raw pointer
- --> $DIR/from_raw_with_void_ptr.rs:34:22
+ --> $DIR/from_raw_with_void_ptr.rs:38:22
|
LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: cast this to a pointer of the appropriate type
- --> $DIR/from_raw_with_void_ptr.rs:34:48
+ --> $DIR/from_raw_with_void_ptr.rs:38:48
|
LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) };
| ^^^
diff --git a/src/tools/clippy/tests/ui/from_str_radix_10.fixed b/src/tools/clippy/tests/ui/from_str_radix_10.fixed
new file mode 100644
index 000000000..8c253bfd9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/from_str_radix_10.fixed
@@ -0,0 +1,61 @@
+#![warn(clippy::from_str_radix_10)]
+
+mod some_mod {
+ // fake function that shouldn't trigger the lint
+ pub fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {
+ unimplemented!()
+ }
+}
+
+// fake function that shouldn't trigger the lint
+fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {
+ unimplemented!()
+}
+
+// to test parenthesis addition
+struct Test;
+
+impl std::ops::Add<Test> for Test {
+ type Output = &'static str;
+
+ fn add(self, _: Self) -> Self::Output {
+ "304"
+ }
+}
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ // all of these should trigger the lint
+ "30".parse::<u32>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+ //~| NOTE: `-D clippy::from-str-radix-10` implied by `-D warnings`
+ "24".parse::<i64>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+ "100".parse::<isize>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+ "7".parse::<u8>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+ ("10".to_owned() + "5").parse::<u16>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+ (Test + Test).parse::<i128>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+
+ let string = "300";
+ string.parse::<i32>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+
+ let stringier = "400".to_string();
+ stringier.parse::<i32>()?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+
+ // none of these should trigger the lint
+ u16::from_str_radix("20", 3)?;
+ i32::from_str_radix("45", 12)?;
+ usize::from_str_radix("10", 16)?;
+ i128::from_str_radix("10", 13)?;
+ some_mod::from_str_radix("50", 10)?;
+ some_mod::from_str_radix("50", 6)?;
+ from_str_radix("50", 10)?;
+ from_str_radix("50", 6)?;
+
+ Ok(())
+}
diff --git a/src/tools/clippy/tests/ui/from_str_radix_10.rs b/src/tools/clippy/tests/ui/from_str_radix_10.rs
index 2f2ea0484..e9d022157 100644
--- a/src/tools/clippy/tests/ui/from_str_radix_10.rs
+++ b/src/tools/clippy/tests/ui/from_str_radix_10.rs
@@ -26,17 +26,26 @@ impl std::ops::Add<Test> for Test {
fn main() -> Result<(), Box<dyn std::error::Error>> {
// all of these should trigger the lint
u32::from_str_radix("30", 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
+ //~| NOTE: `-D clippy::from-str-radix-10` implied by `-D warnings`
i64::from_str_radix("24", 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
isize::from_str_radix("100", 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
u8::from_str_radix("7", 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
u16::from_str_radix(&("10".to_owned() + "5"), 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
i128::from_str_radix(Test + Test, 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
let string = "300";
i32::from_str_radix(string, 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
let stringier = "400".to_string();
i32::from_str_radix(&stringier, 10)?;
+ //~^ ERROR: this call to `from_str_radix` can be replaced with a call to `str::parse`
// none of these should trigger the lint
u16::from_str_radix("20", 3)?;
diff --git a/src/tools/clippy/tests/ui/from_str_radix_10.stderr b/src/tools/clippy/tests/ui/from_str_radix_10.stderr
index da5c16f8d..439dcff74 100644
--- a/src/tools/clippy/tests/ui/from_str_radix_10.stderr
+++ b/src/tools/clippy/tests/ui/from_str_radix_10.stderr
@@ -5,45 +5,46 @@ LL | u32::from_str_radix("30", 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"30".parse::<u32>()`
|
= note: `-D clippy::from-str-radix-10` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::from_str_radix_10)]`
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
- --> $DIR/from_str_radix_10.rs:29:5
+ --> $DIR/from_str_radix_10.rs:31:5
|
LL | i64::from_str_radix("24", 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"24".parse::<i64>()`
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
- --> $DIR/from_str_radix_10.rs:30:5
+ --> $DIR/from_str_radix_10.rs:33:5
|
LL | isize::from_str_radix("100", 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"100".parse::<isize>()`
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
- --> $DIR/from_str_radix_10.rs:31:5
+ --> $DIR/from_str_radix_10.rs:35:5
|
LL | u8::from_str_radix("7", 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"7".parse::<u8>()`
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
- --> $DIR/from_str_radix_10.rs:32:5
+ --> $DIR/from_str_radix_10.rs:37:5
|
LL | u16::from_str_radix(&("10".to_owned() + "5"), 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `("10".to_owned() + "5").parse::<u16>()`
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
- --> $DIR/from_str_radix_10.rs:33:5
+ --> $DIR/from_str_radix_10.rs:39:5
|
LL | i128::from_str_radix(Test + Test, 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(Test + Test).parse::<i128>()`
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
- --> $DIR/from_str_radix_10.rs:36:5
+ --> $DIR/from_str_radix_10.rs:43:5
|
LL | i32::from_str_radix(string, 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.parse::<i32>()`
error: this call to `from_str_radix` can be replaced with a call to `str::parse`
- --> $DIR/from_str_radix_10.rs:39:5
+ --> $DIR/from_str_radix_10.rs:47:5
|
LL | i32::from_str_radix(&stringier, 10)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `stringier.parse::<i32>()`
diff --git a/src/tools/clippy/tests/ui/functions.rs b/src/tools/clippy/tests/ui/functions.rs
index 18149bfbc..0aef60959 100644
--- a/src/tools/clippy/tests/ui/functions.rs
+++ b/src/tools/clippy/tests/ui/functions.rs
@@ -6,9 +6,12 @@
fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {}
fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}
+//~^ ERROR: this function has too many arguments (8/7)
+//~| NOTE: `-D clippy::too-many-arguments` implied by `-D warnings`
#[rustfmt::skip]
fn bad_multiline(
+//~^ ERROR: this function has too many arguments (8/7)
one: u32,
two: u32,
three: &str,
@@ -43,6 +46,7 @@ extern "C" fn extern_fn(
pub trait Foo {
fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool);
fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ());
+ //~^ ERROR: this function has too many arguments (8/7)
fn ptr(p: *const u8);
}
@@ -52,6 +56,7 @@ pub struct Bar;
impl Bar {
fn good_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {}
fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}
+ //~^ ERROR: this function has too many arguments (8/7)
}
// ok, we don’t want to warn implementations
@@ -61,8 +66,12 @@ impl Foo for Bar {
fn ptr(p: *const u8) {
println!("{}", unsafe { *p });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked
+ //~| NOTE: `-D clippy::not-unsafe-ptr-arg-deref` implied by `-D warnings`
println!("{:?}", unsafe { p.as_ref() });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked
unsafe { std::ptr::read(p) };
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked
}
}
@@ -74,16 +83,22 @@ fn private(p: *const u8) {
pub fn public(p: *const u8) {
println!("{}", unsafe { *p });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked `un
println!("{:?}", unsafe { p.as_ref() });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked `un
unsafe { std::ptr::read(p) };
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked `un
}
type Alias = *const u8;
pub fn type_alias(p: Alias) {
println!("{}", unsafe { *p });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked `un
println!("{:?}", unsafe { p.as_ref() });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked `un
unsafe { std::ptr::read(p) };
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked `un
}
impl Bar {
@@ -93,8 +108,11 @@ impl Bar {
pub fn public(self, p: *const u8) {
println!("{}", unsafe { *p });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked
println!("{:?}", unsafe { p.as_ref() });
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked
unsafe { std::ptr::read(p) };
+ //~^ ERROR: this public function might dereference a raw pointer but is not marked
}
pub fn public_ok(self, p: *const u8) {
diff --git a/src/tools/clippy/tests/ui/functions.stderr b/src/tools/clippy/tests/ui/functions.stderr
index 8ebd4997f..371ea1612 100644
--- a/src/tools/clippy/tests/ui/functions.stderr
+++ b/src/tools/clippy/tests/ui/functions.stderr
@@ -5,101 +5,103 @@ LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::too-many-arguments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`
error: this function has too many arguments (8/7)
- --> $DIR/functions.rs:11:1
+ --> $DIR/functions.rs:13:1
|
LL | / fn bad_multiline(
+LL | |
LL | | one: u32,
LL | | two: u32,
-LL | | three: &str,
... |
LL | | eight: ()
LL | | ) {
| |__^
error: this function has too many arguments (8/7)
- --> $DIR/functions.rs:45:5
+ --> $DIR/functions.rs:48:5
|
LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this function has too many arguments (8/7)
- --> $DIR/functions.rs:54:5
+ --> $DIR/functions.rs:58:5
|
LL | fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:63:34
+ --> $DIR/functions.rs:68:34
|
LL | println!("{}", unsafe { *p });
| ^
|
= note: `-D clippy::not-unsafe-ptr-arg-deref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::not_unsafe_ptr_arg_deref)]`
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:64:35
+ --> $DIR/functions.rs:71:35
|
LL | println!("{:?}", unsafe { p.as_ref() });
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:65:33
+ --> $DIR/functions.rs:73:33
|
LL | unsafe { std::ptr::read(p) };
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:76:30
+ --> $DIR/functions.rs:85:30
|
LL | println!("{}", unsafe { *p });
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:77:31
+ --> $DIR/functions.rs:87:31
|
LL | println!("{:?}", unsafe { p.as_ref() });
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:78:29
+ --> $DIR/functions.rs:89:29
|
LL | unsafe { std::ptr::read(p) };
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:84:30
+ --> $DIR/functions.rs:96:30
|
LL | println!("{}", unsafe { *p });
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:85:31
+ --> $DIR/functions.rs:98:31
|
LL | println!("{:?}", unsafe { p.as_ref() });
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:86:29
+ --> $DIR/functions.rs:100:29
|
LL | unsafe { std::ptr::read(p) };
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:95:34
+ --> $DIR/functions.rs:110:34
|
LL | println!("{}", unsafe { *p });
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:96:35
+ --> $DIR/functions.rs:112:35
|
LL | println!("{:?}", unsafe { p.as_ref() });
| ^
error: this public function might dereference a raw pointer but is not marked `unsafe`
- --> $DIR/functions.rs:97:33
+ --> $DIR/functions.rs:114:33
|
LL | unsafe { std::ptr::read(p) };
| ^
diff --git a/src/tools/clippy/tests/ui/functions_maxlines.rs b/src/tools/clippy/tests/ui/functions_maxlines.rs
index 5e1ee55e0..a3496f56d 100644
--- a/src/tools/clippy/tests/ui/functions_maxlines.rs
+++ b/src/tools/clippy/tests/ui/functions_maxlines.rs
@@ -56,6 +56,8 @@ fn good_lines() {
}
fn bad_lines() {
+ //~^ ERROR: this function has too many lines (102/100)
+ //~| NOTE: `-D clippy::too-many-lines` implied by `-D warnings`
println!("Dont get confused by braces: {{}}");
println!("This is bad.");
println!("This is bad.");
diff --git a/src/tools/clippy/tests/ui/functions_maxlines.stderr b/src/tools/clippy/tests/ui/functions_maxlines.stderr
index dc6c8ba2f..1d6ddad79 100644
--- a/src/tools/clippy/tests/ui/functions_maxlines.stderr
+++ b/src/tools/clippy/tests/ui/functions_maxlines.stderr
@@ -2,15 +2,16 @@ error: this function has too many lines (102/100)
--> $DIR/functions_maxlines.rs:58:1
|
LL | / fn bad_lines() {
+LL | |
+LL | |
LL | | println!("Dont get confused by braces: {{}}");
-LL | | println!("This is bad.");
-LL | | println!("This is bad.");
... |
LL | | println!("This is bad.");
LL | | }
| |_^
|
= note: `-D clippy::too-many-lines` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::too_many_lines)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/future_not_send.rs b/src/tools/clippy/tests/ui/future_not_send.rs
index 858036692..9274340b5 100644
--- a/src/tools/clippy/tests/ui/future_not_send.rs
+++ b/src/tools/clippy/tests/ui/future_not_send.rs
@@ -5,10 +5,12 @@ use std::rc::Rc;
use std::sync::Arc;
async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
+ //~^ ERROR: future cannot be sent between threads safely
async { true }.await
}
pub async fn public_future(rc: Rc<[u8]>) {
+ //~^ ERROR: future cannot be sent between threads safely
async { true }.await;
}
@@ -17,10 +19,12 @@ pub async fn public_send(arc: Arc<[u8]>) -> bool {
}
async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
+ //~^ ERROR: future cannot be sent between threads safely
true
}
pub async fn public_future2(rc: Rc<[u8]>) {}
+//~^ ERROR: future cannot be sent between threads safely
pub async fn public_send2(arc: Arc<[u8]>) -> bool {
false
@@ -32,11 +36,13 @@ struct Dummy {
impl Dummy {
async fn private_future(&self) -> usize {
+ //~^ ERROR: future cannot be sent between threads safely
async { true }.await;
self.rc.len()
}
pub async fn public_future(&self) {
+ //~^ ERROR: future cannot be sent between threads safely
self.private_future().await;
}
@@ -47,11 +53,13 @@ impl Dummy {
}
async fn generic_future<T>(t: T) -> T
+//~^ ERROR: future cannot be sent between threads safely
where
T: Send,
{
let rt = &t;
async { true }.await;
+ let _ = rt;
t
}
@@ -63,6 +71,7 @@ where
}
async fn unclear_future<T>(t: T) {}
+//~^ ERROR: future cannot be sent between threads safely
fn main() {
let rc = Rc::new([1, 2, 3]);
diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr
index 5c6348962..f43e3c8ff 100644
--- a/src/tools/clippy/tests/ui/future_not_send.stderr
+++ b/src/tools/clippy/tests/ui/future_not_send.stderr
@@ -5,137 +5,123 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
| ^^^^ future returned by `private_future` is not `Send`
|
note: future is not `Send` as this value is used across an await
- --> $DIR/future_not_send.rs:8:20
+ --> $DIR/future_not_send.rs:9:20
|
LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
+LL |
LL | async { true }.await
| ^^^^^ await occurs here, with `rc` maybe used later
-LL | }
- | - `rc` is later dropped here
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
-note: future is not `Send` as this value is used across an await
- --> $DIR/future_not_send.rs:8:20
+note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
+ --> $DIR/future_not_send.rs:7:39
|
LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
- | ---- has type `&std::cell::Cell<usize>` which is not `Send`
-LL | async { true }.await
- | ^^^^^ await occurs here, with `cell` maybe used later
-LL | }
- | - `cell` is later dropped here
+ | ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
= note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
= note: `-D clippy::future-not-send` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]`
error: future cannot be sent between threads safely
- --> $DIR/future_not_send.rs:11:42
+ --> $DIR/future_not_send.rs:12:42
|
LL | pub async fn public_future(rc: Rc<[u8]>) {
| ^ future returned by `public_future` is not `Send`
|
note: future is not `Send` as this value is used across an await
- --> $DIR/future_not_send.rs:12:20
+ --> $DIR/future_not_send.rs:14:20
|
LL | pub async fn public_future(rc: Rc<[u8]>) {
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
+LL |
LL | async { true }.await;
| ^^^^^ await occurs here, with `rc` maybe used later
-LL | }
- | - `rc` is later dropped here
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
error: future cannot be sent between threads safely
- --> $DIR/future_not_send.rs:19:63
+ --> $DIR/future_not_send.rs:21:63
|
LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
| ^^^^ future returned by `private_future2` is not `Send`
|
note: captured value is not `Send`
- --> $DIR/future_not_send.rs:19:26
+ --> $DIR/future_not_send.rs:21:26
|
LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
| ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
- --> $DIR/future_not_send.rs:19:40
+ --> $DIR/future_not_send.rs:21:40
|
LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
| ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
= note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
error: future cannot be sent between threads safely
- --> $DIR/future_not_send.rs:23:43
+ --> $DIR/future_not_send.rs:26:43
|
LL | pub async fn public_future2(rc: Rc<[u8]>) {}
| ^ future returned by `public_future2` is not `Send`
|
note: captured value is not `Send`
- --> $DIR/future_not_send.rs:23:29
+ --> $DIR/future_not_send.rs:26:29
|
LL | pub async fn public_future2(rc: Rc<[u8]>) {}
| ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
error: future cannot be sent between threads safely
- --> $DIR/future_not_send.rs:34:39
+ --> $DIR/future_not_send.rs:38:39
|
LL | async fn private_future(&self) -> usize {
| ^^^^^ future returned by `private_future` is not `Send`
|
note: future is not `Send` as this value is used across an await
- --> $DIR/future_not_send.rs:35:24
+ --> $DIR/future_not_send.rs:40:24
|
LL | async fn private_future(&self) -> usize {
| ----- has type `&Dummy` which is not `Send`
+LL |
LL | async { true }.await;
| ^^^^^ await occurs here, with `&self` maybe used later
-LL | self.rc.len()
-LL | }
- | - `&self` is later dropped here
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
error: future cannot be sent between threads safely
- --> $DIR/future_not_send.rs:39:39
+ --> $DIR/future_not_send.rs:44:39
|
LL | pub async fn public_future(&self) {
| ^ future returned by `public_future` is not `Send`
|
-note: future is not `Send` as this value is used across an await
- --> $DIR/future_not_send.rs:40:31
+note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
+ --> $DIR/future_not_send.rs:44:32
|
LL | pub async fn public_future(&self) {
- | ----- has type `&Dummy` which is not `Send`
-LL | self.private_future().await;
- | ^^^^^ await occurs here, with `&self` maybe used later
-LL | }
- | - `&self` is later dropped here
+ | ^^^^^ has type `&Dummy` which is not `Send`, because `Dummy` is not `Sync`
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
error: future cannot be sent between threads safely
- --> $DIR/future_not_send.rs:49:37
+ --> $DIR/future_not_send.rs:55:37
|
LL | async fn generic_future<T>(t: T) -> T
| ^ future returned by `generic_future` is not `Send`
|
note: future is not `Send` as this value is used across an await
- --> $DIR/future_not_send.rs:54:20
+ --> $DIR/future_not_send.rs:61:20
|
LL | let rt = &t;
| -- has type `&T` which is not `Send`
LL | async { true }.await;
| ^^^^^ await occurs here, with `rt` maybe used later
-LL | t
-LL | }
- | - `rt` is later dropped here
= note: `T` doesn't implement `std::marker::Sync`
error: future cannot be sent between threads safely
- --> $DIR/future_not_send.rs:65:34
+ --> $DIR/future_not_send.rs:73:34
|
LL | async fn unclear_future<T>(t: T) {}
| ^ future returned by `unclear_future` is not `Send`
|
note: captured value is not `Send`
- --> $DIR/future_not_send.rs:65:28
+ --> $DIR/future_not_send.rs:73:28
|
LL | async fn unclear_future<T>(t: T) {}
| ^ has type `T` which is not `Send`
diff --git a/src/tools/clippy/tests/ui/get_first.fixed b/src/tools/clippy/tests/ui/get_first.fixed
index bc2f86566..b1a597fc4 100644
--- a/src/tools/clippy/tests/ui/get_first.fixed
+++ b/src/tools/clippy/tests/ui/get_first.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::get_first)]
#![allow(clippy::useless_vec)]
use std::collections::{BTreeMap, HashMap, VecDeque};
diff --git a/src/tools/clippy/tests/ui/get_first.rs b/src/tools/clippy/tests/ui/get_first.rs
index bc0e233fd..e27ee4be8 100644
--- a/src/tools/clippy/tests/ui/get_first.rs
+++ b/src/tools/clippy/tests/ui/get_first.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::get_first)]
#![allow(clippy::useless_vec)]
use std::collections::{BTreeMap, HashMap, VecDeque};
diff --git a/src/tools/clippy/tests/ui/get_first.stderr b/src/tools/clippy/tests/ui/get_first.stderr
index 0899a5905..56b4c29a3 100644
--- a/src/tools/clippy/tests/ui/get_first.stderr
+++ b/src/tools/clippy/tests/ui/get_first.stderr
@@ -1,19 +1,20 @@
error: accessing first element with `x.get(0)`
- --> $DIR/get_first.rs:18:13
+ --> $DIR/get_first.rs:17:13
|
LL | let _ = x.get(0); // Use x.first()
| ^^^^^^^^ help: try: `x.first()`
|
= note: `-D clippy::get-first` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::get_first)]`
error: accessing first element with `y.get(0)`
- --> $DIR/get_first.rs:23:13
+ --> $DIR/get_first.rs:22:13
|
LL | let _ = y.get(0); // Use y.first()
| ^^^^^^^^ help: try: `y.first()`
error: accessing first element with `z.get(0)`
- --> $DIR/get_first.rs:28:13
+ --> $DIR/get_first.rs:27:13
|
LL | let _ = z.get(0); // Use z.first()
| ^^^^^^^^ help: try: `z.first()`
diff --git a/src/tools/clippy/tests/ui/get_last_with_len.fixed b/src/tools/clippy/tests/ui/get_last_with_len.fixed
index 01a83e5bf..377906cb2 100644
--- a/src/tools/clippy/tests/ui/get_last_with_len.fixed
+++ b/src/tools/clippy/tests/ui/get_last_with_len.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::get_last_with_len)]
#![allow(unused, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/get_last_with_len.rs b/src/tools/clippy/tests/ui/get_last_with_len.rs
index d82484b46..273593204 100644
--- a/src/tools/clippy/tests/ui/get_last_with_len.rs
+++ b/src/tools/clippy/tests/ui/get_last_with_len.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::get_last_with_len)]
#![allow(unused, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/get_last_with_len.stderr b/src/tools/clippy/tests/ui/get_last_with_len.stderr
index ac8dd6c2e..0056adc57 100644
--- a/src/tools/clippy/tests/ui/get_last_with_len.stderr
+++ b/src/tools/clippy/tests/ui/get_last_with_len.stderr
@@ -1,37 +1,38 @@
error: accessing last element with `x.get(x.len() - 1)`
- --> $DIR/get_last_with_len.rs:10:13
+ --> $DIR/get_last_with_len.rs:8:13
|
LL | let _ = x.get(x.len() - 1);
| ^^^^^^^^^^^^^^^^^^ help: try: `x.last()`
|
= note: `-D clippy::get-last-with-len` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::get_last_with_len)]`
error: accessing last element with `s.field.get(s.field.len() - 1)`
- --> $DIR/get_last_with_len.rs:34:13
+ --> $DIR/get_last_with_len.rs:32:13
|
LL | let _ = s.field.get(s.field.len() - 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.field.last()`
error: accessing last element with `slice.get(slice.len() - 1)`
- --> $DIR/get_last_with_len.rs:39:13
+ --> $DIR/get_last_with_len.rs:37:13
|
LL | let _ = slice.get(slice.len() - 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `slice.last()`
error: accessing last element with `array.get(array.len() - 1)`
- --> $DIR/get_last_with_len.rs:42:13
+ --> $DIR/get_last_with_len.rs:40:13
|
LL | let _ = array.get(array.len() - 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array.last()`
error: accessing last element with `deq.get(deq.len() - 1)`
- --> $DIR/get_last_with_len.rs:45:13
+ --> $DIR/get_last_with_len.rs:43:13
|
LL | let _ = deq.get(deq.len() - 1);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `deq.back()`
error: accessing last element with `nested[0].get(nested[0].len() - 1)`
- --> $DIR/get_last_with_len.rs:48:13
+ --> $DIR/get_last_with_len.rs:46:13
|
LL | let _ = nested[0].get(nested[0].len() - 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `nested[0].last()`
diff --git a/src/tools/clippy/tests/ui/get_unwrap.fixed b/src/tools/clippy/tests/ui/get_unwrap.fixed
index fda334407..d5a4309db 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/get_unwrap.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
unused_mut,
clippy::from_iter_instead_of_collect,
diff --git a/src/tools/clippy/tests/ui/get_unwrap.rs b/src/tools/clippy/tests/ui/get_unwrap.rs
index eaf6b005a..5a9ad204f 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.rs
+++ b/src/tools/clippy/tests/ui/get_unwrap.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
unused_mut,
clippy::from_iter_instead_of_collect,
diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr
index 19dc9071f..384860ea1 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/get_unwrap.stderr
@@ -1,17 +1,17 @@
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:38:17
+ --> $DIR/get_unwrap.rs:36:17
|
LL | let _ = boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&boxed_slice[1]`
|
note: the lint level is defined here
- --> $DIR/get_unwrap.rs:10:9
+ --> $DIR/get_unwrap.rs:8:9
|
LL | #![deny(clippy::get_unwrap)]
| ^^^^^^^^^^^^^^^^^^
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:38:17
+ --> $DIR/get_unwrap.rs:36:17
|
LL | let _ = boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,15 +19,16 @@ LL | let _ = boxed_slice.get(1).unwrap();
= note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
= note: `-D clippy::unwrap-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:39:17
+ --> $DIR/get_unwrap.rs:37:17
|
LL | let _ = some_slice.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_slice[0]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:39:17
+ --> $DIR/get_unwrap.rs:37:17
|
LL | let _ = some_slice.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -36,13 +37,13 @@ LL | let _ = some_slice.get(0).unwrap();
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:40:17
+ --> $DIR/get_unwrap.rs:38:17
|
LL | let _ = some_vec.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vec[0]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:40:17
+ --> $DIR/get_unwrap.rs:38:17
|
LL | let _ = some_vec.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -51,13 +52,13 @@ LL | let _ = some_vec.get(0).unwrap();
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:41:17
+ --> $DIR/get_unwrap.rs:39:17
|
LL | let _ = some_vecdeque.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_vecdeque[0]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:41:17
+ --> $DIR/get_unwrap.rs:39:17
|
LL | let _ = some_vecdeque.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -66,13 +67,13 @@ LL | let _ = some_vecdeque.get(0).unwrap();
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:42:17
+ --> $DIR/get_unwrap.rs:40:17
|
LL | let _ = some_hashmap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_hashmap[&1]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:42:17
+ --> $DIR/get_unwrap.rs:40:17
|
LL | let _ = some_hashmap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -81,13 +82,13 @@ LL | let _ = some_hashmap.get(&1).unwrap();
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:43:17
+ --> $DIR/get_unwrap.rs:41:17
|
LL | let _ = some_btreemap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&some_btreemap[&1]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:43:17
+ --> $DIR/get_unwrap.rs:41:17
|
LL | let _ = some_btreemap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,13 +97,13 @@ LL | let _ = some_btreemap.get(&1).unwrap();
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:47:21
+ --> $DIR/get_unwrap.rs:45:21
|
LL | let _: u8 = *boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[1]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:47:22
+ --> $DIR/get_unwrap.rs:45:22
|
LL | let _: u8 = *boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -111,13 +112,13 @@ LL | let _: u8 = *boxed_slice.get(1).unwrap();
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:52:9
+ --> $DIR/get_unwrap.rs:50:9
|
LL | *boxed_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice[0]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:52:10
+ --> $DIR/get_unwrap.rs:50:10
|
LL | *boxed_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -126,13 +127,13 @@ LL | *boxed_slice.get_mut(0).unwrap() = 1;
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:53:9
+ --> $DIR/get_unwrap.rs:51:9
|
LL | *some_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_slice[0]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:53:10
+ --> $DIR/get_unwrap.rs:51:10
|
LL | *some_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -141,13 +142,13 @@ LL | *some_slice.get_mut(0).unwrap() = 1;
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:54:9
+ --> $DIR/get_unwrap.rs:52:9
|
LL | *some_vec.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:54:10
+ --> $DIR/get_unwrap.rs:52:10
|
LL | *some_vec.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -156,13 +157,13 @@ LL | *some_vec.get_mut(0).unwrap() = 1;
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:55:9
+ --> $DIR/get_unwrap.rs:53:9
|
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vecdeque[0]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:55:10
+ --> $DIR/get_unwrap.rs:53:10
|
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -171,13 +172,13 @@ LL | *some_vecdeque.get_mut(0).unwrap() = 1;
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:67:17
+ --> $DIR/get_unwrap.rs:65:17
|
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:67:17
+ --> $DIR/get_unwrap.rs:65:17
|
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -186,13 +187,13 @@ LL | let _ = some_vec.get(0..1).unwrap().to_vec();
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:68:17
+ --> $DIR/get_unwrap.rs:66:17
|
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[0..1]`
error: used `unwrap()` on an `Option` value
- --> $DIR/get_unwrap.rs:68:17
+ --> $DIR/get_unwrap.rs:66:17
|
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -201,25 +202,25 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:78:24
+ --> $DIR/get_unwrap.rs:76:24
|
LL | let _x: &i32 = f.get(1 + 2).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `&f[1 + 2]`
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:81:18
+ --> $DIR/get_unwrap.rs:79:18
|
LL | let _x = f.get(1 + 2).unwrap().to_string();
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `f[1 + 2]`
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:84:18
+ --> $DIR/get_unwrap.rs:82:18
|
LL | let _x = f.get(1 + 2).unwrap().abs();
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `f[1 + 2]`
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/get_unwrap.rs:101:33
+ --> $DIR/get_unwrap.rs:99:33
|
LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut rest[linidx(j, k) - linidx(i, k) - 1]`
diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed
index beb16000e..f3b4b1fff 100644
--- a/src/tools/clippy/tests/ui/identity_op.fixed
+++ b/src/tools/clippy/tests/ui/identity_op.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::identity_op)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index 072e00c00..631aa3b02 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::identity_op)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/identity_op.stderr b/src/tools/clippy/tests/ui/identity_op.stderr
index 3ba557d18..2a61327f1 100644
--- a/src/tools/clippy/tests/ui/identity_op.stderr
+++ b/src/tools/clippy/tests/ui/identity_op.stderr
@@ -1,241 +1,242 @@
error: this operation has no effect
- --> $DIR/identity_op.rs:43:5
+ --> $DIR/identity_op.rs:42:5
|
LL | x + 0;
| ^^^^^ help: consider reducing it to: `x`
|
= note: `-D clippy::identity-op` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::identity_op)]`
error: this operation has no effect
- --> $DIR/identity_op.rs:44:5
+ --> $DIR/identity_op.rs:43:5
|
LL | x + (1 - 1);
| ^^^^^^^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:46:5
+ --> $DIR/identity_op.rs:45:5
|
LL | 0 + x;
| ^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:49:5
+ --> $DIR/identity_op.rs:48:5
|
LL | x | (0);
| ^^^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:52:5
+ --> $DIR/identity_op.rs:51:5
|
LL | x * 1;
| ^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:53:5
+ --> $DIR/identity_op.rs:52:5
|
LL | 1 * x;
| ^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:59:5
+ --> $DIR/identity_op.rs:58:5
|
LL | -1 & x;
| ^^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:62:5
+ --> $DIR/identity_op.rs:61:5
|
LL | u & 255;
| ^^^^^^^ help: consider reducing it to: `u`
error: this operation has no effect
- --> $DIR/identity_op.rs:65:5
+ --> $DIR/identity_op.rs:64:5
|
LL | 42 << 0;
| ^^^^^^^ help: consider reducing it to: `42`
error: this operation has no effect
- --> $DIR/identity_op.rs:66:5
+ --> $DIR/identity_op.rs:65:5
|
LL | 1 >> 0;
| ^^^^^^ help: consider reducing it to: `1`
error: this operation has no effect
- --> $DIR/identity_op.rs:67:5
+ --> $DIR/identity_op.rs:66:5
|
LL | 42 >> 0;
| ^^^^^^^ help: consider reducing it to: `42`
error: this operation has no effect
- --> $DIR/identity_op.rs:68:5
+ --> $DIR/identity_op.rs:67:5
|
LL | &x >> 0;
| ^^^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:69:5
+ --> $DIR/identity_op.rs:68:5
|
LL | x >> &0;
| ^^^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:76:5
+ --> $DIR/identity_op.rs:75:5
|
LL | 2 % 3;
| ^^^^^ help: consider reducing it to: `2`
error: this operation has no effect
- --> $DIR/identity_op.rs:77:5
+ --> $DIR/identity_op.rs:76:5
|
LL | -2 % 3;
| ^^^^^^ help: consider reducing it to: `-2`
error: this operation has no effect
- --> $DIR/identity_op.rs:78:5
+ --> $DIR/identity_op.rs:77:5
|
LL | 2 % -3 + x;
| ^^^^^^ help: consider reducing it to: `2`
error: this operation has no effect
- --> $DIR/identity_op.rs:79:5
+ --> $DIR/identity_op.rs:78:5
|
LL | -2 % -3 + x;
| ^^^^^^^ help: consider reducing it to: `-2`
error: this operation has no effect
- --> $DIR/identity_op.rs:80:9
+ --> $DIR/identity_op.rs:79:9
|
LL | x + 1 % 3;
| ^^^^^ help: consider reducing it to: `1`
error: this operation has no effect
- --> $DIR/identity_op.rs:88:5
+ --> $DIR/identity_op.rs:87:5
|
LL | 0 + if b { 1 } else { 2 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`
error: this operation has no effect
- --> $DIR/identity_op.rs:89:5
+ --> $DIR/identity_op.rs:88:5
|
LL | 0 + if b { 1 } else { 2 } + if b { 3 } else { 4 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`
error: this operation has no effect
- --> $DIR/identity_op.rs:90:5
+ --> $DIR/identity_op.rs:89:5
|
LL | 0 + match a { 0 => 10, _ => 20 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })`
error: this operation has no effect
- --> $DIR/identity_op.rs:91:5
+ --> $DIR/identity_op.rs:90:5
|
LL | 0 + match a { 0 => 10, _ => 20 } + match a { 0 => 30, _ => 40 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })`
error: this operation has no effect
- --> $DIR/identity_op.rs:92:5
+ --> $DIR/identity_op.rs:91:5
|
LL | 0 + if b { 1 } else { 2 } + match a { 0 => 30, _ => 40 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`
error: this operation has no effect
- --> $DIR/identity_op.rs:93:5
+ --> $DIR/identity_op.rs:92:5
|
LL | 0 + match a { 0 => 10, _ => 20 } + if b { 3 } else { 4 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })`
error: this operation has no effect
- --> $DIR/identity_op.rs:94:5
+ --> $DIR/identity_op.rs:93:5
|
LL | (if b { 1 } else { 2 }) + 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`
error: this operation has no effect
- --> $DIR/identity_op.rs:96:5
+ --> $DIR/identity_op.rs:95:5
|
LL | 0 + { a } + 3;
| ^^^^^^^^^ help: consider reducing it to: `({ a })`
error: this operation has no effect
- --> $DIR/identity_op.rs:97:5
+ --> $DIR/identity_op.rs:96:5
|
LL | 0 + { a } * 2;
| ^^^^^^^^^^^^^ help: consider reducing it to: `({ a } * 2)`
error: this operation has no effect
- --> $DIR/identity_op.rs:98:5
+ --> $DIR/identity_op.rs:97:5
|
LL | 0 + loop { let mut c = 0; if c == 10 { break c; } c += 1; } + { a * 2 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(loop { let mut c = 0; if c == 10 { break c; } c += 1; })`
error: this operation has no effect
- --> $DIR/identity_op.rs:103:7
+ --> $DIR/identity_op.rs:102:7
|
LL | f(1 * a + { 8 * 5 });
| ^^^^^ help: consider reducing it to: `a`
error: this operation has no effect
- --> $DIR/identity_op.rs:104:7
+ --> $DIR/identity_op.rs:103:7
|
LL | f(0 + if b { 1 } else { 2 } + 3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `if b { 1 } else { 2 }`
error: this operation has no effect
- --> $DIR/identity_op.rs:105:20
+ --> $DIR/identity_op.rs:104:20
|
LL | const _: i32 = { 2 * 4 } + 0 + 3;
| ^^^^^^^^^^^^^ help: consider reducing it to: `{ 2 * 4 }`
error: this operation has no effect
- --> $DIR/identity_op.rs:106:20
+ --> $DIR/identity_op.rs:105:20
|
LL | const _: i32 = 0 + { 1 + 2 * 3 } + 3;
| ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `{ 1 + 2 * 3 }`
error: this operation has no effect
- --> $DIR/identity_op.rs:108:5
+ --> $DIR/identity_op.rs:107:5
|
LL | 0 + a as usize;
| ^^^^^^^^^^^^^^ help: consider reducing it to: `a as usize`
error: this operation has no effect
- --> $DIR/identity_op.rs:109:13
+ --> $DIR/identity_op.rs:108:13
|
LL | let _ = 0 + a as usize;
| ^^^^^^^^^^^^^^ help: consider reducing it to: `a as usize`
error: this operation has no effect
- --> $DIR/identity_op.rs:110:5
+ --> $DIR/identity_op.rs:109:5
|
LL | 0 + { a } as usize;
| ^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `({ a } as usize)`
error: this operation has no effect
- --> $DIR/identity_op.rs:112:9
+ --> $DIR/identity_op.rs:111:9
|
LL | 2 * (0 + { a });
| ^^^^^^^^^^^ help: consider reducing it to: `{ a }`
error: this operation has no effect
- --> $DIR/identity_op.rs:113:5
+ --> $DIR/identity_op.rs:112:5
|
LL | 1 * ({ a } + 4);
| ^^^^^^^^^^^^^^^ help: consider reducing it to: `(({ a } + 4))`
error: this operation has no effect
- --> $DIR/identity_op.rs:114:5
+ --> $DIR/identity_op.rs:113:5
|
LL | 1 * 1;
| ^^^^^ help: consider reducing it to: `1`
error: this operation has no effect
- --> $DIR/identity_op.rs:118:18
+ --> $DIR/identity_op.rs:117:18
|
LL | let _: i32 = &x + 0;
| ^^^^^^ help: consider reducing it to: `x`
error: this operation has no effect
- --> $DIR/identity_op.rs:122:5
+ --> $DIR/identity_op.rs:121:5
|
LL | 0 + if a { 1 } else { 2 } + if b { 3 } else { 5 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if a { 1 } else { 2 })`
diff --git a/src/tools/clippy/tests/ui/if_let_mutex.rs b/src/tools/clippy/tests/ui/if_let_mutex.rs
index 321feb022..cb6915e0e 100644
--- a/src/tools/clippy/tests/ui/if_let_mutex.rs
+++ b/src/tools/clippy/tests/ui/if_let_mutex.rs
@@ -8,6 +8,7 @@ fn do_stuff<T>(_: T) {}
fn if_let() {
let m = Mutex::new(1_u8);
if let Err(locked) = m.lock() {
+ //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
do_stuff(locked);
} else {
let lock = m.lock().unwrap();
@@ -20,6 +21,7 @@ fn if_let() {
fn if_let_option() {
let m = Mutex::new(Some(0_u8));
if let Some(locked) = m.lock().unwrap().deref() {
+ //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
do_stuff(locked);
} else {
let lock = m.lock().unwrap();
@@ -41,6 +43,7 @@ fn if_let_different_mutex() {
fn mutex_ref(mutex: &Mutex<i32>) {
if let Ok(i) = mutex.lock() {
+ //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
do_stuff(i);
} else {
let _x = mutex.lock();
diff --git a/src/tools/clippy/tests/ui/if_let_mutex.stderr b/src/tools/clippy/tests/ui/if_let_mutex.stderr
index da0cc25f0..893429443 100644
--- a/src/tools/clippy/tests/ui/if_let_mutex.stderr
+++ b/src/tools/clippy/tests/ui/if_let_mutex.stderr
@@ -5,6 +5,7 @@ LL | if let Err(locked) = m.lock() {
| ^ - this Mutex will remain locked for the entire `if let`-block...
| _____|
| |
+LL | |
LL | | do_stuff(locked);
LL | | } else {
LL | | let lock = m.lock().unwrap();
@@ -15,14 +16,16 @@ LL | | };
|
= help: move the lock call outside of the `if let ...` expression
= note: `-D clippy::if-let-mutex` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::if_let_mutex)]`
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
- --> $DIR/if_let_mutex.rs:22:5
+ --> $DIR/if_let_mutex.rs:23:5
|
LL | if let Some(locked) = m.lock().unwrap().deref() {
| ^ - this Mutex will remain locked for the entire `if let`-block...
| _____|
| |
+LL | |
LL | | do_stuff(locked);
LL | | } else {
LL | | let lock = m.lock().unwrap();
@@ -34,12 +37,13 @@ LL | | };
= help: move the lock call outside of the `if let ...` expression
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
- --> $DIR/if_let_mutex.rs:43:5
+ --> $DIR/if_let_mutex.rs:45:5
|
LL | if let Ok(i) = mutex.lock() {
| ^ ----- this Mutex will remain locked for the entire `if let`-block...
| _____|
| |
+LL | |
LL | | do_stuff(i);
LL | | } else {
LL | | let _x = mutex.lock();
diff --git a/src/tools/clippy/tests/ui/if_not_else.rs b/src/tools/clippy/tests/ui/if_not_else.rs
index b7012b43d..fd30e3702 100644
--- a/src/tools/clippy/tests/ui/if_not_else.rs
+++ b/src/tools/clippy/tests/ui/if_not_else.rs
@@ -10,11 +10,13 @@ fn bla() -> bool {
fn main() {
if !bla() {
+ //~^ ERROR: unnecessary boolean `not` operation
println!("Bugs");
} else {
println!("Bunny");
}
if 4 != 5 {
+ //~^ ERROR: unnecessary `!=` operation
println!("Bugs");
} else {
println!("Bunny");
diff --git a/src/tools/clippy/tests/ui/if_not_else.stderr b/src/tools/clippy/tests/ui/if_not_else.stderr
index 46671c152..8b86f82fa 100644
--- a/src/tools/clippy/tests/ui/if_not_else.stderr
+++ b/src/tools/clippy/tests/ui/if_not_else.stderr
@@ -2,6 +2,7 @@ error: unnecessary boolean `not` operation
--> $DIR/if_not_else.rs:12:5
|
LL | / if !bla() {
+LL | |
LL | | println!("Bugs");
LL | | } else {
LL | | println!("Bunny");
@@ -10,11 +11,13 @@ LL | | }
|
= help: remove the `!` and swap the blocks of the `if`/`else`
= note: `-D clippy::if-not-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::if_not_else)]`
error: unnecessary `!=` operation
- --> $DIR/if_not_else.rs:17:5
+ --> $DIR/if_not_else.rs:18:5
|
LL | / if 4 != 5 {
+LL | |
LL | | println!("Bugs");
LL | | } else {
LL | | println!("Bunny");
diff --git a/src/tools/clippy/tests/ui/if_same_then_else.stderr b/src/tools/clippy/tests/ui/if_same_then_else.stderr
index 774cc0868..fb33e94e6 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else.stderr
@@ -24,6 +24,7 @@ LL | | foo();
LL | | }
| |_____^
= note: `-D clippy::if-same-then-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]`
error: this `if` has identical blocks
--> $DIR/if_same_then_else.rs:67:21
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.rs b/src/tools/clippy/tests/ui/if_same_then_else2.rs
index c545434ef..0b171f21d 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.rs
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.rs
@@ -98,7 +98,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
};
if true {
- // FIXME: should emit "this `if` has identical blocks"
+ //~^ ERROR: this `if` has identical blocks
Ok("foo")?;
} else {
Ok("foo")?;
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.stderr b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
index 37fe787d1..fe68ef271 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
@@ -24,6 +24,7 @@ LL | | }
LL | | }
| |_____^
= note: `-D clippy::if-same-then-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]`
error: this `if` has identical blocks
--> $DIR/if_same_then_else2.rs:36:13
@@ -83,6 +84,25 @@ LL | | };
| |_____^
error: this `if` has identical blocks
+ --> $DIR/if_same_then_else2.rs:100:13
+ |
+LL | if true {
+ | _____________^
+LL | |
+LL | | Ok("foo")?;
+LL | | } else {
+ | |_____^
+ |
+note: same as this
+ --> $DIR/if_same_then_else2.rs:103:12
+ |
+LL | } else {
+ | ____________^
+LL | | Ok("foo")?;
+LL | | }
+ | |_____^
+
+error: this `if` has identical blocks
--> $DIR/if_same_then_else2.rs:124:20
|
LL | } else if true {
@@ -103,5 +123,5 @@ LL | | return Ok(&foo[0..]);
LL | | }
| |_____^
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.rs b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
index 0e89fdb0d..77abd663e 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.rs
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
@@ -3,6 +3,7 @@
fn main() {
// Should issue an error.
let _ = if foo() {
+ //~^ ERROR: this could be simplified with `bool::then`
println!("true!");
Some("foo")
} else {
@@ -11,6 +12,7 @@ fn main() {
// Should issue an error when macros are used.
let _ = if matches!(true, true) {
+ //~^ ERROR: this could be simplified with `bool::then`
println!("true!");
Some(matches!(true, false))
} else {
@@ -20,10 +22,12 @@ fn main() {
// Should issue an error. Binary expression `o < 32` should be parenthesized.
let x = Some(5);
let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
+ //~^ ERROR: this could be simplified with `bool::then_some`
// Should issue an error. Unary expression `!x` should be parenthesized.
let x = true;
let _ = if !x { Some(0) } else { None };
+ //~^ ERROR: this could be simplified with `bool::then_some`
// Should not issue an error since the `else` block has a statement besides `None`.
let _ = if foo() {
@@ -79,6 +83,7 @@ fn _msrv_1_49() {
#[clippy::msrv = "1.50"]
fn _msrv_1_50() {
let _ = if foo() {
+ //~^ ERROR: this could be simplified with `bool::then`
println!("true!");
Some(150)
} else {
@@ -112,3 +117,15 @@ fn f(b: bool, v: Option<()>) -> Option<()> {
None
}
}
+
+fn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> {
+ let x = if b {
+ #[allow(clippy::let_unit_value)]
+ let _ = v?;
+ Some(())
+ } else {
+ None
+ };
+
+ Ok(())
+}
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
index d728a3c31..5c97b06da 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
@@ -3,6 +3,7 @@ error: this could be simplified with `bool::then`
|
LL | let _ = if foo() {
| _____________^
+LL | |
LL | | println!("true!");
LL | | Some("foo")
LL | | } else {
@@ -12,12 +13,14 @@ LL | | };
|
= help: consider using `bool::then` like: `foo().then(|| { /* snippet */ "foo" })`
= note: `-D clippy::if-then-some-else-none` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]`
error: this could be simplified with `bool::then`
- --> $DIR/if_then_some_else_none.rs:13:13
+ --> $DIR/if_then_some_else_none.rs:14:13
|
LL | let _ = if matches!(true, true) {
| _____________^
+LL | |
LL | | println!("true!");
LL | | Some(matches!(true, false))
LL | | } else {
@@ -28,7 +31,7 @@ LL | | };
= help: consider using `bool::then` like: `matches!(true, true).then(|| { /* snippet */ matches!(true, false) })`
error: this could be simplified with `bool::then_some`
- --> $DIR/if_then_some_else_none.rs:22:28
+ --> $DIR/if_then_some_else_none.rs:24:28
|
LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +39,7 @@ LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
= help: consider using `bool::then_some` like: `(o < 32).then_some(o)`
error: this could be simplified with `bool::then_some`
- --> $DIR/if_then_some_else_none.rs:26:13
+ --> $DIR/if_then_some_else_none.rs:29:13
|
LL | let _ = if !x { Some(0) } else { None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,10 +47,11 @@ LL | let _ = if !x { Some(0) } else { None };
= help: consider using `bool::then_some` like: `(!x).then_some(0)`
error: this could be simplified with `bool::then`
- --> $DIR/if_then_some_else_none.rs:81:13
+ --> $DIR/if_then_some_else_none.rs:85:13
|
LL | let _ = if foo() {
| _____________^
+LL | |
LL | | println!("true!");
LL | | Some(150)
LL | | } else {
diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.stderr b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
index 3f52c10b7..c5cd6b2c4 100644
--- a/src/tools/clippy/tests/ui/ifs_same_cond.stderr
+++ b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
@@ -10,6 +10,7 @@ note: same as this
LL | if b {
| ^
= note: `-D clippy::ifs-same-cond` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`
error: this `if` has the same condition as a previous `if`
--> $DIR/ifs_same_cond.rs:19:15
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
index 492219fe4..6c6f21fee 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
@@ -1,7 +1,5 @@
-//@run-rustfix
-
#![warn(clippy::ignored_unit_patterns)]
-#![allow(clippy::redundant_pattern_matching, clippy::single_match)]
+#![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)]
fn foo() -> Result<(), ()> {
unimplemented!()
@@ -9,9 +7,19 @@ fn foo() -> Result<(), ()> {
fn main() {
match foo() {
- Ok(()) => {},
- Err(()) => {},
+ Ok(()) => {}, //~ ERROR: matching over `()` is more explicit
+ Err(()) => {}, //~ ERROR: matching over `()` is more explicit
}
if let Ok(()) = foo() {}
+ //~^ ERROR: matching over `()` is more explicit
let _ = foo().map_err(|()| todo!());
+ //~^ ERROR: matching over `()` is more explicit
+}
+
+#[allow(unused)]
+pub fn moo(_: ()) {
+ let () = foo().unwrap();
+ //~^ ERROR: matching over `()` is more explicit
+ let _: () = foo().unwrap();
+ let _: () = ();
}
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
index 90af36f8e..5e8c2e03b 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
@@ -1,7 +1,5 @@
-//@run-rustfix
-
#![warn(clippy::ignored_unit_patterns)]
-#![allow(clippy::redundant_pattern_matching, clippy::single_match)]
+#![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)]
fn foo() -> Result<(), ()> {
unimplemented!()
@@ -9,9 +7,19 @@ fn foo() -> Result<(), ()> {
fn main() {
match foo() {
- Ok(_) => {},
- Err(_) => {},
+ Ok(_) => {}, //~ ERROR: matching over `()` is more explicit
+ Err(_) => {}, //~ ERROR: matching over `()` is more explicit
}
if let Ok(_) = foo() {}
+ //~^ ERROR: matching over `()` is more explicit
let _ = foo().map_err(|_| todo!());
+ //~^ ERROR: matching over `()` is more explicit
+}
+
+#[allow(unused)]
+pub fn moo(_: ()) {
+ let _ = foo().unwrap();
+ //~^ ERROR: matching over `()` is more explicit
+ let _: () = foo().unwrap();
+ let _: () = ();
}
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
index 8feea3cc2..df5e1d89e 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
@@ -1,28 +1,35 @@
error: matching over `()` is more explicit
- --> $DIR/ignored_unit_patterns.rs:12:12
+ --> $DIR/ignored_unit_patterns.rs:10:12
|
LL | Ok(_) => {},
| ^ help: use `()` instead of `_`: `()`
|
= note: `-D clippy::ignored-unit-patterns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ignored_unit_patterns)]`
error: matching over `()` is more explicit
- --> $DIR/ignored_unit_patterns.rs:13:13
+ --> $DIR/ignored_unit_patterns.rs:11:13
|
LL | Err(_) => {},
| ^ help: use `()` instead of `_`: `()`
error: matching over `()` is more explicit
- --> $DIR/ignored_unit_patterns.rs:15:15
+ --> $DIR/ignored_unit_patterns.rs:13:15
|
LL | if let Ok(_) = foo() {}
| ^ help: use `()` instead of `_`: `()`
error: matching over `()` is more explicit
- --> $DIR/ignored_unit_patterns.rs:16:28
+ --> $DIR/ignored_unit_patterns.rs:15:28
|
LL | let _ = foo().map_err(|_| todo!());
| ^ help: use `()` instead of `_`: `()`
-error: aborting due to 4 previous errors
+error: matching over `()` is more explicit
+ --> $DIR/ignored_unit_patterns.rs:21:9
+ |
+LL | let _ = foo().unwrap();
+ | ^ help: use `()` instead of `_`: `()`
+
+error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/impl.rs b/src/tools/clippy/tests/ui/impl.rs
index aea52a852..7f452cb46 100644
--- a/src/tools/clippy/tests/ui/impl.rs
+++ b/src/tools/clippy/tests/ui/impl.rs
@@ -8,6 +8,7 @@ impl MyStruct {
}
impl MyStruct {
+ //~^ ERROR: multiple implementations of this structure
fn second() {}
}
@@ -22,6 +23,7 @@ mod submod {
}
impl super::MyStruct {
+ //~^ ERROR: multiple implementations of this structure
fn third() {}
}
}
@@ -42,6 +44,7 @@ impl WithArgs<u64> {
fn f2() {}
}
impl WithArgs<u64> {
+ //~^ ERROR: multiple implementations of this structure
fn f3() {}
}
@@ -63,5 +66,6 @@ impl OneAllowedImpl {}
#[allow(clippy::multiple_inherent_impl)]
impl OneAllowedImpl {}
impl OneAllowedImpl {} // Lint, only one of the three blocks is allowed.
+//~^ ERROR: multiple implementations of this structure
fn main() {}
diff --git a/src/tools/clippy/tests/ui/impl.stderr b/src/tools/clippy/tests/ui/impl.stderr
index e28b1bf0c..833a10606 100644
--- a/src/tools/clippy/tests/ui/impl.stderr
+++ b/src/tools/clippy/tests/ui/impl.stderr
@@ -2,6 +2,7 @@ error: multiple implementations of this structure
--> $DIR/impl.rs:10:1
|
LL | / impl MyStruct {
+LL | |
LL | | fn second() {}
LL | | }
| |_^
@@ -14,11 +15,13 @@ LL | | fn first() {}
LL | | }
| |_^
= note: `-D clippy::multiple-inherent-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::multiple_inherent_impl)]`
error: multiple implementations of this structure
- --> $DIR/impl.rs:24:5
+ --> $DIR/impl.rs:25:5
|
LL | / impl super::MyStruct {
+LL | |
LL | | fn third() {}
LL | | }
| |_____^
@@ -32,15 +35,16 @@ LL | | }
| |_^
error: multiple implementations of this structure
- --> $DIR/impl.rs:44:1
+ --> $DIR/impl.rs:46:1
|
LL | / impl WithArgs<u64> {
+LL | |
LL | | fn f3() {}
LL | | }
| |_^
|
note: first implementation here
- --> $DIR/impl.rs:41:1
+ --> $DIR/impl.rs:43:1
|
LL | / impl WithArgs<u64> {
LL | | fn f2() {}
@@ -48,13 +52,13 @@ LL | | }
| |_^
error: multiple implementations of this structure
- --> $DIR/impl.rs:65:1
+ --> $DIR/impl.rs:68:1
|
LL | impl OneAllowedImpl {} // Lint, only one of the three blocks is allowed.
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: first implementation here
- --> $DIR/impl.rs:62:1
+ --> $DIR/impl.rs:65:1
|
LL | impl OneAllowedImpl {}
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/impl_trait_in_params.rs b/src/tools/clippy/tests/ui/impl_trait_in_params.rs
index 07560101a..b652e4a4a 100644
--- a/src/tools/clippy/tests/ui/impl_trait_in_params.rs
+++ b/src/tools/clippy/tests/ui/impl_trait_in_params.rs
@@ -1,12 +1,15 @@
#![allow(unused)]
#![warn(clippy::impl_trait_in_params)]
-
+//@no-rustfix
pub trait Trait {}
pub trait AnotherTrait<T> {}
// Should warn
pub fn a(_: impl Trait) {}
+//~^ ERROR: '`impl Trait` used as a function parameter'
+//~| NOTE: `-D clippy::impl-trait-in-params` implied by `-D warnings`
pub fn c<C: Trait>(_: C, _: impl Trait) {}
+//~^ ERROR: '`impl Trait` used as a function parameter'
fn d(_: impl AnotherTrait<u32>) {}
// Shouldn't warn
diff --git a/src/tools/clippy/tests/ui/impl_trait_in_params.stderr b/src/tools/clippy/tests/ui/impl_trait_in_params.stderr
index 803837435..36b4f27e9 100644
--- a/src/tools/clippy/tests/ui/impl_trait_in_params.stderr
+++ b/src/tools/clippy/tests/ui/impl_trait_in_params.stderr
@@ -5,13 +5,14 @@ LL | pub fn a(_: impl Trait) {}
| ^^^^^^^^^^
|
= note: `-D clippy::impl-trait-in-params` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::impl_trait_in_params)]`
help: add a type parameter
|
LL | pub fn a<{ /* Generic name */ }: Trait>(_: impl Trait) {}
| +++++++++++++++++++++++++++++++
error: '`impl Trait` used as a function parameter'
- --> $DIR/impl_trait_in_params.rs:9:29
+ --> $DIR/impl_trait_in_params.rs:11:29
|
LL | pub fn c<C: Trait>(_: C, _: impl Trait) {}
| ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/implicit_clone.fixed b/src/tools/clippy/tests/ui/implicit_clone.fixed
index e62db8b40..98556b4dd 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.fixed
+++ b/src/tools/clippy/tests/ui/implicit_clone.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::implicit_clone)]
#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
use std::borrow::Borrow;
@@ -68,7 +67,7 @@ fn main() {
let vec_ref = &vec;
let _ = return_owned_from_slice(vec_ref);
- let _ = vec_ref.clone();
+ let _ = vec_ref.to_owned();
let _ = vec_ref.clone();
// we expect no lint for this
diff --git a/src/tools/clippy/tests/ui/implicit_clone.rs b/src/tools/clippy/tests/ui/implicit_clone.rs
index 88352b06a..a064bd23a 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.rs
+++ b/src/tools/clippy/tests/ui/implicit_clone.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::implicit_clone)]
#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
use std::borrow::Borrow;
diff --git a/src/tools/clippy/tests/ui/implicit_clone.stderr b/src/tools/clippy/tests/ui/implicit_clone.stderr
index 92c1aa58a..64c31e651 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.stderr
+++ b/src/tools/clippy/tests/ui/implicit_clone.stderr
@@ -1,76 +1,71 @@
error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
- --> $DIR/implicit_clone.rs:66:13
+ --> $DIR/implicit_clone.rs:65:13
|
LL | let _ = vec.to_owned();
| ^^^^^^^^^^^^^^ help: consider using: `vec.clone()`
|
= note: `-D clippy::implicit-clone` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]`
error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type
- --> $DIR/implicit_clone.rs:67:13
+ --> $DIR/implicit_clone.rs:66:13
|
LL | let _ = vec.to_vec();
| ^^^^^^^^^^^^ help: consider using: `vec.clone()`
-error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
- --> $DIR/implicit_clone.rs:71:13
- |
-LL | let _ = vec_ref.to_owned();
- | ^^^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()`
-
error: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type
- --> $DIR/implicit_clone.rs:72:13
+ --> $DIR/implicit_clone.rs:71:13
|
LL | let _ = vec_ref.to_vec();
| ^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()`
error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
- --> $DIR/implicit_clone.rs:84:13
+ --> $DIR/implicit_clone.rs:83:13
|
LL | let _ = str.to_owned();
| ^^^^^^^^^^^^^^ help: consider using: `str.clone()`
error: implicitly cloning a `Kitten` by calling `to_owned` on its dereferenced type
- --> $DIR/implicit_clone.rs:88:13
+ --> $DIR/implicit_clone.rs:87:13
|
LL | let _ = kitten.to_owned();
| ^^^^^^^^^^^^^^^^^ help: consider using: `kitten.clone()`
error: implicitly cloning a `PathBuf` by calling `to_owned` on its dereferenced type
- --> $DIR/implicit_clone.rs:98:13
+ --> $DIR/implicit_clone.rs:97:13
|
LL | let _ = pathbuf.to_owned();
| ^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`
error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
- --> $DIR/implicit_clone.rs:99:13
+ --> $DIR/implicit_clone.rs:98:13
|
LL | let _ = pathbuf.to_path_buf();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`
error: implicitly cloning a `OsString` by calling `to_owned` on its dereferenced type
- --> $DIR/implicit_clone.rs:102:13
+ --> $DIR/implicit_clone.rs:101:13
|
LL | let _ = os_string.to_owned();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`
error: implicitly cloning a `OsString` by calling `to_os_string` on its dereferenced type
- --> $DIR/implicit_clone.rs:103:13
+ --> $DIR/implicit_clone.rs:102:13
|
LL | let _ = os_string.to_os_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`
error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
- --> $DIR/implicit_clone.rs:114:13
+ --> $DIR/implicit_clone.rs:113:13
|
LL | let _ = pathbuf_ref.to_path_buf();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(*pathbuf_ref).clone()`
error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type
- --> $DIR/implicit_clone.rs:117:13
+ --> $DIR/implicit_clone.rs:116:13
|
LL | let _ = pathbuf_ref.to_path_buf();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()`
-error: aborting due to 12 previous errors
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/implicit_hasher.rs b/src/tools/clippy/tests/ui/implicit_hasher.rs
index 7ed7bf94a..f7cd54174 100644
--- a/src/tools/clippy/tests/ui/implicit_hasher.rs
+++ b/src/tools/clippy/tests/ui/implicit_hasher.rs
@@ -1,5 +1,5 @@
-//@aux-build:proc_macros.rs:proc-macro
-
+//@aux-build:proc_macros.rs
+//@no-rustfix
#![deny(clippy::implicit_hasher)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/implicit_hasher.stderr b/src/tools/clippy/tests/ui/implicit_hasher.stderr
index 83b46de2e..a27590288 100644
--- a/src/tools/clippy/tests/ui/implicit_hasher.stderr
+++ b/src/tools/clippy/tests/ui/implicit_hasher.stderr
@@ -1,155 +1,40 @@
-error: impl for `HashMap` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:18:35
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
+ --> $DIR/implicit_hasher.rs:14:1
|
-LL | impl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> {
- | ^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/implicit_hasher.rs:3:9
- |
-LL | #![deny(clippy::implicit_hasher)]
- | ^^^^^^^^^^^^^^^^^^^^^^^
-help: consider adding a type parameter
- |
-LL | impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashMap<K, V, S> {
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
- |
-LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
- | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-error: impl for `HashMap` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:27:36
- |
-LL | impl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) {
- | ^^^^^^^^^^^^^
- |
-help: consider adding a type parameter
- |
-LL | impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for (HashMap<K, V, S>,) {
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
- |
-LL | ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),))
- | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-error: impl for `HashMap` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:32:19
- |
-LL | impl Foo<i16> for HashMap<String, String> {
- | ^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: consider adding a type parameter
- |
-LL | impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashMap<String, String, S> {
- | +++++++++++++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
- |
-LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
- | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-error: impl for `HashSet` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:49:32
- |
-LL | impl<T: Hash + Eq> Foo<i8> for HashSet<T> {
- | ^^^^^^^^^^
- |
-help: consider adding a type parameter
- |
-LL | impl<T: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashSet<T, S> {
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~
-help: ...and use generic constructor
- |
-LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
- | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL | pub trait Foo<T>: Sized {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
-error: impl for `HashSet` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:54:19
- |
-LL | impl Foo<i16> for HashSet<String> {
- | ^^^^^^^^^^^^^^^
- |
-help: consider adding a type parameter
- |
-LL | impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashSet<String, S> {
- | +++++++++++++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
- |
-LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
- | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-error: parameter of type `HashMap` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:71:23
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
+ --> $DIR/implicit_hasher.rs:71:1
|
LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
- | ^^^^^^^^^^^^^^^^^
- |
-help: consider adding a type parameter
- |
-LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _set: &mut HashSet<i32>) {}
- | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: parameter of type `HashSet` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:71:53
- |
-LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
- | ^^^^^^^^^^^^
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
+ --> $DIR/implicit_hasher.rs:74:1
|
-help: consider adding a type parameter
- |
-LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {}
- | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~
+LL | pub mod gen {
+ | ^^^^^^^^^^^
-error: impl for `HashMap` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:77:43
- |
-LL | impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
- | ^^^^^^^^^^^^^
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
+ --> $DIR/implicit_hasher.rs:92:1
|
- = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider adding a type parameter
- |
-LL | impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
- |
-LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
- | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL | pub mod test_macro;
+ | ^^^^^^^^^^^^^^^^^^^
-error: parameter of type `HashMap` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:83:31
- |
-LL | pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
- | ^^^^^^^^^^^^^^^^^
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
+ --> $DIR/implicit_hasher.rs:96:1
|
- = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider adding a type parameter
+LL | external! {
+ | ^^^^^^^^^
|
-LL | pub fn bar<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _set: &mut HashSet<i32>) {}
- | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~
+ = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: parameter of type `HashSet` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:83:61
- |
-LL | pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
- | ^^^^^^^^^^^^
- |
- = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider adding a type parameter
- |
-LL | pub fn bar<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {}
- | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~
-
-error: parameter of type `HashMap` should be generalized over different hashers
- --> $DIR/implicit_hasher.rs:101:35
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
+ --> $DIR/implicit_hasher.rs:101:1
|
LL | pub async fn election_vote(_data: HashMap<i32, i32>) {}
- | ^^^^^^^^^^^^^^^^^
- |
-help: consider adding a type parameter
- |
-LL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
- | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 11 previous errors
+error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/implicit_return.fixed b/src/tools/clippy/tests/ui/implicit_return.fixed
index 64813eafd..897f1b766 100644
--- a/src/tools/clippy/tests/ui/implicit_return.fixed
+++ b/src/tools/clippy/tests/ui/implicit_return.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(lint_reasons)]
#![warn(clippy::implicit_return)]
#![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)]
diff --git a/src/tools/clippy/tests/ui/implicit_return.rs b/src/tools/clippy/tests/ui/implicit_return.rs
index 39d47b110..fcff67b58 100644
--- a/src/tools/clippy/tests/ui/implicit_return.rs
+++ b/src/tools/clippy/tests/ui/implicit_return.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(lint_reasons)]
#![warn(clippy::implicit_return)]
#![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)]
diff --git a/src/tools/clippy/tests/ui/implicit_return.stderr b/src/tools/clippy/tests/ui/implicit_return.stderr
index 522bc3bf8..1edc6cc6f 100644
--- a/src/tools/clippy/tests/ui/implicit_return.stderr
+++ b/src/tools/clippy/tests/ui/implicit_return.stderr
@@ -1,91 +1,92 @@
error: missing `return` statement
- --> $DIR/implicit_return.rs:12:5
+ --> $DIR/implicit_return.rs:11:5
|
LL | true
| ^^^^ help: add `return` as shown: `return true`
|
= note: `-D clippy::implicit-return` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::implicit_return)]`
error: missing `return` statement
- --> $DIR/implicit_return.rs:16:15
+ --> $DIR/implicit_return.rs:15:15
|
LL | if true { true } else { false }
| ^^^^ help: add `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:16:29
+ --> $DIR/implicit_return.rs:15:29
|
LL | if true { true } else { false }
| ^^^^^ help: add `return` as shown: `return false`
error: missing `return` statement
- --> $DIR/implicit_return.rs:22:17
+ --> $DIR/implicit_return.rs:21:17
|
LL | true => false,
| ^^^^^ help: add `return` as shown: `return false`
error: missing `return` statement
- --> $DIR/implicit_return.rs:23:20
+ --> $DIR/implicit_return.rs:22:20
|
LL | false => { true },
| ^^^^ help: add `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:36:9
+ --> $DIR/implicit_return.rs:35:9
|
LL | break true;
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:43:13
+ --> $DIR/implicit_return.rs:42:13
|
LL | break true;
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:51:13
+ --> $DIR/implicit_return.rs:50:13
|
LL | break true;
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:69:18
+ --> $DIR/implicit_return.rs:68:18
|
LL | let _ = || { true };
| ^^^^ help: add `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:70:16
+ --> $DIR/implicit_return.rs:69:16
|
LL | let _ = || true;
| ^^^^ help: add `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:78:5
+ --> $DIR/implicit_return.rs:77:5
|
LL | format!("test {}", "test")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `return` as shown: `return format!("test {}", "test")`
error: missing `return` statement
- --> $DIR/implicit_return.rs:87:5
+ --> $DIR/implicit_return.rs:86:5
|
LL | m!(true, false)
| ^^^^^^^^^^^^^^^ help: add `return` as shown: `return m!(true, false)`
error: missing `return` statement
- --> $DIR/implicit_return.rs:93:13
+ --> $DIR/implicit_return.rs:92:13
|
LL | break true;
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
error: missing `return` statement
- --> $DIR/implicit_return.rs:98:17
+ --> $DIR/implicit_return.rs:97:17
|
LL | break 'outer false;
| ^^^^^^^^^^^^^^^^^^ help: change `break` to `return` as shown: `return false`
error: missing `return` statement
- --> $DIR/implicit_return.rs:113:5
+ --> $DIR/implicit_return.rs:112:5
|
LL | / loop {
LL | | m!(true);
@@ -100,7 +101,7 @@ LL + }
|
error: missing `return` statement
- --> $DIR/implicit_return.rs:127:5
+ --> $DIR/implicit_return.rs:126:5
|
LL | true
| ^^^^ help: add `return` as shown: `return true`
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_add.fixed b/src/tools/clippy/tests/ui/implicit_saturating_add.fixed
index 7fc510d6b..4cf8e3587 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_add.fixed
+++ b/src/tools/clippy/tests/ui/implicit_saturating_add.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::implicit_saturating_add)]
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_add.rs b/src/tools/clippy/tests/ui/implicit_saturating_add.rs
index 3dcd91f42..94513f34c 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_add.rs
+++ b/src/tools/clippy/tests/ui/implicit_saturating_add.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::implicit_saturating_add)]
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_add.stderr b/src/tools/clippy/tests/ui/implicit_saturating_add.stderr
index 42ae1b488..7119c8bf6 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_add.stderr
+++ b/src/tools/clippy/tests/ui/implicit_saturating_add.stderr
@@ -1,5 +1,5 @@
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:23:5
+ --> $DIR/implicit_saturating_add.rs:21:5
|
LL | / if u_8 != u8::MAX {
LL | | u_8 += 1;
@@ -7,9 +7,10 @@ LL | | }
| |_____^ help: use instead: `u_8 = u_8.saturating_add(1);`
|
= note: `-D clippy::implicit-saturating-add` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_add)]`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:27:5
+ --> $DIR/implicit_saturating_add.rs:25:5
|
LL | / if u_8 < u8::MAX {
LL | | u_8 += 1;
@@ -17,7 +18,7 @@ LL | | }
| |_____^ help: use instead: `u_8 = u_8.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:35:5
+ --> $DIR/implicit_saturating_add.rs:33:5
|
LL | / if u_16 != u16::MAX {
LL | | u_16 += 1;
@@ -25,7 +26,7 @@ LL | | }
| |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:39:5
+ --> $DIR/implicit_saturating_add.rs:37:5
|
LL | / if u_16 < u16::MAX {
LL | | u_16 += 1;
@@ -33,7 +34,7 @@ LL | | }
| |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:43:5
+ --> $DIR/implicit_saturating_add.rs:41:5
|
LL | / if u16::MAX > u_16 {
LL | | u_16 += 1;
@@ -41,7 +42,7 @@ LL | | }
| |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:47:5
+ --> $DIR/implicit_saturating_add.rs:45:5
|
LL | / if u_32 != u32::MAX {
LL | | u_32 += 1;
@@ -49,7 +50,7 @@ LL | | }
| |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:51:5
+ --> $DIR/implicit_saturating_add.rs:49:5
|
LL | / if u_32 < u32::MAX {
LL | | u_32 += 1;
@@ -57,7 +58,7 @@ LL | | }
| |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:55:5
+ --> $DIR/implicit_saturating_add.rs:53:5
|
LL | / if u32::MAX > u_32 {
LL | | u_32 += 1;
@@ -65,7 +66,7 @@ LL | | }
| |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:59:5
+ --> $DIR/implicit_saturating_add.rs:57:5
|
LL | / if u_64 != u64::MAX {
LL | | u_64 += 1;
@@ -73,7 +74,7 @@ LL | | }
| |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:63:5
+ --> $DIR/implicit_saturating_add.rs:61:5
|
LL | / if u_64 < u64::MAX {
LL | | u_64 += 1;
@@ -81,7 +82,7 @@ LL | | }
| |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:67:5
+ --> $DIR/implicit_saturating_add.rs:65:5
|
LL | / if u64::MAX > u_64 {
LL | | u_64 += 1;
@@ -89,7 +90,7 @@ LL | | }
| |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:71:5
+ --> $DIR/implicit_saturating_add.rs:69:5
|
LL | / if i_8 != i8::MAX {
LL | | i_8 += 1;
@@ -97,7 +98,7 @@ LL | | }
| |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:75:5
+ --> $DIR/implicit_saturating_add.rs:73:5
|
LL | / if i_8 < i8::MAX {
LL | | i_8 += 1;
@@ -105,7 +106,7 @@ LL | | }
| |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:79:5
+ --> $DIR/implicit_saturating_add.rs:77:5
|
LL | / if i8::MAX > i_8 {
LL | | i_8 += 1;
@@ -113,7 +114,7 @@ LL | | }
| |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:83:5
+ --> $DIR/implicit_saturating_add.rs:81:5
|
LL | / if i_16 != i16::MAX {
LL | | i_16 += 1;
@@ -121,7 +122,7 @@ LL | | }
| |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:87:5
+ --> $DIR/implicit_saturating_add.rs:85:5
|
LL | / if i_16 < i16::MAX {
LL | | i_16 += 1;
@@ -129,7 +130,7 @@ LL | | }
| |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:91:5
+ --> $DIR/implicit_saturating_add.rs:89:5
|
LL | / if i16::MAX > i_16 {
LL | | i_16 += 1;
@@ -137,7 +138,7 @@ LL | | }
| |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:95:5
+ --> $DIR/implicit_saturating_add.rs:93:5
|
LL | / if i_32 != i32::MAX {
LL | | i_32 += 1;
@@ -145,7 +146,7 @@ LL | | }
| |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:99:5
+ --> $DIR/implicit_saturating_add.rs:97:5
|
LL | / if i_32 < i32::MAX {
LL | | i_32 += 1;
@@ -153,7 +154,7 @@ LL | | }
| |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:103:5
+ --> $DIR/implicit_saturating_add.rs:101:5
|
LL | / if i32::MAX > i_32 {
LL | | i_32 += 1;
@@ -161,7 +162,7 @@ LL | | }
| |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:107:5
+ --> $DIR/implicit_saturating_add.rs:105:5
|
LL | / if i_64 != i64::MAX {
LL | | i_64 += 1;
@@ -169,7 +170,7 @@ LL | | }
| |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:111:5
+ --> $DIR/implicit_saturating_add.rs:109:5
|
LL | / if i_64 < i64::MAX {
LL | | i_64 += 1;
@@ -177,7 +178,7 @@ LL | | }
| |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:115:5
+ --> $DIR/implicit_saturating_add.rs:113:5
|
LL | / if i64::MAX > i_64 {
LL | | i_64 += 1;
@@ -185,7 +186,7 @@ LL | | }
| |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`
error: manual saturating add detected
- --> $DIR/implicit_saturating_add.rs:151:12
+ --> $DIR/implicit_saturating_add.rs:149:12
|
LL | } else if u_32 < u32::MAX {
| ____________^
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
index 1a11db098..27f679797 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)]
#![warn(clippy::implicit_saturating_sub)]
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
index 9369df674..5d7b95d2c 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)]
#![warn(clippy::implicit_saturating_sub)]
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
index 5e589d931..6e026d1a6 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
@@ -1,5 +1,5 @@
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:28:5
+ --> $DIR/implicit_saturating_sub.rs:27:5
|
LL | / if u_8 > 0 {
LL | | u_8 = u_8 - 1;
@@ -7,9 +7,10 @@ LL | | }
| |_____^ help: try: `u_8 = u_8.saturating_sub(1);`
|
= note: `-D clippy::implicit-saturating-sub` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:35:13
+ --> $DIR/implicit_saturating_sub.rs:34:13
|
LL | / if u_8 > 0 {
LL | | u_8 -= 1;
@@ -17,7 +18,7 @@ LL | | }
| |_____________^ help: try: `u_8 = u_8.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:49:5
+ --> $DIR/implicit_saturating_sub.rs:48:5
|
LL | / if u_16 > 0 {
LL | | u_16 -= 1;
@@ -25,7 +26,7 @@ LL | | }
| |_____^ help: try: `u_16 = u_16.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:59:5
+ --> $DIR/implicit_saturating_sub.rs:58:5
|
LL | / if u_32 != 0 {
LL | | u_32 -= 1;
@@ -33,7 +34,7 @@ LL | | }
| |_____^ help: try: `u_32 = u_32.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:80:5
+ --> $DIR/implicit_saturating_sub.rs:79:5
|
LL | / if u_64 > 0 {
LL | | u_64 -= 1;
@@ -41,7 +42,7 @@ LL | | }
| |_____^ help: try: `u_64 = u_64.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:85:5
+ --> $DIR/implicit_saturating_sub.rs:84:5
|
LL | / if 0 < u_64 {
LL | | u_64 -= 1;
@@ -49,7 +50,7 @@ LL | | }
| |_____^ help: try: `u_64 = u_64.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:90:5
+ --> $DIR/implicit_saturating_sub.rs:89:5
|
LL | / if 0 != u_64 {
LL | | u_64 -= 1;
@@ -57,7 +58,7 @@ LL | | }
| |_____^ help: try: `u_64 = u_64.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:111:5
+ --> $DIR/implicit_saturating_sub.rs:110:5
|
LL | / if u_usize > 0 {
LL | | u_usize -= 1;
@@ -65,7 +66,7 @@ LL | | }
| |_____^ help: try: `u_usize = u_usize.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:123:5
+ --> $DIR/implicit_saturating_sub.rs:122:5
|
LL | / if i_8 > i8::MIN {
LL | | i_8 -= 1;
@@ -73,7 +74,7 @@ LL | | }
| |_____^ help: try: `i_8 = i_8.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:128:5
+ --> $DIR/implicit_saturating_sub.rs:127:5
|
LL | / if i_8 > i8::MIN {
LL | | i_8 -= 1;
@@ -81,7 +82,7 @@ LL | | }
| |_____^ help: try: `i_8 = i_8.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:133:5
+ --> $DIR/implicit_saturating_sub.rs:132:5
|
LL | / if i_8 != i8::MIN {
LL | | i_8 -= 1;
@@ -89,7 +90,7 @@ LL | | }
| |_____^ help: try: `i_8 = i_8.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:138:5
+ --> $DIR/implicit_saturating_sub.rs:137:5
|
LL | / if i_8 != i8::MIN {
LL | | i_8 -= 1;
@@ -97,7 +98,7 @@ LL | | }
| |_____^ help: try: `i_8 = i_8.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:148:5
+ --> $DIR/implicit_saturating_sub.rs:147:5
|
LL | / if i_16 > i16::MIN {
LL | | i_16 -= 1;
@@ -105,7 +106,7 @@ LL | | }
| |_____^ help: try: `i_16 = i_16.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:153:5
+ --> $DIR/implicit_saturating_sub.rs:152:5
|
LL | / if i_16 > i16::MIN {
LL | | i_16 -= 1;
@@ -113,7 +114,7 @@ LL | | }
| |_____^ help: try: `i_16 = i_16.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:158:5
+ --> $DIR/implicit_saturating_sub.rs:157:5
|
LL | / if i_16 != i16::MIN {
LL | | i_16 -= 1;
@@ -121,7 +122,7 @@ LL | | }
| |_____^ help: try: `i_16 = i_16.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:163:5
+ --> $DIR/implicit_saturating_sub.rs:162:5
|
LL | / if i_16 != i16::MIN {
LL | | i_16 -= 1;
@@ -129,7 +130,7 @@ LL | | }
| |_____^ help: try: `i_16 = i_16.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:173:5
+ --> $DIR/implicit_saturating_sub.rs:172:5
|
LL | / if i_32 > i32::MIN {
LL | | i_32 -= 1;
@@ -137,7 +138,7 @@ LL | | }
| |_____^ help: try: `i_32 = i_32.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:178:5
+ --> $DIR/implicit_saturating_sub.rs:177:5
|
LL | / if i_32 > i32::MIN {
LL | | i_32 -= 1;
@@ -145,7 +146,7 @@ LL | | }
| |_____^ help: try: `i_32 = i_32.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:183:5
+ --> $DIR/implicit_saturating_sub.rs:182:5
|
LL | / if i_32 != i32::MIN {
LL | | i_32 -= 1;
@@ -153,7 +154,7 @@ LL | | }
| |_____^ help: try: `i_32 = i_32.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:188:5
+ --> $DIR/implicit_saturating_sub.rs:187:5
|
LL | / if i_32 != i32::MIN {
LL | | i_32 -= 1;
@@ -161,7 +162,7 @@ LL | | }
| |_____^ help: try: `i_32 = i_32.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:198:5
+ --> $DIR/implicit_saturating_sub.rs:197:5
|
LL | / if i64::MIN < i_64 {
LL | | i_64 -= 1;
@@ -169,7 +170,7 @@ LL | | }
| |_____^ help: try: `i_64 = i_64.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:203:5
+ --> $DIR/implicit_saturating_sub.rs:202:5
|
LL | / if i64::MIN != i_64 {
LL | | i_64 -= 1;
@@ -177,7 +178,7 @@ LL | | }
| |_____^ help: try: `i_64 = i_64.saturating_sub(1);`
error: implicitly performing saturating subtraction
- --> $DIR/implicit_saturating_sub.rs:208:5
+ --> $DIR/implicit_saturating_sub.rs:207:5
|
LL | / if i64::MIN < i_64 {
LL | | i_64 -= 1;
diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed
new file mode 100644
index 000000000..a50fa0ccf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.fixed
@@ -0,0 +1,125 @@
+#![warn(clippy::implied_bounds_in_impls)]
+#![allow(dead_code)]
+#![feature(return_position_impl_trait_in_trait)]
+
+use std::ops::{Deref, DerefMut};
+
+// Only one bound, nothing to lint.
+fn normal_deref<T>(x: T) -> impl Deref<Target = T> {
+ Box::new(x)
+}
+
+// Deref implied by DerefMut
+fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> {
+ Box::new(x)
+}
+
+trait GenericTrait<T> {}
+trait GenericTrait2<V> {}
+// U is intentionally at a different "index" in GenericSubtrait than `T` is in GenericTrait,
+// so this can be a good test to make sure that the calculations are right (no off-by-one errors,
+// ...)
+trait GenericSubtrait<T, U, V>: GenericTrait<U> + GenericTrait2<V> {}
+
+impl GenericTrait<i32> for () {}
+impl GenericTrait<i64> for () {}
+impl<V> GenericTrait2<V> for () {}
+impl<V> GenericSubtrait<(), i32, V> for () {}
+impl<V> GenericSubtrait<(), i64, V> for () {}
+
+fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U>
+where
+ (): GenericSubtrait<U, W, U>,
+{
+}
+
+fn generics_implied_multi<V>() -> impl GenericSubtrait<(), i32, V> {}
+
+fn generics_implied_multi2<T, V>() -> impl GenericSubtrait<(), T, V>
+where
+ (): GenericSubtrait<(), T, V> + GenericTrait<T>,
+{
+}
+
+// i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait<i32>, don't lint
+fn generics_different() -> impl GenericTrait<i32> + GenericSubtrait<(), i64, ()> {}
+
+// i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait<i32>, lint
+fn generics_same() -> impl GenericSubtrait<(), i32, ()> {}
+
+trait SomeTrait {
+ // Check that it works in trait declarations.
+ fn f() -> impl DerefMut<Target = u8>;
+}
+struct SomeStruct;
+impl SomeStruct {
+ // Check that it works in inherent impl blocks.
+ fn f() -> impl DerefMut<Target = u8> {
+ Box::new(123)
+ }
+}
+impl SomeTrait for SomeStruct {
+ // Check that it works in trait impls.
+ fn f() -> impl DerefMut<Target = u8> {
+ Box::new(42)
+ }
+}
+
+mod issue11422 {
+ use core::fmt::Debug;
+ // Some additional tests that would cause ICEs:
+
+ // `PartialOrd` has a default generic parameter and does not need to be explicitly specified.
+ // This needs special handling.
+ fn default_generic_param1() -> impl PartialOrd + Debug {}
+ fn default_generic_param2() -> impl PartialOrd + Debug {}
+
+ // Referring to `Self` in the supertrait clause needs special handling.
+ trait Trait1<X: ?Sized> {}
+ trait Trait2: Trait1<Self> {}
+ impl Trait1<()> for () {}
+ impl Trait2 for () {}
+
+ fn f() -> impl Trait1<()> + Trait2 {}
+}
+
+mod issue11435 {
+ // Associated type needs to be included on DoubleEndedIterator in the suggestion
+ fn my_iter() -> impl DoubleEndedIterator<Item = u32> {
+ 0..5
+ }
+
+ // Removing the `Clone` bound should include the `+` behind it in its remove suggestion
+ fn f() -> impl Copy {
+ 1
+ }
+
+ trait Trait1<T> {
+ type U;
+ }
+ impl Trait1<i32> for () {
+ type U = i64;
+ }
+ trait Trait2<T>: Trait1<T> {}
+ impl Trait2<i32> for () {}
+
+ // When the other trait has generics, it shouldn't add another pair of `<>`
+ fn f2() -> impl Trait2<i32, U = i64> {}
+
+ trait Trait3<T, U, V> {
+ type X;
+ type Y;
+ }
+ trait Trait4<T>: Trait3<T, i16, i64> {}
+ impl Trait3<i8, i16, i64> for () {
+ type X = i32;
+ type Y = i128;
+ }
+ impl Trait4<i8> for () {}
+
+ // Associated type `X` is specified, but `Y` is not, so only that associated type should be moved
+ // over
+ fn f3() -> impl Trait4<i8, X = i32, Y = i128> {}
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs
new file mode 100644
index 000000000..e74ed4425
--- /dev/null
+++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.rs
@@ -0,0 +1,125 @@
+#![warn(clippy::implied_bounds_in_impls)]
+#![allow(dead_code)]
+#![feature(return_position_impl_trait_in_trait)]
+
+use std::ops::{Deref, DerefMut};
+
+// Only one bound, nothing to lint.
+fn normal_deref<T>(x: T) -> impl Deref<Target = T> {
+ Box::new(x)
+}
+
+// Deref implied by DerefMut
+fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {
+ Box::new(x)
+}
+
+trait GenericTrait<T> {}
+trait GenericTrait2<V> {}
+// U is intentionally at a different "index" in GenericSubtrait than `T` is in GenericTrait,
+// so this can be a good test to make sure that the calculations are right (no off-by-one errors,
+// ...)
+trait GenericSubtrait<T, U, V>: GenericTrait<U> + GenericTrait2<V> {}
+
+impl GenericTrait<i32> for () {}
+impl GenericTrait<i64> for () {}
+impl<V> GenericTrait2<V> for () {}
+impl<V> GenericSubtrait<(), i32, V> for () {}
+impl<V> GenericSubtrait<(), i64, V> for () {}
+
+fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>
+where
+ (): GenericSubtrait<U, W, U>,
+{
+}
+
+fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
+
+fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
+where
+ (): GenericSubtrait<(), T, V> + GenericTrait<T>,
+{
+}
+
+// i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait<i32>, don't lint
+fn generics_different() -> impl GenericTrait<i32> + GenericSubtrait<(), i64, ()> {}
+
+// i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait<i32>, lint
+fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}
+
+trait SomeTrait {
+ // Check that it works in trait declarations.
+ fn f() -> impl Deref + DerefMut<Target = u8>;
+}
+struct SomeStruct;
+impl SomeStruct {
+ // Check that it works in inherent impl blocks.
+ fn f() -> impl Deref + DerefMut<Target = u8> {
+ Box::new(123)
+ }
+}
+impl SomeTrait for SomeStruct {
+ // Check that it works in trait impls.
+ fn f() -> impl Deref + DerefMut<Target = u8> {
+ Box::new(42)
+ }
+}
+
+mod issue11422 {
+ use core::fmt::Debug;
+ // Some additional tests that would cause ICEs:
+
+ // `PartialOrd` has a default generic parameter and does not need to be explicitly specified.
+ // This needs special handling.
+ fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {}
+ fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {}
+
+ // Referring to `Self` in the supertrait clause needs special handling.
+ trait Trait1<X: ?Sized> {}
+ trait Trait2: Trait1<Self> {}
+ impl Trait1<()> for () {}
+ impl Trait2 for () {}
+
+ fn f() -> impl Trait1<()> + Trait2 {}
+}
+
+mod issue11435 {
+ // Associated type needs to be included on DoubleEndedIterator in the suggestion
+ fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator {
+ 0..5
+ }
+
+ // Removing the `Clone` bound should include the `+` behind it in its remove suggestion
+ fn f() -> impl Copy + Clone {
+ 1
+ }
+
+ trait Trait1<T> {
+ type U;
+ }
+ impl Trait1<i32> for () {
+ type U = i64;
+ }
+ trait Trait2<T>: Trait1<T> {}
+ impl Trait2<i32> for () {}
+
+ // When the other trait has generics, it shouldn't add another pair of `<>`
+ fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {}
+
+ trait Trait3<T, U, V> {
+ type X;
+ type Y;
+ }
+ trait Trait4<T>: Trait3<T, i16, i64> {}
+ impl Trait3<i8, i16, i64> for () {
+ type X = i32;
+ type Y = i128;
+ }
+ impl Trait4<i8> for () {}
+
+ // Associated type `X` is specified, but `Y` is not, so only that associated type should be moved
+ // over
+ fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {}
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr b/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr
new file mode 100644
index 000000000..72dc2a183
--- /dev/null
+++ b/src/tools/clippy/tests/ui/implied_bounds_in_impls.stderr
@@ -0,0 +1,196 @@
+error: this bound is already specified as the supertrait of `DerefMut<Target = T>`
+ --> $DIR/implied_bounds_in_impls.rs:13:36
+ |
+LL | fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::implied-bounds-in-impls` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::implied_bounds_in_impls)]`
+help: try removing this bound
+ |
+LL - fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {
+LL + fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> {
+ |
+
+error: this bound is already specified as the supertrait of `GenericSubtrait<U, W, U>`
+ --> $DIR/implied_bounds_in_impls.rs:30:37
+ |
+LL | fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>
+ | ^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>
+LL + fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U>
+ |
+
+error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>`
+ --> $DIR/implied_bounds_in_impls.rs:36:40
+ |
+LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
+LL + fn generics_implied_multi<V>() -> impl GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
+ |
+
+error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>`
+ --> $DIR/implied_bounds_in_impls.rs:36:60
+ |
+LL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
+ | ^^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}
+LL + fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, V> {}
+ |
+
+error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>`
+ --> $DIR/implied_bounds_in_impls.rs:38:44
+ |
+LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
+ | ^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
+LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait2<V> + GenericSubtrait<(), T, V>
+ |
+
+error: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>`
+ --> $DIR/implied_bounds_in_impls.rs:38:62
+ |
+LL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
+ | ^^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>
+LL + fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericSubtrait<(), T, V>
+ |
+
+error: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, ()>`
+ --> $DIR/implied_bounds_in_impls.rs:48:28
+ |
+LL | fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}
+LL + fn generics_same() -> impl GenericSubtrait<(), i32, ()> {}
+ |
+
+error: this bound is already specified as the supertrait of `DerefMut<Target = u8>`
+ --> $DIR/implied_bounds_in_impls.rs:52:20
+ |
+LL | fn f() -> impl Deref + DerefMut<Target = u8>;
+ | ^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn f() -> impl Deref + DerefMut<Target = u8>;
+LL + fn f() -> impl DerefMut<Target = u8>;
+ |
+
+error: this bound is already specified as the supertrait of `DerefMut<Target = u8>`
+ --> $DIR/implied_bounds_in_impls.rs:57:20
+ |
+LL | fn f() -> impl Deref + DerefMut<Target = u8> {
+ | ^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn f() -> impl Deref + DerefMut<Target = u8> {
+LL + fn f() -> impl DerefMut<Target = u8> {
+ |
+
+error: this bound is already specified as the supertrait of `DerefMut<Target = u8>`
+ --> $DIR/implied_bounds_in_impls.rs:63:20
+ |
+LL | fn f() -> impl Deref + DerefMut<Target = u8> {
+ | ^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn f() -> impl Deref + DerefMut<Target = u8> {
+LL + fn f() -> impl DerefMut<Target = u8> {
+ |
+
+error: this bound is already specified as the supertrait of `PartialOrd`
+ --> $DIR/implied_bounds_in_impls.rs:74:41
+ |
+LL | fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {}
+ | ^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {}
+LL + fn default_generic_param1() -> impl PartialOrd + Debug {}
+ |
+
+error: this bound is already specified as the supertrait of `PartialOrd`
+ --> $DIR/implied_bounds_in_impls.rs:75:54
+ |
+LL | fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {}
+ | ^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {}
+LL + fn default_generic_param2() -> impl PartialOrd + Debug {}
+ |
+
+error: this bound is already specified as the supertrait of `DoubleEndedIterator`
+ --> $DIR/implied_bounds_in_impls.rs:88:26
+ |
+LL | fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator {
+LL + fn my_iter() -> impl DoubleEndedIterator<Item = u32> {
+ |
+
+error: this bound is already specified as the supertrait of `Copy`
+ --> $DIR/implied_bounds_in_impls.rs:93:27
+ |
+LL | fn f() -> impl Copy + Clone {
+ | ^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn f() -> impl Copy + Clone {
+LL + fn f() -> impl Copy {
+ |
+
+error: this bound is already specified as the supertrait of `Trait2<i32>`
+ --> $DIR/implied_bounds_in_impls.rs:107:21
+ |
+LL | fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {}
+LL + fn f2() -> impl Trait2<i32, U = i64> {}
+ |
+
+error: this bound is already specified as the supertrait of `Trait4<i8, X = i32>`
+ --> $DIR/implied_bounds_in_impls.rs:122:21
+ |
+LL | fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try removing this bound
+ |
+LL - fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {}
+LL + fn f3() -> impl Trait4<i8, X = i32, Y = i128> {}
+ |
+
+error: aborting due to 16 previous errors
+
diff --git a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed
index 06919809e..3f1dfbbae 100644
--- a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed
+++ b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#[warn(clippy::inconsistent_digit_grouping)]
#[deny(clippy::unreadable_literal)]
#[allow(unused_variables, clippy::excessive_precision)]
diff --git a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs
index 04d9125f2..ac47ae175 100644
--- a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs
+++ b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#[warn(clippy::inconsistent_digit_grouping)]
#[deny(clippy::unreadable_literal)]
#[allow(unused_variables, clippy::excessive_precision)]
diff --git a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.stderr b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.stderr
index b8ac91554..6aeb33eda 100644
--- a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.stderr
+++ b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.stderr
@@ -1,67 +1,68 @@
error: digits grouped inconsistently by underscores
- --> $DIR/inconsistent_digit_grouping.rs:26:16
+ --> $DIR/inconsistent_digit_grouping.rs:25:16
|
LL | let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);
| ^^^^^^^^ help: consider: `123_456`
|
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`
error: digits grouped inconsistently by underscores
- --> $DIR/inconsistent_digit_grouping.rs:26:26
+ --> $DIR/inconsistent_digit_grouping.rs:25:26
|
LL | let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);
| ^^^^^^^^^^ help: consider: `12_345_678`
error: digits grouped inconsistently by underscores
- --> $DIR/inconsistent_digit_grouping.rs:26:38
+ --> $DIR/inconsistent_digit_grouping.rs:25:38
|
LL | let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);
| ^^^^^^^^ help: consider: `1_234_567`
error: digits grouped inconsistently by underscores
- --> $DIR/inconsistent_digit_grouping.rs:26:48
+ --> $DIR/inconsistent_digit_grouping.rs:25:48
|
LL | let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);
| ^^^^^^^^^^^^^^ help: consider: `1_234.567_8_f32`
error: digits grouped inconsistently by underscores
- --> $DIR/inconsistent_digit_grouping.rs:26:64
+ --> $DIR/inconsistent_digit_grouping.rs:25:64
|
LL | let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);
| ^^^^^^^^^^^^^^ help: consider: `1.234_567_8_f32`
error: long literal lacking separators
- --> $DIR/inconsistent_digit_grouping.rs:29:13
+ --> $DIR/inconsistent_digit_grouping.rs:28:13
|
LL | let _ = 0x100000;
| ^^^^^^^^ help: consider: `0x0010_0000`
|
note: the lint level is defined here
- --> $DIR/inconsistent_digit_grouping.rs:3:8
+ --> $DIR/inconsistent_digit_grouping.rs:2:8
|
LL | #[deny(clippy::unreadable_literal)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: long literal lacking separators
- --> $DIR/inconsistent_digit_grouping.rs:30:13
+ --> $DIR/inconsistent_digit_grouping.rs:29:13
|
LL | let _ = 0x1000000;
| ^^^^^^^^^ help: consider: `0x0100_0000`
error: long literal lacking separators
- --> $DIR/inconsistent_digit_grouping.rs:31:13
+ --> $DIR/inconsistent_digit_grouping.rs:30:13
|
LL | let _ = 0x10000000;
| ^^^^^^^^^^ help: consider: `0x1000_0000`
error: long literal lacking separators
- --> $DIR/inconsistent_digit_grouping.rs:32:13
+ --> $DIR/inconsistent_digit_grouping.rs:31:13
|
LL | let _ = 0x100000000_u64;
| ^^^^^^^^^^^^^^^ help: consider: `0x0001_0000_0000_u64`
error: digits grouped inconsistently by underscores
- --> $DIR/inconsistent_digit_grouping.rs:35:18
+ --> $DIR/inconsistent_digit_grouping.rs:34:18
|
LL | let _: f32 = 1_23_456.;
| ^^^^^^^^^ help: consider: `123_456.`
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
index d84346e87..5778f8f52 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::inconsistent_struct_constructor)]
#![allow(clippy::redundant_field_names)]
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
index 87fba7448..9efaf0689 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::inconsistent_struct_constructor)]
#![allow(clippy::redundant_field_names)]
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
index 785a6dc9d..fc080d7ec 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
@@ -1,13 +1,14 @@
error: struct constructor field order is inconsistent with struct definition field order
- --> $DIR/inconsistent_struct_constructor.rs:29:9
+ --> $DIR/inconsistent_struct_constructor.rs:28:9
|
LL | Foo { y, x, z };
| ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }`
|
= note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]`
error: struct constructor field order is inconsistent with struct definition field order
- --> $DIR/inconsistent_struct_constructor.rs:56:9
+ --> $DIR/inconsistent_struct_constructor.rs:55:9
|
LL | / Foo {
LL | | z,
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.fixed b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.fixed
new file mode 100644
index 000000000..13f0cbe9c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.fixed
@@ -0,0 +1,177 @@
+#![deny(clippy::index_refutable_slice)]
+#![allow(clippy::uninlined_format_args)]
+
+enum SomeEnum<T> {
+ One(T),
+ Two(T),
+ Three(T),
+ Four(T),
+}
+
+fn lintable_examples() {
+ // Try with reference
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some([slice_0, ..]) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ println!("{}", slice_0);
+ }
+
+ // Try with copy
+ let slice: Option<[u32; 3]> = Some([1, 2, 3]);
+ if let Some([slice_0, ..]) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ println!("{}", slice_0);
+ }
+
+ // Try with long slice and small indices
+ let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+ if let Some([slice_0, _, slice_2, ..]) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ println!("{}", slice_2);
+ println!("{}", slice_0);
+ }
+
+ // Multiple bindings
+ let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);
+ if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ println!("{}", slice_0);
+ }
+
+ // Two lintable slices in one if let
+ let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);
+ let b_wrapped: Option<[u32; 2]> = Some([4, 6]);
+ if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ //~| ERROR: this binding can be a slice pattern to avoid indexing
+ println!("{} -> {}", a_2, b_1);
+ }
+
+ // This requires the slice values to be borrowed as the slice values can only be
+ // borrowed and `String` doesn't implement copy
+ let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
+ if let Some([_, ref slice_1, ..]) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ println!("{:?}", slice_1);
+ }
+ println!("{:?}", slice);
+
+ // This should not suggest using the `ref` keyword as the scrutinee is already
+ // a reference
+ let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
+ if let Some([slice_0, ..]) = &slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ println!("{:?}", slice_0);
+ }
+ println!("{:?}", slice);
+}
+
+fn slice_index_above_limit() {
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+
+ if let Some(slice) = slice {
+ // Would cause a panic, IDK
+ println!("{}", slice[7]);
+ }
+}
+
+fn slice_is_used() {
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some(slice) = slice {
+ println!("{:?}", slice.len());
+ }
+
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some(slice) = slice {
+ println!("{:?}", slice.to_vec());
+ }
+
+ let opt: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
+ if let Some(slice) = opt {
+ if !slice.is_empty() {
+ println!("first: {}", slice[0]);
+ }
+ }
+}
+
+/// The slice is used by an external function and should therefore not be linted
+fn check_slice_as_arg() {
+ fn is_interesting<T>(slice: &[T; 2]) -> bool {
+ !slice.is_empty()
+ }
+
+ let slice_wrapped: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
+ if let Some(slice) = &slice_wrapped {
+ if is_interesting(slice) {
+ println!("This is interesting {}", slice[0]);
+ }
+ }
+ println!("{:?}", slice_wrapped);
+}
+
+fn check_slice_in_struct() {
+ #[derive(Debug)]
+ struct Wrapper<'a> {
+ inner: Option<&'a [String]>,
+ is_awesome: bool,
+ }
+
+ impl<'a> Wrapper<'a> {
+ fn is_super_awesome(&self) -> bool {
+ self.is_awesome
+ }
+ }
+
+ let inner = &[String::from("New"), String::from("World")];
+ let wrap = Wrapper {
+ inner: Some(inner),
+ is_awesome: true,
+ };
+
+ // Test 1: Field access
+ if let Some([slice_0, ..]) = wrap.inner {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ if wrap.is_awesome {
+ println!("This is awesome! {}", slice_0);
+ }
+ }
+
+ // Test 2: function access
+ if let Some([slice_0, ..]) = wrap.inner {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ if wrap.is_super_awesome() {
+ println!("This is super awesome! {}", slice_0);
+ }
+ }
+ println!("Complete wrap: {:?}", wrap);
+}
+
+/// This would be a nice additional feature to have in the future, but adding it
+/// now would make the PR too large. This is therefore only a test that we don't
+/// lint cases we can't make a reasonable suggestion for
+fn mutable_slice_index() {
+ // Mut access
+ let mut slice: Option<[String; 1]> = Some([String::from("Penguin")]);
+ if let Some(ref mut slice) = slice {
+ slice[0] = String::from("Mr. Penguin");
+ }
+ println!("Use after modification: {:?}", slice);
+
+ // Mut access on reference
+ let mut slice: Option<[String; 1]> = Some([String::from("Cat")]);
+ if let Some(slice) = &mut slice {
+ slice[0] = String::from("Lord Meow Meow");
+ }
+ println!("Use after modification: {:?}", slice);
+}
+
+/// The lint will ignore bindings with sub patterns as it would be hard
+/// to build correct suggestions for these instances :)
+fn binding_with_sub_pattern() {
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some(slice @ [_, _, _]) = slice {
+ println!("{:?}", slice[2]);
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
index 0a3374d11..d8d38c167 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
@@ -12,18 +12,21 @@ fn lintable_examples() {
// Try with reference
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice[0]);
}
// Try with copy
let slice: Option<[u32; 3]> = Some([1, 2, 3]);
if let Some(slice) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice[0]);
}
// Try with long slice and small indices
let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);
if let Some(slice) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice[2]);
println!("{}", slice[0]);
}
@@ -31,6 +34,7 @@ fn lintable_examples() {
// Multiple bindings
let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);
if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{}", slice[0]);
}
@@ -38,6 +42,8 @@ fn lintable_examples() {
let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);
let b_wrapped: Option<[u32; 2]> = Some([4, 6]);
if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ //~| ERROR: this binding can be a slice pattern to avoid indexing
println!("{} -> {}", a[2], b[1]);
}
@@ -45,6 +51,7 @@ fn lintable_examples() {
// borrowed and `String` doesn't implement copy
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
if let Some(ref slice) = slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{:?}", slice[1]);
}
println!("{:?}", slice);
@@ -53,6 +60,7 @@ fn lintable_examples() {
// a reference
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
if let Some(slice) = &slice {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
println!("{:?}", slice[0]);
}
println!("{:?}", slice);
@@ -122,6 +130,7 @@ fn check_slice_in_struct() {
// Test 1: Field access
if let Some(slice) = wrap.inner {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
if wrap.is_awesome {
println!("This is awesome! {}", slice[0]);
}
@@ -129,6 +138,7 @@ fn check_slice_in_struct() {
// Test 2: function access
if let Some(slice) = wrap.inner {
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
if wrap.is_super_awesome() {
println!("This is super awesome! {}", slice[0]);
}
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.stderr b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.stderr
index 0a13ac135..f0e635954 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.stderr
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.stderr
@@ -19,7 +19,7 @@ LL | println!("{}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:20:17
+ --> $DIR/if_let_slice_binding.rs:21:17
|
LL | if let Some(slice) = slice {
| ^^^^^
@@ -34,7 +34,7 @@ LL | println!("{}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:26:17
+ --> $DIR/if_let_slice_binding.rs:28:17
|
LL | if let Some(slice) = slice {
| ^^^^^
@@ -50,7 +50,7 @@ LL ~ println!("{}", slice_0);
|
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:33:26
+ --> $DIR/if_let_slice_binding.rs:36:26
|
LL | if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {
| ^^^^^
@@ -65,7 +65,7 @@ LL | println!("{}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:40:29
+ --> $DIR/if_let_slice_binding.rs:44:29
|
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
| ^
@@ -80,7 +80,7 @@ LL | println!("{} -> {}", a_2, b[1]);
| ~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:40:38
+ --> $DIR/if_let_slice_binding.rs:44:38
|
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
| ^
@@ -95,7 +95,7 @@ LL | println!("{} -> {}", a[2], b_1);
| ~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:47:21
+ --> $DIR/if_let_slice_binding.rs:53:21
|
LL | if let Some(ref slice) = slice {
| ^^^^^
@@ -110,7 +110,7 @@ LL | println!("{:?}", slice_1);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:55:17
+ --> $DIR/if_let_slice_binding.rs:62:17
|
LL | if let Some(slice) = &slice {
| ^^^^^
@@ -125,7 +125,7 @@ LL | println!("{:?}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:124:17
+ --> $DIR/if_let_slice_binding.rs:132:17
|
LL | if let Some(slice) = wrap.inner {
| ^^^^^
@@ -140,7 +140,7 @@ LL | println!("This is awesome! {}", slice_0);
| ~~~~~~~
error: this binding can be a slice pattern to avoid indexing
- --> $DIR/if_let_slice_binding.rs:131:17
+ --> $DIR/if_let_slice_binding.rs:140:17
|
LL | if let Some(slice) = wrap.inner {
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
new file mode 100644
index 000000000..72edc539f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
@@ -0,0 +1,29 @@
+#![deny(clippy::index_refutable_slice)]
+
+extern crate if_chain;
+use if_chain::if_chain;
+
+macro_rules! if_let_slice_macro {
+ () => {
+ // This would normally be linted
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some(slice) = slice {
+ println!("{}", slice[0]);
+ }
+ };
+}
+
+fn main() {
+ // Don't lint this
+ if_let_slice_macro!();
+
+ // Do lint this
+ if_chain! {
+ let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+ if let Some([slice_0, ..]) = slice;
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
+ then {
+ println!("{}", slice_0);
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
index 406e82083..7b474ba42 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
@@ -21,6 +21,7 @@ fn main() {
if_chain! {
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
if let Some(slice) = slice;
+ //~^ ERROR: this binding can be a slice pattern to avoid indexing
then {
println!("{}", slice[0]);
}
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
index 16f9e47e8..f0da5dfc6 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
@@ -12,7 +12,9 @@
const ARR: [i32; 2] = [1, 2];
const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+//~^ ERROR: indexing may panic
const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
+//~^ ERROR: indexing may panic
const fn idx() -> usize {
1
@@ -25,29 +27,51 @@ fn main() {
let x = [1, 2, 3, 4];
let index: usize = 1;
x[index];
- x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
- x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+ //~^ ERROR: indexing may panic
+ // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+ x[4];
+ // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+ x[1 << 3];
- x[0]; // Ok, should not produce stderr.
- x[3]; // Ok, should not produce stderr.
- x[const { idx() }]; // Ok, should not produce stderr.
- x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
- const { &ARR[idx()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
- const { &ARR[idx4()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+ // Ok, should not produce stderr.
+ x[0];
+ // Ok, should not produce stderr.
+ x[3];
+ // Ok, should not produce stderr.
+ x[const { idx() }];
+ // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+ x[const { idx4() }];
+ // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+ const { &ARR[idx()] };
+ //~^ ERROR: indexing may panic
+ // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+ const { &ARR[idx4()] };
+ //~^ ERROR: indexing may panic
let y = &x;
- y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021
- y[4]; // Ok, rustc will handle references too.
+ // Ok, referencing shouldn't affect this lint. See the issue 6021
+ y[0];
+ // Ok, rustc will handle references too.
+ y[4];
let v = vec![0; 5];
v[0];
+ //~^ ERROR: indexing may panic
v[10];
+ //~^ ERROR: indexing may panic
v[1 << 3];
+ //~^ ERROR: indexing may panic
- const N: usize = 15; // Out of bounds
- const M: usize = 3; // In bounds
- x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
- x[M]; // Ok, should not produce stderr.
+ // Out of bounds
+ const N: usize = 15;
+ // In bounds
+ const M: usize = 3;
+ // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+ x[N];
+ // Ok, should not produce stderr.
+ x[M];
v[N];
+ //~^ ERROR: indexing may panic
v[M];
+ //~^ ERROR: indexing may panic
}
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index f4357c1d5..1c34875d2 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -7,9 +7,10 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re
= help: consider using `.get(n)` or `.get_mut(n)` instead
= note: the suggestion might not be applicable in constant blocks
= note: `-D clippy::indexing-slicing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:15:24
+ --> $DIR/indexing_slicing_index.rs:16:24
|
LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
| ^^^^^^^^^^^
@@ -18,19 +19,19 @@ LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
= note: the suggestion might not be applicable in constant blocks
error[E0080]: evaluation of `main::{constant#3}` failed
- --> $DIR/indexing_slicing_index.rs:36:14
+ --> $DIR/indexing_slicing_index.rs:48:14
|
-LL | const { &ARR[idx4()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
-note: erroneous constant used
- --> $DIR/indexing_slicing_index.rs:36:5
+note: erroneous constant encountered
+ --> $DIR/indexing_slicing_index.rs:48:5
|
-LL | const { &ARR[idx4()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^^^^^^^^^^^^
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:27:5
+ --> $DIR/indexing_slicing_index.rs:29:5
|
LL | x[index];
| ^^^^^^^^
@@ -38,25 +39,25 @@ LL | x[index];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:35:14
+ --> $DIR/indexing_slicing_index.rs:45:14
|
-LL | const { &ARR[idx()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+LL | const { &ARR[idx()] };
| ^^^^^^^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
= note: the suggestion might not be applicable in constant blocks
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:36:14
+ --> $DIR/indexing_slicing_index.rs:48:14
|
-LL | const { &ARR[idx4()] }; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
+LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
= note: the suggestion might not be applicable in constant blocks
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:43:5
+ --> $DIR/indexing_slicing_index.rs:58:5
|
LL | v[0];
| ^^^^
@@ -64,7 +65,7 @@ LL | v[0];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:44:5
+ --> $DIR/indexing_slicing_index.rs:60:5
|
LL | v[10];
| ^^^^^
@@ -72,7 +73,7 @@ LL | v[10];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:45:5
+ --> $DIR/indexing_slicing_index.rs:62:5
|
LL | v[1 << 3];
| ^^^^^^^^^
@@ -80,7 +81,7 @@ LL | v[1 << 3];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:51:5
+ --> $DIR/indexing_slicing_index.rs:73:5
|
LL | v[N];
| ^^^^
@@ -88,7 +89,7 @@ LL | v[N];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
- --> $DIR/indexing_slicing_index.rs:52:5
+ --> $DIR/indexing_slicing_index.rs:75:5
|
LL | v[M];
| ^^^^
@@ -96,7 +97,7 @@ LL | v[M];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error[E0080]: evaluation of constant value failed
- --> $DIR/indexing_slicing_index.rs:15:24
+ --> $DIR/indexing_slicing_index.rs:16:24
|
LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_slice.rs b/src/tools/clippy/tests/ui/indexing_slicing_slice.rs
index 939b6ac36..fc591021e 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_slice.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_slice.rs
@@ -10,12 +10,22 @@ fn main() {
let index_from: usize = 2;
let index_to: usize = 3;
&x[index..];
+ //~^ ERROR: slicing may panic
&x[..index];
+ //~^ ERROR: slicing may panic
&x[index_from..index_to];
- &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to].
- &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and another for slicing [..10].
+ //~^ ERROR: slicing may panic
+ &x[index_from..][..index_to];
+ //~^ ERROR: slicing may panic
+ //~| ERROR: slicing may panic
+ &x[5..][..10];
+ //~^ ERROR: slicing may panic
+ //~| ERROR: range is out of bounds
+ //~| NOTE: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`
&x[0..][..3];
+ //~^ ERROR: slicing may panic
&x[1..][..5];
+ //~^ ERROR: slicing may panic
&x[0..].get(..3); // Ok, should not produce stderr.
&x[0..3]; // Ok, should not produce stderr.
@@ -23,15 +33,22 @@ fn main() {
let y = &x;
&y[1..2];
&y[0..=4];
+ //~^ ERROR: range is out of bounds
&y[..=4];
+ //~^ ERROR: range is out of bounds
&y[..]; // Ok, should not produce stderr.
let v = vec![0; 5];
&v[10..100];
- &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100].
+ //~^ ERROR: slicing may panic
+ &x[10..][..100];
+ //~^ ERROR: slicing may panic
+ //~| ERROR: range is out of bounds
&v[10..];
+ //~^ ERROR: slicing may panic
&v[..100];
+ //~^ ERROR: slicing may panic
&v[..]; // Ok, should not produce stderr.
}
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
index dc54bd413..eebe67810 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
@@ -6,9 +6,10 @@ LL | &x[index..];
|
= help: consider using `.get(n..)` or .get_mut(n..)` instead
= note: `-D clippy::indexing-slicing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:13:6
+ --> $DIR/indexing_slicing_slice.rs:14:6
|
LL | &x[..index];
| ^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | &x[..index];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:14:6
+ --> $DIR/indexing_slicing_slice.rs:16:6
|
LL | &x[index_from..index_to];
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,39 +25,40 @@ LL | &x[index_from..index_to];
= help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:15:6
+ --> $DIR/indexing_slicing_slice.rs:18:6
|
-LL | &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to].
+LL | &x[index_from..][..index_to];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:15:6
+ --> $DIR/indexing_slicing_slice.rs:18:6
|
-LL | &x[index_from..][..index_to]; // Two lint reports, one for [index_from..] and another for [..index_to].
+LL | &x[index_from..][..index_to];
| ^^^^^^^^^^^^^^^
|
= help: consider using `.get(n..)` or .get_mut(n..)` instead
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:16:6
+ --> $DIR/indexing_slicing_slice.rs:21:6
|
-LL | &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and another for slicing [..10].
+LL | &x[5..][..10];
| ^^^^^^^^^^^^
|
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
- --> $DIR/indexing_slicing_slice.rs:16:8
+ --> $DIR/indexing_slicing_slice.rs:21:8
|
-LL | &x[5..][..10]; // Two lint reports, one for out of bounds [5..] and another for slicing [..10].
+LL | &x[5..][..10];
| ^
|
= note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:17:6
+ --> $DIR/indexing_slicing_slice.rs:25:6
|
LL | &x[0..][..3];
| ^^^^^^^^^^^
@@ -64,7 +66,7 @@ LL | &x[0..][..3];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:18:6
+ --> $DIR/indexing_slicing_slice.rs:27:6
|
LL | &x[1..][..5];
| ^^^^^^^^^^^
@@ -72,19 +74,19 @@ LL | &x[1..][..5];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
- --> $DIR/indexing_slicing_slice.rs:25:12
+ --> $DIR/indexing_slicing_slice.rs:35:12
|
LL | &y[0..=4];
| ^
error: range is out of bounds
- --> $DIR/indexing_slicing_slice.rs:26:11
+ --> $DIR/indexing_slicing_slice.rs:37:11
|
LL | &y[..=4];
| ^
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:31:6
+ --> $DIR/indexing_slicing_slice.rs:43:6
|
LL | &v[10..100];
| ^^^^^^^^^^
@@ -92,21 +94,21 @@ LL | &v[10..100];
= help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:32:6
+ --> $DIR/indexing_slicing_slice.rs:45:6
|
-LL | &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100].
+LL | &x[10..][..100];
| ^^^^^^^^^^^^^^
|
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
- --> $DIR/indexing_slicing_slice.rs:32:8
+ --> $DIR/indexing_slicing_slice.rs:45:8
|
-LL | &x[10..][..100]; // Two lint reports, one for [10..] and another for [..100].
+LL | &x[10..][..100];
| ^^
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:33:6
+ --> $DIR/indexing_slicing_slice.rs:48:6
|
LL | &v[10..];
| ^^^^^^^
@@ -114,7 +116,7 @@ LL | &v[10..];
= help: consider using `.get(n..)` or .get_mut(n..)` instead
error: slicing may panic
- --> $DIR/indexing_slicing_slice.rs:34:6
+ --> $DIR/indexing_slicing_slice.rs:50:6
|
LL | &v[..100];
| ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/inefficient_to_string.fixed b/src/tools/clippy/tests/ui/inefficient_to_string.fixed
index 557f7fb73..1e1932311 100644
--- a/src/tools/clippy/tests/ui/inefficient_to_string.fixed
+++ b/src/tools/clippy/tests/ui/inefficient_to_string.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::inefficient_to_string)]
use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/inefficient_to_string.rs b/src/tools/clippy/tests/ui/inefficient_to_string.rs
index 6503001e3..f027bae6f 100644
--- a/src/tools/clippy/tests/ui/inefficient_to_string.rs
+++ b/src/tools/clippy/tests/ui/inefficient_to_string.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::inefficient_to_string)]
use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/inefficient_to_string.stderr b/src/tools/clippy/tests/ui/inefficient_to_string.stderr
index 914dc92bf..4b93465c4 100644
--- a/src/tools/clippy/tests/ui/inefficient_to_string.stderr
+++ b/src/tools/clippy/tests/ui/inefficient_to_string.stderr
@@ -1,18 +1,18 @@
error: calling `to_string` on `&&str`
- --> $DIR/inefficient_to_string.rs:11:21
+ --> $DIR/inefficient_to_string.rs:10:21
|
LL | let _: String = rrstr.to_string();
| ^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrstr).to_string()`
|
= help: `&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString`
note: the lint level is defined here
- --> $DIR/inefficient_to_string.rs:2:9
+ --> $DIR/inefficient_to_string.rs:1:9
|
LL | #![deny(clippy::inefficient_to_string)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `to_string` on `&&&str`
- --> $DIR/inefficient_to_string.rs:12:21
+ --> $DIR/inefficient_to_string.rs:11:21
|
LL | let _: String = rrrstr.to_string();
| ^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrstr).to_string()`
@@ -20,7 +20,7 @@ LL | let _: String = rrrstr.to_string();
= help: `&&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString`
error: calling `to_string` on `&&std::string::String`
- --> $DIR/inefficient_to_string.rs:20:21
+ --> $DIR/inefficient_to_string.rs:19:21
|
LL | let _: String = rrstring.to_string();
| ^^^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrstring).to_string()`
@@ -28,7 +28,7 @@ LL | let _: String = rrstring.to_string();
= help: `&std::string::String` implements `ToString` through a slower blanket impl, but `std::string::String` has a fast specialization of `ToString`
error: calling `to_string` on `&&&std::string::String`
- --> $DIR/inefficient_to_string.rs:21:21
+ --> $DIR/inefficient_to_string.rs:20:21
|
LL | let _: String = rrrstring.to_string();
| ^^^^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrstring).to_string()`
@@ -36,7 +36,7 @@ LL | let _: String = rrrstring.to_string();
= help: `&&std::string::String` implements `ToString` through a slower blanket impl, but `std::string::String` has a fast specialization of `ToString`
error: calling `to_string` on `&&std::borrow::Cow<'_, str>`
- --> $DIR/inefficient_to_string.rs:29:21
+ --> $DIR/inefficient_to_string.rs:28:21
|
LL | let _: String = rrcow.to_string();
| ^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrcow).to_string()`
@@ -44,7 +44,7 @@ LL | let _: String = rrcow.to_string();
= help: `&std::borrow::Cow<'_, str>` implements `ToString` through a slower blanket impl, but `std::borrow::Cow<'_, str>` has a fast specialization of `ToString`
error: calling `to_string` on `&&&std::borrow::Cow<'_, str>`
- --> $DIR/inefficient_to_string.rs:30:21
+ --> $DIR/inefficient_to_string.rs:29:21
|
LL | let _: String = rrrcow.to_string();
| ^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrcow).to_string()`
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
index e396ae94a..60304177b 100644
--- a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
+++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(exhaustive_patterns, never_type)]
#![allow(dead_code, unreachable_code, unused_variables)]
#![allow(clippy::let_and_return)]
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
index 3fce7bbb6..b77aac4a1 100644
--- a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
+++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(exhaustive_patterns, never_type)]
#![allow(dead_code, unreachable_code, unused_variables)]
#![allow(clippy::let_and_return)]
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.stderr b/src/tools/clippy/tests/ui/infallible_destructuring_match.stderr
index 004260a1d..93851aae8 100644
--- a/src/tools/clippy/tests/ui/infallible_destructuring_match.stderr
+++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.stderr
@@ -1,5 +1,5 @@
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
- --> $DIR/infallible_destructuring_match.rs:29:5
+ --> $DIR/infallible_destructuring_match.rs:28:5
|
LL | / let data = match wrapper {
LL | | SingleVariantEnum::Variant(i) => i,
@@ -7,9 +7,10 @@ LL | | };
| |______^ help: try: `let SingleVariantEnum::Variant(data) = wrapper;`
|
= note: `-D clippy::infallible-destructuring-match` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::infallible_destructuring_match)]`
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
- --> $DIR/infallible_destructuring_match.rs:61:5
+ --> $DIR/infallible_destructuring_match.rs:60:5
|
LL | / let data = match wrapper {
LL | | TupleStruct(i) => i,
@@ -17,7 +18,7 @@ LL | | };
| |______^ help: try: `let TupleStruct(data) = wrapper;`
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
- --> $DIR/infallible_destructuring_match.rs:85:5
+ --> $DIR/infallible_destructuring_match.rs:84:5
|
LL | / let data = match wrapper {
LL | | TupleStructWithNonCopy(ref n) => n,
@@ -25,7 +26,7 @@ LL | | };
| |______^ help: try: `let TupleStructWithNonCopy(ref data) = wrapper;`
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
- --> $DIR/infallible_destructuring_match.rs:104:5
+ --> $DIR/infallible_destructuring_match.rs:103:5
|
LL | / let data = match wrapper {
LL | | Ok(i) => i,
diff --git a/src/tools/clippy/tests/ui/infinite_iter.rs b/src/tools/clippy/tests/ui/infinite_iter.rs
index 622644f67..da95ba04b 100644
--- a/src/tools/clippy/tests/ui/infinite_iter.rs
+++ b/src/tools/clippy/tests/ui/infinite_iter.rs
@@ -8,42 +8,73 @@ fn square_is_lower_64(x: &u32) -> bool {
#[allow(clippy::maybe_infinite_iter)]
#[deny(clippy::infinite_iter)]
fn infinite_iters() {
- repeat(0_u8).collect::<Vec<_>>(); // infinite iter
- (0..8_u32).take_while(square_is_lower_64).cycle().count(); // infinite iter
- (0..8_u64).chain(0..).max(); // infinite iter
+ repeat(0_u8).collect::<Vec<_>>();
+ //~^ ERROR: infinite iteration detected
+ // infinite iter
+ (0..8_u32).take_while(square_is_lower_64).cycle().count();
+ //~^ ERROR: infinite iteration detected
+ // infinite iter
+ (0..8_u64).chain(0..).max();
+ //~^ ERROR: infinite iteration detected
+ // infinite iter
(0_usize..)
.chain([0usize, 1, 2].iter().cloned())
.skip_while(|x| *x != 42)
- .min(); // infinite iter
+ .min();
+ // infinite iter
(0..8_u32)
+ //~^ ERROR: infinite iteration detected
.rev()
.cycle()
.map(|x| x + 1_u32)
- .for_each(|x| println!("{}", x)); // infinite iter
- (0..3_u32).flat_map(|x| x..).sum::<u32>(); // infinite iter
- (0_usize..).flat_map(|x| 0..x).product::<usize>(); // infinite iter
- (0_u64..).filter(|x| x % 2 == 0).last(); // infinite iter
- (0..42_u64).by_ref().last(); // not an infinite, because ranges are double-ended
- (0..).next(); // iterator is not exhausted
+ .for_each(|x| println!("{}", x));
+ // infinite iter
+ (0..3_u32).flat_map(|x| x..).sum::<u32>();
+ // infinite iter
+ (0_usize..).flat_map(|x| 0..x).product::<usize>();
+ //~^ ERROR: infinite iteration detected
+ // infinite iter
+ (0_u64..).filter(|x| x % 2 == 0).last();
+ //~^ ERROR: infinite iteration detected
+ // not an infinite, because ranges are double-ended
+ (0..42_u64).by_ref().last();
+ // iterator is not exhausted
+ (0..).next();
}
#[deny(clippy::maybe_infinite_iter)]
fn potential_infinite_iters() {
- (0..).zip((0..).take_while(square_is_lower_64)).count(); // maybe infinite iter
- repeat(42).take_while(|x| *x == 42).chain(0..42).max(); // maybe infinite iter
+ // maybe infinite iter
+ (0..).zip((0..).take_while(square_is_lower_64)).count();
+ //~^ ERROR: possible infinite iteration detected
+ // maybe infinite iter
+ repeat(42).take_while(|x| *x == 42).chain(0..42).max();
+ //~^ ERROR: possible infinite iteration detected
+ // maybe infinite iter
(1..)
+ //~^ ERROR: possible infinite iteration detected
.scan(0, |state, x| {
*state += x;
Some(*state)
})
- .min(); // maybe infinite iter
- (0..).find(|x| *x == 24); // maybe infinite iter
- (0..).position(|x| x == 24); // maybe infinite iter
- (0..).any(|x| x == 24); // maybe infinite iter
- (0..).all(|x| x == 24); // maybe infinite iter
+ .min();
+ // maybe infinite iter
+ (0..).find(|x| *x == 24);
+ //~^ ERROR: possible infinite iteration detected
+ // maybe infinite iter
+ (0..).position(|x| x == 24);
+ //~^ ERROR: possible infinite iteration detected
+ // maybe infinite iter
+ (0..).any(|x| x == 24);
+ //~^ ERROR: possible infinite iteration detected
+ // maybe infinite iter
+ (0..).all(|x| x == 24);
+ //~^ ERROR: possible infinite iteration detected
- (0..).zip(0..42).take_while(|&(x, _)| x != 42).count(); // not infinite
- repeat(42).take_while(|x| *x == 42).next(); // iterator is not exhausted
+ // not infinite
+ (0..).zip(0..42).take_while(|&(x, _)| x != 42).count();
+ // iterator is not exhausted
+ repeat(42).take_while(|x| *x == 42).next();
}
fn main() {
@@ -62,7 +93,10 @@ mod finite_collect {
}
fn check_collect() {
- let _: HashSet<i32> = (0..).collect(); // Infinite iter
+ // Infinite iter
+ let _: HashSet<i32> = (0..).collect();
+ //~^ ERROR: infinite iteration detected
+ //~| NOTE: `#[deny(clippy::infinite_iter)]` on by default
// Some data structures don't collect infinitely, such as `ArrayVec`
let _: C = (0..).collect();
diff --git a/src/tools/clippy/tests/ui/infinite_iter.stderr b/src/tools/clippy/tests/ui/infinite_iter.stderr
index b911163f7..d0d0f0db4 100644
--- a/src/tools/clippy/tests/ui/infinite_iter.stderr
+++ b/src/tools/clippy/tests/ui/infinite_iter.stderr
@@ -1,7 +1,7 @@
error: infinite iteration detected
--> $DIR/infinite_iter.rs:11:5
|
-LL | repeat(0_u8).collect::<Vec<_>>(); // infinite iter
+LL | repeat(0_u8).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
@@ -11,96 +11,98 @@ LL | #[deny(clippy::infinite_iter)]
| ^^^^^^^^^^^^^^^^^^^^^
error: infinite iteration detected
- --> $DIR/infinite_iter.rs:12:5
+ --> $DIR/infinite_iter.rs:14:5
|
-LL | (0..8_u32).take_while(square_is_lower_64).cycle().count(); // infinite iter
+LL | (0..8_u32).take_while(square_is_lower_64).cycle().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: infinite iteration detected
- --> $DIR/infinite_iter.rs:13:5
+ --> $DIR/infinite_iter.rs:17:5
|
-LL | (0..8_u64).chain(0..).max(); // infinite iter
+LL | (0..8_u64).chain(0..).max();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: infinite iteration detected
- --> $DIR/infinite_iter.rs:18:5
+ --> $DIR/infinite_iter.rs:25:5
|
LL | / (0..8_u32)
+LL | |
LL | | .rev()
LL | | .cycle()
LL | | .map(|x| x + 1_u32)
-LL | | .for_each(|x| println!("{}", x)); // infinite iter
+LL | | .for_each(|x| println!("{}", x));
| |________________________________________^
error: infinite iteration detected
- --> $DIR/infinite_iter.rs:24:5
+ --> $DIR/infinite_iter.rs:34:5
|
-LL | (0_usize..).flat_map(|x| 0..x).product::<usize>(); // infinite iter
+LL | (0_usize..).flat_map(|x| 0..x).product::<usize>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: infinite iteration detected
- --> $DIR/infinite_iter.rs:25:5
+ --> $DIR/infinite_iter.rs:37:5
|
-LL | (0_u64..).filter(|x| x % 2 == 0).last(); // infinite iter
+LL | (0_u64..).filter(|x| x % 2 == 0).last();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: possible infinite iteration detected
- --> $DIR/infinite_iter.rs:32:5
+ --> $DIR/infinite_iter.rs:48:5
|
-LL | (0..).zip((0..).take_while(square_is_lower_64)).count(); // maybe infinite iter
+LL | (0..).zip((0..).take_while(square_is_lower_64)).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/infinite_iter.rs:30:8
+ --> $DIR/infinite_iter.rs:45:8
|
LL | #[deny(clippy::maybe_infinite_iter)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: possible infinite iteration detected
- --> $DIR/infinite_iter.rs:33:5
+ --> $DIR/infinite_iter.rs:51:5
|
-LL | repeat(42).take_while(|x| *x == 42).chain(0..42).max(); // maybe infinite iter
+LL | repeat(42).take_while(|x| *x == 42).chain(0..42).max();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: possible infinite iteration detected
- --> $DIR/infinite_iter.rs:34:5
+ --> $DIR/infinite_iter.rs:54:5
|
LL | / (1..)
+LL | |
LL | | .scan(0, |state, x| {
LL | | *state += x;
LL | | Some(*state)
LL | | })
-LL | | .min(); // maybe infinite iter
+LL | | .min();
| |______________^
error: possible infinite iteration detected
- --> $DIR/infinite_iter.rs:40:5
+ --> $DIR/infinite_iter.rs:62:5
|
-LL | (0..).find(|x| *x == 24); // maybe infinite iter
+LL | (0..).find(|x| *x == 24);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: possible infinite iteration detected
- --> $DIR/infinite_iter.rs:41:5
+ --> $DIR/infinite_iter.rs:65:5
|
-LL | (0..).position(|x| x == 24); // maybe infinite iter
+LL | (0..).position(|x| x == 24);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: possible infinite iteration detected
- --> $DIR/infinite_iter.rs:42:5
+ --> $DIR/infinite_iter.rs:68:5
|
-LL | (0..).any(|x| x == 24); // maybe infinite iter
+LL | (0..).any(|x| x == 24);
| ^^^^^^^^^^^^^^^^^^^^^^
error: possible infinite iteration detected
- --> $DIR/infinite_iter.rs:43:5
+ --> $DIR/infinite_iter.rs:71:5
|
-LL | (0..).all(|x| x == 24); // maybe infinite iter
+LL | (0..).all(|x| x == 24);
| ^^^^^^^^^^^^^^^^^^^^^^
error: infinite iteration detected
- --> $DIR/infinite_iter.rs:65:31
+ --> $DIR/infinite_iter.rs:97:31
|
-LL | let _: HashSet<i32> = (0..).collect(); // Infinite iter
+LL | let _: HashSet<i32> = (0..).collect();
| ^^^^^^^^^^^^^^^
|
= note: `#[deny(clippy::infinite_iter)]` on by default
diff --git a/src/tools/clippy/tests/ui/infinite_loop.rs b/src/tools/clippy/tests/ui/infinite_loop.rs
index 38e64b9ac..765c67011 100644
--- a/src/tools/clippy/tests/ui/infinite_loop.rs
+++ b/src/tools/clippy/tests/ui/infinite_loop.rs
@@ -1,3 +1,5 @@
+//@no-rustfix
+
fn fn_val(i: i32) -> i32 {
unimplemented!()
}
@@ -18,11 +20,15 @@ fn immutable_condition() {
// Should warn when all vars mentioned are immutable
let y = 0;
while y < 10 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
println!("KO - y is immutable");
}
let x = 0;
while y < 10 && x < 3 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
let mut k = 1;
k += 2;
println!("KO - x and y immutable");
@@ -30,6 +36,8 @@ fn immutable_condition() {
let cond = false;
while !cond {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
println!("KO - cond immutable");
}
@@ -74,15 +82,21 @@ fn unused_var() {
let (mut i, mut j) = (0, 0);
while i < 3 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
j = 3;
println!("KO - i not mentioned");
}
while i < 3 && j > 0 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
println!("KO - i and j not mentioned");
}
while i < 3 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
let mut i = 5;
fn_mutref(&mut i);
println!("KO - shadowed");
@@ -98,11 +112,15 @@ fn used_immutable() {
let mut i = 0;
while i < 3 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
fn_constref(&i);
println!("KO - const reference");
}
while i < 3 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
fn_val(i);
println!("KO - passed by value");
}
@@ -169,6 +187,8 @@ impl Counter {
fn print_n(&self, n: usize) {
while self.count < n {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
println!("KO - {} is not mutated", self.count);
}
}
@@ -177,6 +197,8 @@ impl Counter {
fn while_loop_with_break_and_return() {
let y = 0;
while y < 10 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
if y == 0 {
break;
}
@@ -184,6 +206,8 @@ fn while_loop_with_break_and_return() {
}
while y < 10 {
+ //~^ ERROR: variables in the condition are not mutated in the loop body
+ //~| NOTE: this may lead to an infinite or to a never running loop
if y == 0 {
return;
}
diff --git a/src/tools/clippy/tests/ui/infinite_loop.stderr b/src/tools/clippy/tests/ui/infinite_loop.stderr
index 85258b9d6..a78e47d02 100644
--- a/src/tools/clippy/tests/ui/infinite_loop.stderr
+++ b/src/tools/clippy/tests/ui/infinite_loop.stderr
@@ -1,5 +1,5 @@
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:20:11
+ --> $DIR/infinite_loop.rs:22:11
|
LL | while y < 10 {
| ^^^^^^
@@ -8,7 +8,7 @@ LL | while y < 10 {
= note: `#[deny(clippy::while_immutable_condition)]` on by default
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:25:11
+ --> $DIR/infinite_loop.rs:29:11
|
LL | while y < 10 && x < 3 {
| ^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL | while y < 10 && x < 3 {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:32:11
+ --> $DIR/infinite_loop.rs:38:11
|
LL | while !cond {
| ^^^^^
@@ -24,7 +24,7 @@ LL | while !cond {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:76:11
+ --> $DIR/infinite_loop.rs:84:11
|
LL | while i < 3 {
| ^^^^^
@@ -32,7 +32,7 @@ LL | while i < 3 {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:81:11
+ --> $DIR/infinite_loop.rs:91:11
|
LL | while i < 3 && j > 0 {
| ^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL | while i < 3 && j > 0 {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:85:11
+ --> $DIR/infinite_loop.rs:97:11
|
LL | while i < 3 {
| ^^^^^
@@ -48,7 +48,7 @@ LL | while i < 3 {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:100:11
+ --> $DIR/infinite_loop.rs:114:11
|
LL | while i < 3 {
| ^^^^^
@@ -56,7 +56,7 @@ LL | while i < 3 {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:105:11
+ --> $DIR/infinite_loop.rs:121:11
|
LL | while i < 3 {
| ^^^^^
@@ -64,7 +64,7 @@ LL | while i < 3 {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:171:15
+ --> $DIR/infinite_loop.rs:189:15
|
LL | while self.count < n {
| ^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL | while self.count < n {
= note: this may lead to an infinite or to a never running loop
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:179:11
+ --> $DIR/infinite_loop.rs:199:11
|
LL | while y < 10 {
| ^^^^^^
@@ -82,7 +82,7 @@ LL | while y < 10 {
= help: rewrite it as `if cond { loop { } }`
error: variables in the condition are not mutated in the loop body
- --> $DIR/infinite_loop.rs:186:11
+ --> $DIR/infinite_loop.rs:208:11
|
LL | while y < 10 {
| ^^^^^^
diff --git a/src/tools/clippy/tests/ui/inherent_to_string.rs b/src/tools/clippy/tests/ui/inherent_to_string.rs
index adb0389a0..7b938cdd7 100644
--- a/src/tools/clippy/tests/ui/inherent_to_string.rs
+++ b/src/tools/clippy/tests/ui/inherent_to_string.rs
@@ -20,6 +20,7 @@ struct J;
impl A {
// Should be detected; emit warning
fn to_string(&self) -> String {
+ //~^ ERROR: implementation of inherent method `to_string(&self) -> String` for type `A
"A.to_string()".to_string()
}
@@ -44,6 +45,7 @@ impl B {
impl C {
// Should be detected and emit error as C also implements Display
fn to_string(&self) -> String {
+ //~^ ERROR: type `C` implements inherent method `to_string(&self) -> String` which sha
"C.to_string()".to_string()
}
}
diff --git a/src/tools/clippy/tests/ui/inherent_to_string.stderr b/src/tools/clippy/tests/ui/inherent_to_string.stderr
index 579b3c8c5..cf8d09180 100644
--- a/src/tools/clippy/tests/ui/inherent_to_string.stderr
+++ b/src/tools/clippy/tests/ui/inherent_to_string.stderr
@@ -2,17 +2,20 @@ error: implementation of inherent method `to_string(&self) -> String` for type `
--> $DIR/inherent_to_string.rs:22:5
|
LL | / fn to_string(&self) -> String {
+LL | |
LL | | "A.to_string()".to_string()
LL | | }
| |_____^
|
= help: implement trait `Display` for type `A` instead
= note: `-D clippy::inherent-to-string` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inherent_to_string)]`
error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`
- --> $DIR/inherent_to_string.rs:46:5
+ --> $DIR/inherent_to_string.rs:47:5
|
LL | / fn to_string(&self) -> String {
+LL | |
LL | | "C.to_string()".to_string()
LL | | }
| |_____^
diff --git a/src/tools/clippy/tests/ui/inline_fn_without_body.fixed b/src/tools/clippy/tests/ui/inline_fn_without_body.fixed
index 9c5819558..acd808ed4 100644
--- a/src/tools/clippy/tests/ui/inline_fn_without_body.fixed
+++ b/src/tools/clippy/tests/ui/inline_fn_without_body.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::inline_fn_without_body)]
#![allow(clippy::inline_always)]
diff --git a/src/tools/clippy/tests/ui/inline_fn_without_body.rs b/src/tools/clippy/tests/ui/inline_fn_without_body.rs
index 43ffaf812..af81feaa3 100644
--- a/src/tools/clippy/tests/ui/inline_fn_without_body.rs
+++ b/src/tools/clippy/tests/ui/inline_fn_without_body.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::inline_fn_without_body)]
#![allow(clippy::inline_always)]
diff --git a/src/tools/clippy/tests/ui/inline_fn_without_body.stderr b/src/tools/clippy/tests/ui/inline_fn_without_body.stderr
index 32d35e209..60f6eb8df 100644
--- a/src/tools/clippy/tests/ui/inline_fn_without_body.stderr
+++ b/src/tools/clippy/tests/ui/inline_fn_without_body.stderr
@@ -1,5 +1,5 @@
error: use of `#[inline]` on trait method `default_inline` which has no body
- --> $DIR/inline_fn_without_body.rs:7:5
+ --> $DIR/inline_fn_without_body.rs:5:5
|
LL | #[inline]
| _____-^^^^^^^^
@@ -7,9 +7,10 @@ LL | | fn default_inline();
| |____- help: remove
|
= note: `-D clippy::inline-fn-without-body` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inline_fn_without_body)]`
error: use of `#[inline]` on trait method `always_inline` which has no body
- --> $DIR/inline_fn_without_body.rs:10:5
+ --> $DIR/inline_fn_without_body.rs:8:5
|
LL | #[inline(always)]
| _____-^^^^^^^^^^^^^^^^
@@ -17,7 +18,7 @@ LL | | fn always_inline();
| |____- help: remove
error: use of `#[inline]` on trait method `never_inline` which has no body
- --> $DIR/inline_fn_without_body.rs:13:5
+ --> $DIR/inline_fn_without_body.rs:11:5
|
LL | #[inline(never)]
| _____-^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/inspect_for_each.rs b/src/tools/clippy/tests/ui/inspect_for_each.rs
index 7fe45c83b..974690eaa 100644
--- a/src/tools/clippy/tests/ui/inspect_for_each.rs
+++ b/src/tools/clippy/tests/ui/inspect_for_each.rs
@@ -5,6 +5,7 @@ fn main() {
let mut b: Vec<usize> = Vec::new();
a.into_iter().inspect(|x| assert!(*x > 0)).for_each(|x| {
+ //~^ ERROR: called `inspect(..).for_each(..)` on an `Iterator`
let y = do_some(x);
let z = do_more(y);
b.push(z);
diff --git a/src/tools/clippy/tests/ui/inspect_for_each.stderr b/src/tools/clippy/tests/ui/inspect_for_each.stderr
index 67c2d5e53..80df86ad6 100644
--- a/src/tools/clippy/tests/ui/inspect_for_each.stderr
+++ b/src/tools/clippy/tests/ui/inspect_for_each.stderr
@@ -3,6 +3,7 @@ error: called `inspect(..).for_each(..)` on an `Iterator`
|
LL | a.into_iter().inspect(|x| assert!(*x > 0)).for_each(|x| {
| ___________________^
+LL | |
LL | | let y = do_some(x);
LL | | let z = do_more(y);
LL | | b.push(z);
@@ -11,6 +12,7 @@ LL | | });
|
= help: move the code from `inspect(..)` to `for_each(..)` and remove the `inspect(..)`
= note: `-D clippy::inspect-for-each` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inspect_for_each)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/int_plus_one.fixed b/src/tools/clippy/tests/ui/int_plus_one.fixed
index 5a36ec462..77d9cd3f7 100644
--- a/src/tools/clippy/tests/ui/int_plus_one.fixed
+++ b/src/tools/clippy/tests/ui/int_plus_one.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[allow(clippy::no_effect, clippy::unnecessary_operation)]
#[warn(clippy::int_plus_one)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/int_plus_one.rs b/src/tools/clippy/tests/ui/int_plus_one.rs
index bffa4afd6..57c87819d 100644
--- a/src/tools/clippy/tests/ui/int_plus_one.rs
+++ b/src/tools/clippy/tests/ui/int_plus_one.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[allow(clippy::no_effect, clippy::unnecessary_operation)]
#[warn(clippy::int_plus_one)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/int_plus_one.stderr b/src/tools/clippy/tests/ui/int_plus_one.stderr
index c5b020ba8..6a62eac7c 100644
--- a/src/tools/clippy/tests/ui/int_plus_one.stderr
+++ b/src/tools/clippy/tests/ui/int_plus_one.stderr
@@ -1,25 +1,26 @@
error: unnecessary `>= y + 1` or `x - 1 >=`
- --> $DIR/int_plus_one.rs:9:13
+ --> $DIR/int_plus_one.rs:7:13
|
LL | let _ = x >= y + 1;
| ^^^^^^^^^^ help: change it to: `x > y`
|
= note: `-D clippy::int-plus-one` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::int_plus_one)]`
error: unnecessary `>= y + 1` or `x - 1 >=`
- --> $DIR/int_plus_one.rs:10:13
+ --> $DIR/int_plus_one.rs:8:13
|
LL | let _ = y + 1 <= x;
| ^^^^^^^^^^ help: change it to: `y < x`
error: unnecessary `>= y + 1` or `x - 1 >=`
- --> $DIR/int_plus_one.rs:12:13
+ --> $DIR/int_plus_one.rs:10:13
|
LL | let _ = x - 1 >= y;
| ^^^^^^^^^^ help: change it to: `x > y`
error: unnecessary `>= y + 1` or `x - 1 >=`
- --> $DIR/int_plus_one.rs:13:13
+ --> $DIR/int_plus_one.rs:11:13
|
LL | let _ = y <= x - 1;
| ^^^^^^^^^^ help: change it to: `y < x`
diff --git a/src/tools/clippy/tests/ui/integer_division.rs b/src/tools/clippy/tests/ui/integer_division.rs
index 800c75257..137548fec 100644
--- a/src/tools/clippy/tests/ui/integer_division.rs
+++ b/src/tools/clippy/tests/ui/integer_division.rs
@@ -3,7 +3,10 @@
fn main() {
let two = 2;
let n = 1 / 2;
+ //~^ ERROR: integer division
let o = 1 / two;
+ //~^ ERROR: integer division
let p = two / 4;
+ //~^ ERROR: integer division
let x = 1. / 2.0;
}
diff --git a/src/tools/clippy/tests/ui/integer_division.stderr b/src/tools/clippy/tests/ui/integer_division.stderr
index ca8001279..420f0f30e 100644
--- a/src/tools/clippy/tests/ui/integer_division.stderr
+++ b/src/tools/clippy/tests/ui/integer_division.stderr
@@ -6,9 +6,10 @@ LL | let n = 1 / 2;
|
= help: division of integers may cause loss of precision. consider using floats
= note: `-D clippy::integer-division` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::integer_division)]`
error: integer division
- --> $DIR/integer_division.rs:6:13
+ --> $DIR/integer_division.rs:7:13
|
LL | let o = 1 / two;
| ^^^^^^^
@@ -16,7 +17,7 @@ LL | let o = 1 / two;
= help: division of integers may cause loss of precision. consider using floats
error: integer division
- --> $DIR/integer_division.rs:7:13
+ --> $DIR/integer_division.rs:9:13
|
LL | let p = two / 4;
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/into_iter_on_ref.fixed b/src/tools/clippy/tests/ui/into_iter_on_ref.fixed
index af197e33f..c03d91c79 100644
--- a/src/tools/clippy/tests/ui/into_iter_on_ref.fixed
+++ b/src/tools/clippy/tests/ui/into_iter_on_ref.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::useless_vec, clippy::needless_borrow)]
#![warn(clippy::into_iter_on_ref)]
diff --git a/src/tools/clippy/tests/ui/into_iter_on_ref.rs b/src/tools/clippy/tests/ui/into_iter_on_ref.rs
index 3ac13d7dd..93c732fd6 100644
--- a/src/tools/clippy/tests/ui/into_iter_on_ref.rs
+++ b/src/tools/clippy/tests/ui/into_iter_on_ref.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::useless_vec, clippy::needless_borrow)]
#![warn(clippy::into_iter_on_ref)]
diff --git a/src/tools/clippy/tests/ui/into_iter_on_ref.stderr b/src/tools/clippy/tests/ui/into_iter_on_ref.stderr
index 06014a93f..481957d50 100644
--- a/src/tools/clippy/tests/ui/into_iter_on_ref.stderr
+++ b/src/tools/clippy/tests/ui/into_iter_on_ref.stderr
@@ -1,163 +1,164 @@
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec`
- --> $DIR/into_iter_on_ref.rs:14:30
+ --> $DIR/into_iter_on_ref.rs:13:30
|
LL | let _ = (&vec![1, 2, 3]).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
|
= note: `-D clippy::into-iter-on-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::into_iter_on_ref)]`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`
- --> $DIR/into_iter_on_ref.rs:15:46
+ --> $DIR/into_iter_on_ref.rs:14:46
|
LL | let _ = vec![1, 2, 3].into_boxed_slice().into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`
- --> $DIR/into_iter_on_ref.rs:16:41
+ --> $DIR/into_iter_on_ref.rs:15:41
|
LL | let _ = std::rc::Rc::from(&[X][..]).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`
- --> $DIR/into_iter_on_ref.rs:17:44
+ --> $DIR/into_iter_on_ref.rs:16:44
|
LL | let _ = std::sync::Arc::from(&[X][..]).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`
- --> $DIR/into_iter_on_ref.rs:19:32
+ --> $DIR/into_iter_on_ref.rs:18:32
|
LL | let _ = (&&&&&&&[1, 2, 3]).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`
- --> $DIR/into_iter_on_ref.rs:20:36
+ --> $DIR/into_iter_on_ref.rs:19:36
|
LL | let _ = (&&&&mut &&&[1, 2, 3]).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `array`
- --> $DIR/into_iter_on_ref.rs:21:40
+ --> $DIR/into_iter_on_ref.rs:20:40
|
LL | let _ = (&mut &mut &mut [1, 2, 3]).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Option`
- --> $DIR/into_iter_on_ref.rs:23:24
+ --> $DIR/into_iter_on_ref.rs:22:24
|
LL | let _ = (&Some(4)).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Option`
- --> $DIR/into_iter_on_ref.rs:24:28
+ --> $DIR/into_iter_on_ref.rs:23:28
|
LL | let _ = (&mut Some(5)).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Result`
- --> $DIR/into_iter_on_ref.rs:25:32
+ --> $DIR/into_iter_on_ref.rs:24:32
|
LL | let _ = (&Ok::<_, i32>(6)).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Result`
- --> $DIR/into_iter_on_ref.rs:26:37
+ --> $DIR/into_iter_on_ref.rs:25:37
|
LL | let _ = (&mut Err::<i32, _>(7)).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec`
- --> $DIR/into_iter_on_ref.rs:27:34
+ --> $DIR/into_iter_on_ref.rs:26:34
|
LL | let _ = (&Vec::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Vec`
- --> $DIR/into_iter_on_ref.rs:28:38
+ --> $DIR/into_iter_on_ref.rs:27:38
|
LL | let _ = (&mut Vec::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeMap`
- --> $DIR/into_iter_on_ref.rs:29:44
+ --> $DIR/into_iter_on_ref.rs:28:44
|
LL | let _ = (&BTreeMap::<i32, u64>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `BTreeMap`
- --> $DIR/into_iter_on_ref.rs:30:48
+ --> $DIR/into_iter_on_ref.rs:29:48
|
LL | let _ = (&mut BTreeMap::<i32, u64>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `VecDeque`
- --> $DIR/into_iter_on_ref.rs:31:39
+ --> $DIR/into_iter_on_ref.rs:30:39
|
LL | let _ = (&VecDeque::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `VecDeque`
- --> $DIR/into_iter_on_ref.rs:32:43
+ --> $DIR/into_iter_on_ref.rs:31:43
|
LL | let _ = (&mut VecDeque::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `LinkedList`
- --> $DIR/into_iter_on_ref.rs:33:41
+ --> $DIR/into_iter_on_ref.rs:32:41
|
LL | let _ = (&LinkedList::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `LinkedList`
- --> $DIR/into_iter_on_ref.rs:34:45
+ --> $DIR/into_iter_on_ref.rs:33:45
|
LL | let _ = (&mut LinkedList::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashMap`
- --> $DIR/into_iter_on_ref.rs:35:43
+ --> $DIR/into_iter_on_ref.rs:34:43
|
LL | let _ = (&HashMap::<i32, u64>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap`
- --> $DIR/into_iter_on_ref.rs:36:47
+ --> $DIR/into_iter_on_ref.rs:35:47
|
LL | let _ = (&mut HashMap::<i32, u64>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter_mut`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet`
- --> $DIR/into_iter_on_ref.rs:38:39
+ --> $DIR/into_iter_on_ref.rs:37:39
|
LL | let _ = (&BTreeSet::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap`
- --> $DIR/into_iter_on_ref.rs:39:41
+ --> $DIR/into_iter_on_ref.rs:38:41
|
LL | let _ = (&BinaryHeap::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashSet`
- --> $DIR/into_iter_on_ref.rs:40:38
+ --> $DIR/into_iter_on_ref.rs:39:38
|
LL | let _ = (&HashSet::<i32>::new()).into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Path`
- --> $DIR/into_iter_on_ref.rs:41:43
+ --> $DIR/into_iter_on_ref.rs:40:43
|
LL | let _ = std::path::Path::new("12/34").into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `PathBuf`
- --> $DIR/into_iter_on_ref.rs:42:47
+ --> $DIR/into_iter_on_ref.rs:41:47
|
LL | let _ = std::path::PathBuf::from("12/34").into_iter();
| ^^^^^^^^^ help: call directly: `iter`
error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`
- --> $DIR/into_iter_on_ref.rs:44:26
+ --> $DIR/into_iter_on_ref.rs:43:26
|
LL | let _ = (&[1, 2, 3]).into_iter().next();
| ^^^^^^^^^ help: call directly: `iter`
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
index 9264fb7e9..eeddc2349 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
fn main() {
unsafe {
let _slice: &[usize] = std::slice::from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
index 80c942d77..8569b7740 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
fn main() {
unsafe {
let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), 0);
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
index 532c36abe..22efa0d84 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
@@ -1,5 +1,5 @@
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:5:59
+ --> $DIR/invalid_null_ptr_usage.rs:3:59
|
LL | let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(), 0);
| ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
@@ -7,145 +7,145 @@ LL | let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null(),
= note: `#[deny(clippy::invalid_null_ptr_usage)]` on by default
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:6:59
+ --> $DIR/invalid_null_ptr_usage.rs:4:59
|
LL | let _slice: &[usize] = std::slice::from_raw_parts(std::ptr::null_mut(), 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:8:63
+ --> $DIR/invalid_null_ptr_usage.rs:6:63
|
LL | let _slice: &[usize] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:10:33
+ --> $DIR/invalid_null_ptr_usage.rs:8:33
|
LL | std::ptr::copy::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
| ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:11:73
+ --> $DIR/invalid_null_ptr_usage.rs:9:73
|
LL | std::ptr::copy::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:13:48
+ --> $DIR/invalid_null_ptr_usage.rs:11:48
|
LL | std::ptr::copy_nonoverlapping::<usize>(std::ptr::null(), std::ptr::NonNull::dangling().as_ptr(), 0);
| ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:14:88
+ --> $DIR/invalid_null_ptr_usage.rs:12:88
|
LL | std::ptr::copy_nonoverlapping::<usize>(std::ptr::NonNull::dangling().as_ptr(), std::ptr::null_mut(), 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:19:36
+ --> $DIR/invalid_null_ptr_usage.rs:17:36
|
LL | let _a: A = std::ptr::read(std::ptr::null());
| ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:20:36
+ --> $DIR/invalid_null_ptr_usage.rs:18:36
|
LL | let _a: A = std::ptr::read(std::ptr::null_mut());
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:22:46
+ --> $DIR/invalid_null_ptr_usage.rs:20:46
|
LL | let _a: A = std::ptr::read_unaligned(std::ptr::null());
| ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:23:46
+ --> $DIR/invalid_null_ptr_usage.rs:21:46
|
LL | let _a: A = std::ptr::read_unaligned(std::ptr::null_mut());
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:25:45
+ --> $DIR/invalid_null_ptr_usage.rs:23:45
|
LL | let _a: A = std::ptr::read_volatile(std::ptr::null());
| ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:26:45
+ --> $DIR/invalid_null_ptr_usage.rs:24:45
|
LL | let _a: A = std::ptr::read_volatile(std::ptr::null_mut());
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:28:39
+ --> $DIR/invalid_null_ptr_usage.rs:26:39
|
LL | let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:30:69
+ --> $DIR/invalid_null_ptr_usage.rs:28:69
|
LL | let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null(), 0);
| ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:31:69
+ --> $DIR/invalid_null_ptr_usage.rs:29:69
|
LL | let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:33:73
+ --> $DIR/invalid_null_ptr_usage.rs:31:73
|
LL | let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:35:29
+ --> $DIR/invalid_null_ptr_usage.rs:33:29
|
LL | std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:36:37
+ --> $DIR/invalid_null_ptr_usage.rs:34:37
|
LL | std::ptr::swap::<A>(&mut A, std::ptr::null_mut());
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:38:44
+ --> $DIR/invalid_null_ptr_usage.rs:36:44
|
LL | std::ptr::swap_nonoverlapping::<A>(std::ptr::null_mut(), &mut A, 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:39:52
+ --> $DIR/invalid_null_ptr_usage.rs:37:52
|
LL | std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::null_mut(), 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:41:25
+ --> $DIR/invalid_null_ptr_usage.rs:39:25
|
LL | std::ptr::write(std::ptr::null_mut(), A);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:43:35
+ --> $DIR/invalid_null_ptr_usage.rs:41:35
|
LL | std::ptr::write_unaligned(std::ptr::null_mut(), A);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:45:34
+ --> $DIR/invalid_null_ptr_usage.rs:43:34
|
LL | std::ptr::write_volatile(std::ptr::null_mut(), A);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
error: pointer must be non-null
- --> $DIR/invalid_null_ptr_usage.rs:47:40
+ --> $DIR/invalid_null_ptr_usage.rs:45:40
|
LL | std::ptr::write_bytes::<usize>(std::ptr::null_mut(), 42, 0);
| ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
diff --git a/src/tools/clippy/tests/ui/invalid_upcast_comparisons.rs b/src/tools/clippy/tests/ui/invalid_upcast_comparisons.rs
index 697416dce..a9db15f20 100644
--- a/src/tools/clippy/tests/ui/invalid_upcast_comparisons.rs
+++ b/src/tools/clippy/tests/ui/invalid_upcast_comparisons.rs
@@ -19,36 +19,61 @@ fn main() {
// always false, since no u8 can be > 300
(u8 as u32) > 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
+ //~| NOTE: `-D clippy::invalid-upcast-comparisons` implied by `-D warnings`
(u8 as i32) > 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
(u8 as u32) == 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
(u8 as i32) == 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 < (u8 as u32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 < (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 == (u8 as u32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 == (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
// inverted of the above
(u8 as u32) <= 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
(u8 as i32) <= 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
(u8 as u32) != 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
(u8 as i32) != 300;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 >= (u8 as u32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 >= (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 != (u8 as u32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
300 != (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
// always false, since u8 -> i32 doesn't wrap
(u8 as i32) < 0;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
-5 != (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
// inverted of the above
(u8 as i32) >= 0;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
-5 == (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
// always false, since no u8 can be 1337
1337 == (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
1337 == (u8 as u32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
// inverted of the above
1337 != (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
1337 != (u8 as u32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
// Those are Ok:
(u8 as u32) > 20;
@@ -63,7 +88,9 @@ fn main() {
(u8 as i8) == -1;
(u8 as i8) != -1;
(u8 as i32) > -1;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
(u8 as i32) < -1;
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
(u32 as i32) < -5;
(u32 as i32) < 10;
@@ -80,6 +107,7 @@ fn main() {
-5 > (u32 as i32);
-5 >= (u8 as i32);
+ //~^ ERROR: because of the numeric bounds on `u8` prior to casting, this expression is
-5 == (u32 as i32);
}
diff --git a/src/tools/clippy/tests/ui/invalid_upcast_comparisons.stderr b/src/tools/clippy/tests/ui/invalid_upcast_comparisons.stderr
index 03c3fb80a..a57b4b02d 100644
--- a/src/tools/clippy/tests/ui/invalid_upcast_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/invalid_upcast_comparisons.stderr
@@ -5,159 +5,160 @@ LL | (u8 as u32) > 300;
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::invalid-upcast-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::invalid_upcast_comparisons)]`
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:22:5
+ --> $DIR/invalid_upcast_comparisons.rs:24:5
|
LL | (u8 as i32) > 300;
| ^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:23:5
+ --> $DIR/invalid_upcast_comparisons.rs:26:5
|
LL | (u8 as u32) == 300;
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:24:5
+ --> $DIR/invalid_upcast_comparisons.rs:28:5
|
LL | (u8 as i32) == 300;
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:25:5
+ --> $DIR/invalid_upcast_comparisons.rs:30:5
|
LL | 300 < (u8 as u32);
| ^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:26:5
+ --> $DIR/invalid_upcast_comparisons.rs:32:5
|
LL | 300 < (u8 as i32);
| ^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:27:5
+ --> $DIR/invalid_upcast_comparisons.rs:34:5
|
LL | 300 == (u8 as u32);
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:28:5
+ --> $DIR/invalid_upcast_comparisons.rs:36:5
|
LL | 300 == (u8 as i32);
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:30:5
+ --> $DIR/invalid_upcast_comparisons.rs:39:5
|
LL | (u8 as u32) <= 300;
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:31:5
+ --> $DIR/invalid_upcast_comparisons.rs:41:5
|
LL | (u8 as i32) <= 300;
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:32:5
+ --> $DIR/invalid_upcast_comparisons.rs:43:5
|
LL | (u8 as u32) != 300;
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:33:5
+ --> $DIR/invalid_upcast_comparisons.rs:45:5
|
LL | (u8 as i32) != 300;
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:34:5
+ --> $DIR/invalid_upcast_comparisons.rs:47:5
|
LL | 300 >= (u8 as u32);
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:35:5
+ --> $DIR/invalid_upcast_comparisons.rs:49:5
|
LL | 300 >= (u8 as i32);
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:36:5
+ --> $DIR/invalid_upcast_comparisons.rs:51:5
|
LL | 300 != (u8 as u32);
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:37:5
+ --> $DIR/invalid_upcast_comparisons.rs:53:5
|
LL | 300 != (u8 as i32);
| ^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:40:5
+ --> $DIR/invalid_upcast_comparisons.rs:57:5
|
LL | (u8 as i32) < 0;
| ^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:41:5
+ --> $DIR/invalid_upcast_comparisons.rs:59:5
|
LL | -5 != (u8 as i32);
| ^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:43:5
+ --> $DIR/invalid_upcast_comparisons.rs:62:5
|
LL | (u8 as i32) >= 0;
| ^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:44:5
+ --> $DIR/invalid_upcast_comparisons.rs:64:5
|
LL | -5 == (u8 as i32);
| ^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:47:5
+ --> $DIR/invalid_upcast_comparisons.rs:68:5
|
LL | 1337 == (u8 as i32);
| ^^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:48:5
+ --> $DIR/invalid_upcast_comparisons.rs:70:5
|
LL | 1337 == (u8 as u32);
| ^^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:50:5
+ --> $DIR/invalid_upcast_comparisons.rs:73:5
|
LL | 1337 != (u8 as i32);
| ^^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:51:5
+ --> $DIR/invalid_upcast_comparisons.rs:75:5
|
LL | 1337 != (u8 as u32);
| ^^^^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always true
- --> $DIR/invalid_upcast_comparisons.rs:65:5
+ --> $DIR/invalid_upcast_comparisons.rs:90:5
|
LL | (u8 as i32) > -1;
| ^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:66:5
+ --> $DIR/invalid_upcast_comparisons.rs:92:5
|
LL | (u8 as i32) < -1;
| ^^^^^^^^^^^^^^^^
error: because of the numeric bounds on `u8` prior to casting, this expression is always false
- --> $DIR/invalid_upcast_comparisons.rs:82:5
+ --> $DIR/invalid_upcast_comparisons.rs:109:5
|
LL | -5 >= (u8 as i32);
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed b/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed
index bc43303a6..62953ff74 100644
--- a/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed
+++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::is_digit_ascii_radix)]
const TEN: u32 = 10;
diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs b/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs
index 93cba5c8e..229f530f6 100644
--- a/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs
+++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::is_digit_ascii_radix)]
const TEN: u32 = 10;
diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr b/src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr
index dc5cb2913..28040c3a9 100644
--- a/src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr
+++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr
@@ -1,19 +1,20 @@
error: use of `char::is_digit` with literal radix of 10
- --> $DIR/is_digit_ascii_radix.rs:11:13
+ --> $DIR/is_digit_ascii_radix.rs:9:13
|
LL | let _ = c.is_digit(10);
| ^^^^^^^^^^^^^^ help: try: `c.is_ascii_digit()`
|
= note: `-D clippy::is-digit-ascii-radix` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::is_digit_ascii_radix)]`
error: use of `char::is_digit` with literal radix of 16
- --> $DIR/is_digit_ascii_radix.rs:12:13
+ --> $DIR/is_digit_ascii_radix.rs:10:13
|
LL | let _ = c.is_digit(16);
| ^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()`
error: use of `char::is_digit` with literal radix of 16
- --> $DIR/is_digit_ascii_radix.rs:13:13
+ --> $DIR/is_digit_ascii_radix.rs:11:13
|
LL | let _ = c.is_digit(0x10);
| ^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()`
diff --git a/src/tools/clippy/tests/ui/issue-7447.rs b/src/tools/clippy/tests/ui/issue-7447.rs
index de4362c4d..7e7ef209d 100644
--- a/src/tools/clippy/tests/ui/issue-7447.rs
+++ b/src/tools/clippy/tests/ui/issue-7447.rs
@@ -24,5 +24,8 @@ pub struct ByteView<'a> {
fn main() {
byte_view(panic!());
+ //~^ ERROR: sub-expression diverges
+ //~| NOTE: `-D clippy::diverging-sub-expression` implied by `-D warnings`
group_entries(panic!());
+ //~^ ERROR: sub-expression diverges
}
diff --git a/src/tools/clippy/tests/ui/issue-7447.stderr b/src/tools/clippy/tests/ui/issue-7447.stderr
index 7a113740c..51ecac455 100644
--- a/src/tools/clippy/tests/ui/issue-7447.stderr
+++ b/src/tools/clippy/tests/ui/issue-7447.stderr
@@ -5,10 +5,11 @@ LL | byte_view(panic!());
| ^^^^^^^^
|
= note: `-D clippy::diverging-sub-expression` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]`
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: sub-expression diverges
- --> $DIR/issue-7447.rs:27:19
+ --> $DIR/issue-7447.rs:29:19
|
LL | group_entries(panic!());
| ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/issue_2356.fixed b/src/tools/clippy/tests/ui/issue_2356.fixed
index a69f5ebdc..892aa4e34 100644
--- a/src/tools/clippy/tests/ui/issue_2356.fixed
+++ b/src/tools/clippy/tests/ui/issue_2356.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::while_let_on_iterator)]
#![allow(unused_mut)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/issue_2356.rs b/src/tools/clippy/tests/ui/issue_2356.rs
index 50e1bce1f..da0eead15 100644
--- a/src/tools/clippy/tests/ui/issue_2356.rs
+++ b/src/tools/clippy/tests/ui/issue_2356.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::while_let_on_iterator)]
#![allow(unused_mut)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/issue_2356.stderr b/src/tools/clippy/tests/ui/issue_2356.stderr
index a24b0b32e..d04b49e52 100644
--- a/src/tools/clippy/tests/ui/issue_2356.stderr
+++ b/src/tools/clippy/tests/ui/issue_2356.stderr
@@ -1,11 +1,11 @@
error: this loop could be written as a `for` loop
- --> $DIR/issue_2356.rs:18:9
+ --> $DIR/issue_2356.rs:17:9
|
LL | while let Some(e) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for e in it`
|
note: the lint level is defined here
- --> $DIR/issue_2356.rs:2:9
+ --> $DIR/issue_2356.rs:1:9
|
LL | #![deny(clippy::while_let_on_iterator)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/issue_4266.rs b/src/tools/clippy/tests/ui/issue_4266.rs
index 8e0620e52..23453207b 100644
--- a/src/tools/clippy/tests/ui/issue_4266.rs
+++ b/src/tools/clippy/tests/ui/issue_4266.rs
@@ -2,10 +2,13 @@
#![allow(clippy::uninlined_format_args)]
async fn sink1<'a>(_: &'a str) {} // lint
+//~^ ERROR: the following explicit lifetimes could be elided: 'a
+//~| NOTE: `-D clippy::needless-lifetimes` implied by `-D warnings`
async fn sink1_elided(_: &str) {} // ok
// lint
async fn one_to_one<'a>(s: &'a str) -> &'a str {
+ //~^ ERROR: the following explicit lifetimes could be elided: 'a
s
}
@@ -26,6 +29,7 @@ struct Foo;
impl Foo {
// ok
pub async fn new(&mut self) -> Self {
+ //~^ ERROR: methods called `new` usually take no `self`
Foo {}
}
}
diff --git a/src/tools/clippy/tests/ui/issue_4266.stderr b/src/tools/clippy/tests/ui/issue_4266.stderr
index 5b60646ef..692de2ae5 100644
--- a/src/tools/clippy/tests/ui/issue_4266.stderr
+++ b/src/tools/clippy/tests/ui/issue_4266.stderr
@@ -5,21 +5,23 @@ LL | async fn sink1<'a>(_: &'a str) {} // lint
| ^^ ^^
|
= note: `-D clippy::needless-lifetimes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]`
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/issue_4266.rs:8:21
+ --> $DIR/issue_4266.rs:10:21
|
LL | async fn one_to_one<'a>(s: &'a str) -> &'a str {
| ^^ ^^
error: methods called `new` usually take no `self`
- --> $DIR/issue_4266.rs:28:22
+ --> $DIR/issue_4266.rs:31:22
|
LL | pub async fn new(&mut self) -> Self {
| ^^^^^^^^^
|
= help: consider choosing a less ambiguous name
= note: `-D clippy::wrong-self-convention` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/items_after_statement.rs b/src/tools/clippy/tests/ui/items_after_statement.rs
index f12cb8f22..943e7c116 100644
--- a/src/tools/clippy/tests/ui/items_after_statement.rs
+++ b/src/tools/clippy/tests/ui/items_after_statement.rs
@@ -11,6 +11,8 @@ fn ok() {
fn last() {
foo();
fn foo() {
+ //~^ ERROR: adding items after statements is confusing, since items exist from the sta
+ //~| NOTE: `-D clippy::items-after-statements` implied by `-D warnings`
println!("foo");
}
}
@@ -18,6 +20,7 @@ fn last() {
fn main() {
foo();
fn foo() {
+ //~^ ERROR: adding items after statements is confusing, since items exist from the sta
println!("foo");
}
foo();
diff --git a/src/tools/clippy/tests/ui/items_after_statement.stderr b/src/tools/clippy/tests/ui/items_after_statement.stderr
index f69635a97..fa494f217 100644
--- a/src/tools/clippy/tests/ui/items_after_statement.stderr
+++ b/src/tools/clippy/tests/ui/items_after_statement.stderr
@@ -2,22 +2,26 @@ error: adding items after statements is confusing, since items exist from the st
--> $DIR/items_after_statement.rs:13:5
|
LL | / fn foo() {
+LL | |
+LL | |
LL | | println!("foo");
LL | | }
| |_____^
|
= note: `-D clippy::items-after-statements` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::items_after_statements)]`
error: adding items after statements is confusing, since items exist from the start of the scope
- --> $DIR/items_after_statement.rs:20:5
+ --> $DIR/items_after_statement.rs:22:5
|
LL | / fn foo() {
+LL | |
LL | | println!("foo");
LL | | }
| |_____^
error: adding items after statements is confusing, since items exist from the start of the scope
- --> $DIR/items_after_statement.rs:33:13
+ --> $DIR/items_after_statement.rs:36:13
|
LL | / fn say_something() {
LL | | println!("something");
diff --git a/src/tools/clippy/tests/ui/iter_cloned_collect.fixed b/src/tools/clippy/tests/ui/iter_cloned_collect.fixed
index 636f572a3..1d623642a 100644
--- a/src/tools/clippy/tests/ui/iter_cloned_collect.fixed
+++ b/src/tools/clippy/tests/ui/iter_cloned_collect.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/iter_cloned_collect.rs b/src/tools/clippy/tests/ui/iter_cloned_collect.rs
index 518cb75af..091bd9eaf 100644
--- a/src/tools/clippy/tests/ui/iter_cloned_collect.rs
+++ b/src/tools/clippy/tests/ui/iter_cloned_collect.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/iter_cloned_collect.stderr b/src/tools/clippy/tests/ui/iter_cloned_collect.stderr
index b2cc497bf..aa7fb98a7 100644
--- a/src/tools/clippy/tests/ui/iter_cloned_collect.stderr
+++ b/src/tools/clippy/tests/ui/iter_cloned_collect.stderr
@@ -1,19 +1,20 @@
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
- --> $DIR/iter_cloned_collect.rs:10:27
+ --> $DIR/iter_cloned_collect.rs:8:27
|
LL | let v2: Vec<isize> = v.iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
|
= note: `-D clippy::iter-cloned-collect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_cloned_collect)]`
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
- --> $DIR/iter_cloned_collect.rs:15:38
+ --> $DIR/iter_cloned_collect.rs:13:38
|
LL | let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
- --> $DIR/iter_cloned_collect.rs:20:24
+ --> $DIR/iter_cloned_collect.rs:18:24
|
LL | .to_bytes()
| ________________________^
@@ -23,13 +24,13 @@ LL | | .collect();
| |______________________^ help: try: `.to_vec()`
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
- --> $DIR/iter_cloned_collect.rs:28:24
+ --> $DIR/iter_cloned_collect.rs:26:24
|
LL | let _: Vec<_> = arr.iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
error: called `iter().copied().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
- --> $DIR/iter_cloned_collect.rs:31:26
+ --> $DIR/iter_cloned_collect.rs:29:26
|
LL | let _: Vec<isize> = v.iter().copied().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
diff --git a/src/tools/clippy/tests/ui/iter_count.fixed b/src/tools/clippy/tests/ui/iter_count.fixed
index b62082014..75c007bb0 100644
--- a/src/tools/clippy/tests/ui/iter_count.fixed
+++ b/src/tools/clippy/tests/ui/iter_count.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:option_helpers.rs
#![warn(clippy::iter_count)]
diff --git a/src/tools/clippy/tests/ui/iter_count.rs b/src/tools/clippy/tests/ui/iter_count.rs
index fb2161312..cd8207b2c 100644
--- a/src/tools/clippy/tests/ui/iter_count.rs
+++ b/src/tools/clippy/tests/ui/iter_count.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:option_helpers.rs
#![warn(clippy::iter_count)]
diff --git a/src/tools/clippy/tests/ui/iter_count.stderr b/src/tools/clippy/tests/ui/iter_count.stderr
index f9aee0b78..2882b7d28 100644
--- a/src/tools/clippy/tests/ui/iter_count.stderr
+++ b/src/tools/clippy/tests/ui/iter_count.stderr
@@ -1,151 +1,152 @@
error: called `.iter().count()` on a `slice`
- --> $DIR/iter_count.rs:55:6
+ --> $DIR/iter_count.rs:54:6
|
LL | &vec[..].iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`
|
= note: `-D clippy::iter-count` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_count)]`
error: called `.iter().count()` on a `Vec`
- --> $DIR/iter_count.rs:56:5
+ --> $DIR/iter_count.rs:55:5
|
LL | vec.iter().count();
| ^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`
error: called `.iter().count()` on a `slice`
- --> $DIR/iter_count.rs:57:5
+ --> $DIR/iter_count.rs:56:5
|
LL | boxed_slice.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()`
error: called `.iter().count()` on a `VecDeque`
- --> $DIR/iter_count.rs:58:5
+ --> $DIR/iter_count.rs:57:5
|
LL | vec_deque.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`
error: called `.iter().count()` on a `HashSet`
- --> $DIR/iter_count.rs:59:5
+ --> $DIR/iter_count.rs:58:5
|
LL | hash_set.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()`
error: called `.iter().count()` on a `HashMap`
- --> $DIR/iter_count.rs:60:5
+ --> $DIR/iter_count.rs:59:5
|
LL | hash_map.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()`
error: called `.iter().count()` on a `BTreeMap`
- --> $DIR/iter_count.rs:61:5
+ --> $DIR/iter_count.rs:60:5
|
LL | b_tree_map.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()`
error: called `.iter().count()` on a `BTreeSet`
- --> $DIR/iter_count.rs:62:5
+ --> $DIR/iter_count.rs:61:5
|
LL | b_tree_set.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()`
error: called `.iter().count()` on a `LinkedList`
- --> $DIR/iter_count.rs:63:5
+ --> $DIR/iter_count.rs:62:5
|
LL | linked_list.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()`
error: called `.iter().count()` on a `BinaryHeap`
- --> $DIR/iter_count.rs:64:5
+ --> $DIR/iter_count.rs:63:5
|
LL | binary_heap.iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()`
error: called `.iter_mut().count()` on a `Vec`
- --> $DIR/iter_count.rs:66:5
+ --> $DIR/iter_count.rs:65:5
|
LL | vec.iter_mut().count();
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`
error: called `.iter_mut().count()` on a `slice`
- --> $DIR/iter_count.rs:67:6
+ --> $DIR/iter_count.rs:66:6
|
LL | &vec[..].iter_mut().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`
error: called `.iter_mut().count()` on a `VecDeque`
- --> $DIR/iter_count.rs:68:5
+ --> $DIR/iter_count.rs:67:5
|
LL | vec_deque.iter_mut().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`
error: called `.iter_mut().count()` on a `HashMap`
- --> $DIR/iter_count.rs:69:5
+ --> $DIR/iter_count.rs:68:5
|
LL | hash_map.iter_mut().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()`
error: called `.iter_mut().count()` on a `BTreeMap`
- --> $DIR/iter_count.rs:70:5
+ --> $DIR/iter_count.rs:69:5
|
LL | b_tree_map.iter_mut().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()`
error: called `.iter_mut().count()` on a `LinkedList`
- --> $DIR/iter_count.rs:71:5
+ --> $DIR/iter_count.rs:70:5
|
LL | linked_list.iter_mut().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()`
error: called `.into_iter().count()` on a `slice`
- --> $DIR/iter_count.rs:73:6
+ --> $DIR/iter_count.rs:72:6
|
LL | &vec[..].into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`
error: called `.into_iter().count()` on a `Vec`
- --> $DIR/iter_count.rs:74:5
+ --> $DIR/iter_count.rs:73:5
|
LL | vec.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`
error: called `.into_iter().count()` on a `VecDeque`
- --> $DIR/iter_count.rs:75:5
+ --> $DIR/iter_count.rs:74:5
|
LL | vec_deque.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`
error: called `.into_iter().count()` on a `HashSet`
- --> $DIR/iter_count.rs:76:5
+ --> $DIR/iter_count.rs:75:5
|
LL | hash_set.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()`
error: called `.into_iter().count()` on a `HashMap`
- --> $DIR/iter_count.rs:77:5
+ --> $DIR/iter_count.rs:76:5
|
LL | hash_map.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()`
error: called `.into_iter().count()` on a `BTreeMap`
- --> $DIR/iter_count.rs:78:5
+ --> $DIR/iter_count.rs:77:5
|
LL | b_tree_map.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()`
error: called `.into_iter().count()` on a `BTreeSet`
- --> $DIR/iter_count.rs:79:5
+ --> $DIR/iter_count.rs:78:5
|
LL | b_tree_set.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()`
error: called `.into_iter().count()` on a `LinkedList`
- --> $DIR/iter_count.rs:80:5
+ --> $DIR/iter_count.rs:79:5
|
LL | linked_list.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()`
error: called `.into_iter().count()` on a `BinaryHeap`
- --> $DIR/iter_count.rs:81:5
+ --> $DIR/iter_count.rs:80:5
|
LL | binary_heap.into_iter().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()`
diff --git a/src/tools/clippy/tests/ui/iter_kv_map.fixed b/src/tools/clippy/tests/ui/iter_kv_map.fixed
index 64201b553..566a5b690 100644
--- a/src/tools/clippy/tests/ui/iter_kv_map.fixed
+++ b/src/tools/clippy/tests/ui/iter_kv_map.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::iter_kv_map)]
#![allow(unused_mut, clippy::redundant_clone, clippy::suspicious_map, clippy::map_identity)]
diff --git a/src/tools/clippy/tests/ui/iter_kv_map.rs b/src/tools/clippy/tests/ui/iter_kv_map.rs
index ec0231ba5..d85e501da 100644
--- a/src/tools/clippy/tests/ui/iter_kv_map.rs
+++ b/src/tools/clippy/tests/ui/iter_kv_map.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::iter_kv_map)]
#![allow(unused_mut, clippy::redundant_clone, clippy::suspicious_map, clippy::map_identity)]
diff --git a/src/tools/clippy/tests/ui/iter_kv_map.stderr b/src/tools/clippy/tests/ui/iter_kv_map.stderr
index e00da223b..62155b7f8 100644
--- a/src/tools/clippy/tests/ui/iter_kv_map.stderr
+++ b/src/tools/clippy/tests/ui/iter_kv_map.stderr
@@ -1,79 +1,80 @@
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:16:13
+ --> $DIR/iter_kv_map.rs:14:13
|
LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
|
= note: `-D clippy::iter-kv-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_kv_map)]`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:17:13
+ --> $DIR/iter_kv_map.rs:15:13
|
LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:18:13
+ --> $DIR/iter_kv_map.rs:16:13
|
LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:20:13
+ --> $DIR/iter_kv_map.rs:18:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:21:13
+ --> $DIR/iter_kv_map.rs:19:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:23:13
+ --> $DIR/iter_kv_map.rs:21:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:24:13
+ --> $DIR/iter_kv_map.rs:22:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:26:13
+ --> $DIR/iter_kv_map.rs:24:13
|
LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:27:13
+ --> $DIR/iter_kv_map.rs:25:13
|
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:37:13
+ --> $DIR/iter_kv_map.rs:35:13
|
LL | let _ = map.iter().map(|(key, _value)| key * 9).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:38:13
+ --> $DIR/iter_kv_map.rs:36:13
|
LL | let _ = map.iter().map(|(_key, value)| value * 17).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:41:13
+ --> $DIR/iter_kv_map.rs:39:13
|
LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:44:13
+ --> $DIR/iter_kv_map.rs:42:13
|
LL | let _ = map
| _____________^
@@ -95,85 +96,85 @@ LL + })
|
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:54:13
+ --> $DIR/iter_kv_map.rs:52:13
|
LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:58:13
+ --> $DIR/iter_kv_map.rs:56:13
|
LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:59:13
+ --> $DIR/iter_kv_map.rs:57:13
|
LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:60:13
+ --> $DIR/iter_kv_map.rs:58:13
|
LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:62:13
+ --> $DIR/iter_kv_map.rs:60:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:63:13
+ --> $DIR/iter_kv_map.rs:61:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:65:13
+ --> $DIR/iter_kv_map.rs:63:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:66:13
+ --> $DIR/iter_kv_map.rs:64:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:68:13
+ --> $DIR/iter_kv_map.rs:66:13
|
LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:69:13
+ --> $DIR/iter_kv_map.rs:67:13
|
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
error: iterating on a map's keys
- --> $DIR/iter_kv_map.rs:79:13
+ --> $DIR/iter_kv_map.rs:77:13
|
LL | let _ = map.iter().map(|(key, _value)| key * 9).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:80:13
+ --> $DIR/iter_kv_map.rs:78:13
|
LL | let _ = map.iter().map(|(_key, value)| value * 17).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:83:13
+ --> $DIR/iter_kv_map.rs:81:13
|
LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))`
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:86:13
+ --> $DIR/iter_kv_map.rs:84:13
|
LL | let _ = map
| _____________^
@@ -195,7 +196,7 @@ LL + })
|
error: iterating on a map's values
- --> $DIR/iter_kv_map.rs:96:13
+ --> $DIR/iter_kv_map.rs:94:13
|
LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
diff --git a/src/tools/clippy/tests/ui/iter_next_slice.fixed b/src/tools/clippy/tests/ui/iter_next_slice.fixed
index 702edccdb..83be12c4e 100644
--- a/src/tools/clippy/tests/ui/iter_next_slice.fixed
+++ b/src/tools/clippy/tests/ui/iter_next_slice.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_next_slice)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/iter_next_slice.rs b/src/tools/clippy/tests/ui/iter_next_slice.rs
index 30bfc72de..1b257514d 100644
--- a/src/tools/clippy/tests/ui/iter_next_slice.rs
+++ b/src/tools/clippy/tests/ui/iter_next_slice.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_next_slice)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/iter_next_slice.stderr b/src/tools/clippy/tests/ui/iter_next_slice.stderr
index 0db8201a1..e6b4bd6c0 100644
--- a/src/tools/clippy/tests/ui/iter_next_slice.stderr
+++ b/src/tools/clippy/tests/ui/iter_next_slice.stderr
@@ -1,25 +1,26 @@
error: using `.iter().next()` on an array
- --> $DIR/iter_next_slice.rs:10:13
+ --> $DIR/iter_next_slice.rs:9:13
|
LL | let _ = s.iter().next();
| ^^^^^^^^^^^^^^^ help: try calling: `s.first()`
|
= note: `-D clippy::iter-next-slice` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_next_slice)]`
error: using `.iter().next()` on a Slice without end index
- --> $DIR/iter_next_slice.rs:13:13
+ --> $DIR/iter_next_slice.rs:12:13
|
LL | let _ = s[2..].iter().next();
| ^^^^^^^^^^^^^^^^^^^^ help: try calling: `s.get(2)`
error: using `.iter().next()` on a Slice without end index
- --> $DIR/iter_next_slice.rs:16:13
+ --> $DIR/iter_next_slice.rs:15:13
|
LL | let _ = v[5..].iter().next();
| ^^^^^^^^^^^^^^^^^^^^ help: try calling: `v.get(5)`
error: using `.iter().next()` on an array
- --> $DIR/iter_next_slice.rs:19:13
+ --> $DIR/iter_next_slice.rs:18:13
|
LL | let _ = v.iter().next();
| ^^^^^^^^^^^^^^^ help: try calling: `v.first()`
diff --git a/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs b/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs
index cce216fc6..e694bc7ac 100644
--- a/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs
+++ b/src/tools/clippy/tests/ui/iter_not_returning_iterator.rs
@@ -28,10 +28,13 @@ struct Counter2 {
impl Data2 {
fn iter(&self) -> Counter2 {
+ //~^ ERROR: this method is named `iter` but its return type does not implement `Iterat
+ //~| NOTE: `-D clippy::iter-not-returning-iterator` implied by `-D warnings`
todo!()
}
fn iter_mut(&self) -> Counter2 {
+ //~^ ERROR: this method is named `iter_mut` but its return type does not implement `It
todo!()
}
}
@@ -48,6 +51,7 @@ impl Iterator for Counter {
trait Iter {
type I;
fn iter(&self) -> Self::I;
+ //~^ ERROR: this method is named `iter` but its return type does not implement `Iterat
}
impl Iter for () {
diff --git a/src/tools/clippy/tests/ui/iter_not_returning_iterator.stderr b/src/tools/clippy/tests/ui/iter_not_returning_iterator.stderr
index 44f029558..c695b1932 100644
--- a/src/tools/clippy/tests/ui/iter_not_returning_iterator.stderr
+++ b/src/tools/clippy/tests/ui/iter_not_returning_iterator.stderr
@@ -5,15 +5,16 @@ LL | fn iter(&self) -> Counter2 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::iter-not-returning-iterator` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_not_returning_iterator)]`
error: this method is named `iter_mut` but its return type does not implement `Iterator`
- --> $DIR/iter_not_returning_iterator.rs:34:5
+ --> $DIR/iter_not_returning_iterator.rs:36:5
|
LL | fn iter_mut(&self) -> Counter2 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this method is named `iter` but its return type does not implement `Iterator`
- --> $DIR/iter_not_returning_iterator.rs:50:5
+ --> $DIR/iter_not_returning_iterator.rs:53:5
|
LL | fn iter(&self) -> Self::I;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/iter_nth.stderr b/src/tools/clippy/tests/ui/iter_nth.stderr
index 24be81454..162e6c338 100644
--- a/src/tools/clippy/tests/ui/iter_nth.stderr
+++ b/src/tools/clippy/tests/ui/iter_nth.stderr
@@ -6,6 +6,7 @@ LL | let bad_vec = some_vec.iter().nth(3);
|
= help: calling `.get()` is both faster and more readable
= note: `-D clippy::iter-nth` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_nth)]`
error: called `.iter().nth()` on a slice
--> $DIR/iter_nth.rs:35:26
diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.fixed b/src/tools/clippy/tests/ui/iter_nth_zero.fixed
index 91f4a7ba0..a3cdb2e59 100644
--- a/src/tools/clippy/tests/ui/iter_nth_zero.fixed
+++ b/src/tools/clippy/tests/ui/iter_nth_zero.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::iter_nth_zero)]
use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.rs b/src/tools/clippy/tests/ui/iter_nth_zero.rs
index 160a895bb..64229b512 100644
--- a/src/tools/clippy/tests/ui/iter_nth_zero.rs
+++ b/src/tools/clippy/tests/ui/iter_nth_zero.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::iter_nth_zero)]
use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.stderr b/src/tools/clippy/tests/ui/iter_nth_zero.stderr
index 29c56f3a9..939fd0063 100644
--- a/src/tools/clippy/tests/ui/iter_nth_zero.stderr
+++ b/src/tools/clippy/tests/ui/iter_nth_zero.stderr
@@ -1,19 +1,20 @@
error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent
- --> $DIR/iter_nth_zero.rs:20:14
+ --> $DIR/iter_nth_zero.rs:18:14
|
LL | let _x = s.iter().nth(0);
| ^^^^^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `s.iter().next()`
|
= note: `-D clippy::iter-nth-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_nth_zero)]`
error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent
- --> $DIR/iter_nth_zero.rs:25:14
+ --> $DIR/iter_nth_zero.rs:23:14
|
LL | let _y = iter.nth(0);
| ^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter.next()`
error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent
- --> $DIR/iter_nth_zero.rs:30:22
+ --> $DIR/iter_nth_zero.rs:28:22
|
LL | let _unwrapped = iter2.nth(0).unwrap();
| ^^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter2.next()`
diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed
index 4616f0cdc..794629f24 100644
--- a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed
+++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_on_empty_collections)]
#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs
index 81cc7265e..a6461a702 100644
--- a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs
+++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_on_empty_collections)]
#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr
index cbd611769..57a532019 100644
--- a/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr
+++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.stderr
@@ -1,37 +1,38 @@
error: `into_iter` call on an empty collection
- --> $DIR/iter_on_empty_collections.rs:6:16
+ --> $DIR/iter_on_empty_collections.rs:5:16
|
LL | assert_eq!([].into_iter().next(), Option::<i32>::None);
| ^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
|
= note: `-D clippy::iter-on-empty-collections` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_on_empty_collections)]`
error: `iter_mut` call on an empty collection
- --> $DIR/iter_on_empty_collections.rs:7:16
+ --> $DIR/iter_on_empty_collections.rs:6:16
|
LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
| ^^^^^^^^^^^^^ help: try: `std::iter::empty()`
error: `iter` call on an empty collection
- --> $DIR/iter_on_empty_collections.rs:8:16
+ --> $DIR/iter_on_empty_collections.rs:7:16
|
LL | assert_eq!([].iter().next(), Option::<&i32>::None);
| ^^^^^^^^^ help: try: `std::iter::empty()`
error: `into_iter` call on an empty collection
- --> $DIR/iter_on_empty_collections.rs:9:16
+ --> $DIR/iter_on_empty_collections.rs:8:16
|
LL | assert_eq!(None.into_iter().next(), Option::<i32>::None);
| ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
error: `iter_mut` call on an empty collection
- --> $DIR/iter_on_empty_collections.rs:10:16
+ --> $DIR/iter_on_empty_collections.rs:9:16
|
LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
| ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
error: `iter` call on an empty collection
- --> $DIR/iter_on_empty_collections.rs:11:16
+ --> $DIR/iter_on_empty_collections.rs:10:16
|
LL | assert_eq!(None.iter().next(), Option::<&i32>::None);
| ^^^^^^^^^^^ help: try: `std::iter::empty()`
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.fixed b/src/tools/clippy/tests/ui/iter_on_single_items.fixed
index 80dbe454b..117ec8429 100644
--- a/src/tools/clippy/tests/ui/iter_on_single_items.fixed
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_on_single_items)]
#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.rs b/src/tools/clippy/tests/ui/iter_on_single_items.rs
index 71c8c7a3f..d059370d9 100644
--- a/src/tools/clippy/tests/ui/iter_on_single_items.rs
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_on_single_items)]
#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.stderr b/src/tools/clippy/tests/ui/iter_on_single_items.stderr
index d6c547116..00398f541 100644
--- a/src/tools/clippy/tests/ui/iter_on_single_items.stderr
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.stderr
@@ -1,37 +1,38 @@
error: `into_iter` call on a collection with only one item
- --> $DIR/iter_on_single_items.rs:6:16
+ --> $DIR/iter_on_single_items.rs:5:16
|
LL | assert_eq!([123].into_iter().next(), Some(123));
| ^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
|
= note: `-D clippy::iter-on-single-items` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_on_single_items)]`
error: `iter_mut` call on a collection with only one item
- --> $DIR/iter_on_single_items.rs:7:16
+ --> $DIR/iter_on_single_items.rs:6:16
|
LL | assert_eq!([123].iter_mut().next(), Some(&mut 123));
| ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
error: `iter` call on a collection with only one item
- --> $DIR/iter_on_single_items.rs:8:16
+ --> $DIR/iter_on_single_items.rs:7:16
|
LL | assert_eq!([123].iter().next(), Some(&123));
| ^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
error: `into_iter` call on a collection with only one item
- --> $DIR/iter_on_single_items.rs:9:16
+ --> $DIR/iter_on_single_items.rs:8:16
|
LL | assert_eq!(Some(123).into_iter().next(), Some(123));
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
error: `iter_mut` call on a collection with only one item
- --> $DIR/iter_on_single_items.rs:10:16
+ --> $DIR/iter_on_single_items.rs:9:16
|
LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
| ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
error: `iter` call on a collection with only one item
- --> $DIR/iter_on_single_items.rs:11:16
+ --> $DIR/iter_on_single_items.rs:10:16
|
LL | assert_eq!(Some(123).iter().next(), Some(&123));
| ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
diff --git a/src/tools/clippy/tests/ui/iter_out_of_bounds.rs b/src/tools/clippy/tests/ui/iter_out_of_bounds.rs
new file mode 100644
index 000000000..3cfe6e82f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_out_of_bounds.rs
@@ -0,0 +1,71 @@
+//@no-rustfix
+
+#![deny(clippy::iter_out_of_bounds)]
+#![allow(clippy::useless_vec)]
+
+fn opaque_empty_iter() -> impl Iterator<Item = ()> {
+ std::iter::empty()
+}
+
+fn main() {
+ #[allow(clippy::never_loop)]
+ for _ in [1, 2, 3].iter().skip(4) {
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+ unreachable!();
+ }
+ for (i, _) in [1, 2, 3].iter().take(4).enumerate() {
+ //~^ ERROR: this `.take()` call takes more items than the iterator will produce
+ assert!(i <= 2);
+ }
+
+ #[allow(clippy::needless_borrow)]
+ for _ in (&&&&&&[1, 2, 3]).iter().take(4) {}
+ //~^ ERROR: this `.take()` call takes more items than the iterator will produce
+
+ for _ in [1, 2, 3].iter().skip(4) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ for _ in [1; 3].iter().skip(4) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ // Should not lint
+ for _ in opaque_empty_iter().skip(1) {}
+
+ for _ in vec![1, 2, 3].iter().skip(4) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ for _ in vec![1; 3].iter().skip(4) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ let x = [1, 2, 3];
+ for _ in x.iter().skip(4) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ let n = 4;
+ for _ in x.iter().skip(n) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ let empty = std::iter::empty::<i8>;
+
+ for _ in empty().skip(1) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ for _ in empty().take(1) {}
+ //~^ ERROR: this `.take()` call takes more items than the iterator will produce
+
+ for _ in std::iter::once(1).skip(2) {}
+ //~^ ERROR: this `.skip()` call skips more items than the iterator will produce
+
+ for _ in std::iter::once(1).take(2) {}
+ //~^ ERROR: this `.take()` call takes more items than the iterator will produce
+
+ for x in [].iter().take(1) {
+ //~^ ERROR: this `.take()` call takes more items than the iterator will produce
+ let _: &i32 = x;
+ }
+
+ // ok, not out of bounds
+ for _ in [1].iter().take(1) {}
+ for _ in [1, 2, 3].iter().take(2) {}
+ for _ in [1, 2, 3].iter().skip(2) {}
+}
diff --git a/src/tools/clippy/tests/ui/iter_out_of_bounds.stderr b/src/tools/clippy/tests/ui/iter_out_of_bounds.stderr
new file mode 100644
index 000000000..f235faec8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_out_of_bounds.stderr
@@ -0,0 +1,119 @@
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:12:14
+ |
+LL | for _ in [1, 2, 3].iter().skip(4) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+note: the lint level is defined here
+ --> $DIR/iter_out_of_bounds.rs:3:9
+ |
+LL | #![deny(clippy::iter_out_of_bounds)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: this `.take()` call takes more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:16:19
+ |
+LL | for (i, _) in [1, 2, 3].iter().take(4).enumerate() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and the returned iterator will simply yield the same items
+
+error: this `.take()` call takes more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:22:14
+ |
+LL | for _ in (&&&&&&[1, 2, 3]).iter().take(4) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and the returned iterator will simply yield the same items
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:25:14
+ |
+LL | for _ in [1, 2, 3].iter().skip(4) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:28:14
+ |
+LL | for _ in [1; 3].iter().skip(4) {}
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:34:14
+ |
+LL | for _ in vec![1, 2, 3].iter().skip(4) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:37:14
+ |
+LL | for _ in vec![1; 3].iter().skip(4) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:41:14
+ |
+LL | for _ in x.iter().skip(4) {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:45:14
+ |
+LL | for _ in x.iter().skip(n) {}
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:50:14
+ |
+LL | for _ in empty().skip(1) {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.take()` call takes more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:53:14
+ |
+LL | for _ in empty().take(1) {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and the returned iterator will simply yield the same items
+
+error: this `.skip()` call skips more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:56:14
+ |
+LL | for _ in std::iter::once(1).skip(2) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and will create an empty iterator
+
+error: this `.take()` call takes more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:59:14
+ |
+LL | for _ in std::iter::once(1).take(2) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and the returned iterator will simply yield the same items
+
+error: this `.take()` call takes more items than the iterator will produce
+ --> $DIR/iter_out_of_bounds.rs:62:14
+ |
+LL | for x in [].iter().take(1) {
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: this operation is useless and the returned iterator will simply yield the same items
+
+error: aborting due to 14 previous errors
+
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
index 2874513c0..7d8a584b0 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
#![allow(dead_code, clippy::let_unit_value, clippy::useless_vec)]
@@ -21,26 +20,52 @@ fn main() {
.iter()
.flatten().cloned();
- // Not implemented yet
- let _ = vec.iter().cloned().filter(|x| x.starts_with('2'));
+ let _ = vec.iter().filter(|&x| x.starts_with('2')).cloned();
- // Not implemented yet
- let _ = vec.iter().cloned().map(|x| x.len());
+ let _ = vec.iter().find(|&x| x == "2").cloned();
+
+ {
+ let f = |x: &String| x.starts_with('2');
+ let _ = vec.iter().filter(|&x| f(x)).cloned();
+ let _ = vec.iter().find(|&x| f(x)).cloned();
+ }
+
+ {
+ let vec: Vec<(String, String)> = vec![];
+ let f = move |x: &(String, String)| x.0.starts_with('2');
+ let _ = vec.iter().filter(|&x| f(x)).cloned();
+ let _ = vec.iter().find(|&x| f(x)).cloned();
+ }
+
+ fn test_move<'a>(
+ iter: impl Iterator<Item = &'a (&'a u32, String)> + 'a,
+ target: String,
+ ) -> impl Iterator<Item = (&'a u32, String)> + 'a {
+ iter.filter(move |&(&a, b)| a == 1 && b == &target).cloned()
+ }
+
+ {
+ #[derive(Clone)]
+ struct S<'a> {
+ a: &'a u32,
+ b: String,
+ }
+
+ fn bar<'a>(iter: impl Iterator<Item = &'a S<'a>> + 'a, target: String) -> impl Iterator<Item = S<'a>> + 'a {
+ iter.filter(move |&S { a, b }| **a == 1 && b == &target).cloned()
+ }
+ }
+
+ let _ = vec.iter().map(|x| x.len());
// This would fail if changed.
let _ = vec.iter().cloned().map(|x| x + "2");
- // Not implemented yet
- let _ = vec.iter().cloned().find(|x| x == "2");
-
- // Not implemented yet
- let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty()));
+ let _ = vec.iter().for_each(|x| assert!(!x.is_empty()));
- // Not implemented yet
- let _ = vec.iter().cloned().all(|x| x.len() == 1);
+ let _ = vec.iter().all(|x| x.len() == 1);
- // Not implemented yet
- let _ = vec.iter().cloned().any(|x| x.len() == 1);
+ let _ = vec.iter().any(|x| x.len() == 1);
// Should probably stay as it is.
let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
index 26f39734a..58c374ab8 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
#![allow(dead_code, clippy::let_unit_value, clippy::useless_vec)]
@@ -22,25 +21,51 @@ fn main() {
.cloned()
.flatten();
- // Not implemented yet
let _ = vec.iter().cloned().filter(|x| x.starts_with('2'));
- // Not implemented yet
+ let _ = vec.iter().cloned().find(|x| x == "2");
+
+ {
+ let f = |x: &String| x.starts_with('2');
+ let _ = vec.iter().cloned().filter(f);
+ let _ = vec.iter().cloned().find(f);
+ }
+
+ {
+ let vec: Vec<(String, String)> = vec![];
+ let f = move |x: &(String, String)| x.0.starts_with('2');
+ let _ = vec.iter().cloned().filter(f);
+ let _ = vec.iter().cloned().find(f);
+ }
+
+ fn test_move<'a>(
+ iter: impl Iterator<Item = &'a (&'a u32, String)> + 'a,
+ target: String,
+ ) -> impl Iterator<Item = (&'a u32, String)> + 'a {
+ iter.cloned().filter(move |(&a, b)| a == 1 && b == &target)
+ }
+
+ {
+ #[derive(Clone)]
+ struct S<'a> {
+ a: &'a u32,
+ b: String,
+ }
+
+ fn bar<'a>(iter: impl Iterator<Item = &'a S<'a>> + 'a, target: String) -> impl Iterator<Item = S<'a>> + 'a {
+ iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target)
+ }
+ }
+
let _ = vec.iter().cloned().map(|x| x.len());
// This would fail if changed.
let _ = vec.iter().cloned().map(|x| x + "2");
- // Not implemented yet
- let _ = vec.iter().cloned().find(|x| x == "2");
-
- // Not implemented yet
let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty()));
- // Not implemented yet
let _ = vec.iter().cloned().all(|x| x.len() == 1);
- // Not implemented yet
let _ = vec.iter().cloned().any(|x| x.len() == 1);
// Should probably stay as it is.
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr b/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
index eaac48be8..a9a739688 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
@@ -1,5 +1,5 @@
error: unnecessarily eager cloning of iterator items
- --> $DIR/iter_overeager_cloned.rs:8:29
+ --> $DIR/iter_overeager_cloned.rs:7:29
|
LL | let _: Option<String> = vec.iter().cloned().last();
| ^^^^^^^^^^----------------
@@ -7,9 +7,10 @@ LL | let _: Option<String> = vec.iter().cloned().last();
| help: try: `.last().cloned()`
|
= note: `-D clippy::iter-overeager-cloned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_overeager_cloned)]`
error: unnecessarily eager cloning of iterator items
- --> $DIR/iter_overeager_cloned.rs:10:29
+ --> $DIR/iter_overeager_cloned.rs:9:29
|
LL | let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------
@@ -17,7 +18,7 @@ LL | let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();
| help: try: `.next().cloned()`
error: unneeded cloning of iterator items
- --> $DIR/iter_overeager_cloned.rs:12:20
+ --> $DIR/iter_overeager_cloned.rs:11:20
|
LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------
@@ -25,9 +26,10 @@ LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
| help: try: `.count()`
|
= note: `-D clippy::redundant-clone` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
error: unnecessarily eager cloning of iterator items
- --> $DIR/iter_overeager_cloned.rs:14:21
+ --> $DIR/iter_overeager_cloned.rs:13:21
|
LL | let _: Vec<_> = vec.iter().cloned().take(2).collect();
| ^^^^^^^^^^-----------------
@@ -35,7 +37,7 @@ LL | let _: Vec<_> = vec.iter().cloned().take(2).collect();
| help: try: `.take(2).cloned()`
error: unnecessarily eager cloning of iterator items
- --> $DIR/iter_overeager_cloned.rs:16:21
+ --> $DIR/iter_overeager_cloned.rs:15:21
|
LL | let _: Vec<_> = vec.iter().cloned().skip(2).collect();
| ^^^^^^^^^^-----------------
@@ -43,7 +45,7 @@ LL | let _: Vec<_> = vec.iter().cloned().skip(2).collect();
| help: try: `.skip(2).cloned()`
error: unnecessarily eager cloning of iterator items
- --> $DIR/iter_overeager_cloned.rs:18:13
+ --> $DIR/iter_overeager_cloned.rs:17:13
|
LL | let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------
@@ -51,7 +53,7 @@ LL | let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2);
| help: try: `.nth(2).cloned()`
error: unnecessarily eager cloning of iterator items
- --> $DIR/iter_overeager_cloned.rs:20:13
+ --> $DIR/iter_overeager_cloned.rs:19:13
|
LL | let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))]
| _____________^
@@ -66,5 +68,101 @@ LL ~ .iter()
LL ~ .flatten().cloned();
|
-error: aborting due to 7 previous errors
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:24:13
+ |
+LL | let _ = vec.iter().cloned().filter(|x| x.starts_with('2'));
+ | ^^^^^^^^^^----------------------------------------
+ | |
+ | help: try: `.filter(|&x| x.starts_with('2')).cloned()`
+
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:26:13
+ |
+LL | let _ = vec.iter().cloned().find(|x| x == "2");
+ | ^^^^^^^^^^----------------------------
+ | |
+ | help: try: `.find(|&x| x == "2").cloned()`
+
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:30:17
+ |
+LL | let _ = vec.iter().cloned().filter(f);
+ | ^^^^^^^^^^-------------------
+ | |
+ | help: try: `.filter(|&x| f(x)).cloned()`
+
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:31:17
+ |
+LL | let _ = vec.iter().cloned().find(f);
+ | ^^^^^^^^^^-----------------
+ | |
+ | help: try: `.find(|&x| f(x)).cloned()`
+
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:37:17
+ |
+LL | let _ = vec.iter().cloned().filter(f);
+ | ^^^^^^^^^^-------------------
+ | |
+ | help: try: `.filter(|&x| f(x)).cloned()`
+
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:38:17
+ |
+LL | let _ = vec.iter().cloned().find(f);
+ | ^^^^^^^^^^-----------------
+ | |
+ | help: try: `.find(|&x| f(x)).cloned()`
+
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:45:9
+ |
+LL | iter.cloned().filter(move |(&a, b)| a == 1 && b == &target)
+ | ^^^^-------------------------------------------------------
+ | |
+ | help: try: `.filter(move |&(&a, b)| a == 1 && b == &target).cloned()`
+
+error: unnecessarily eager cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:56:13
+ |
+LL | iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target)
+ | ^^^^------------------------------------------------------------
+ | |
+ | help: try: `.filter(move |&S { a, b }| **a == 1 && b == &target).cloned()`
+
+error: unneeded cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:60:13
+ |
+LL | let _ = vec.iter().cloned().map(|x| x.len());
+ | ^^^^^^^^^^--------------------------
+ | |
+ | help: try: `.map(|x| x.len())`
+
+error: unneeded cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:65:13
+ |
+LL | let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty()));
+ | ^^^^^^^^^^----------------------------------------------
+ | |
+ | help: try: `.for_each(|x| assert!(!x.is_empty()))`
+
+error: unneeded cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:67:13
+ |
+LL | let _ = vec.iter().cloned().all(|x| x.len() == 1);
+ | ^^^^^^^^^^-------------------------------
+ | |
+ | help: try: `.all(|x| x.len() == 1)`
+
+error: unneeded cloning of iterator items
+ --> $DIR/iter_overeager_cloned.rs:69:13
+ |
+LL | let _ = vec.iter().cloned().any(|x| x.len() == 1);
+ | ^^^^^^^^^^-------------------------------
+ | |
+ | help: try: `.any(|x| x.len() == 1)`
+
+error: aborting due to 19 previous errors
diff --git a/src/tools/clippy/tests/ui/iter_skip_next.fixed b/src/tools/clippy/tests/ui/iter_skip_next.fixed
index b888d965e..3e41b3632 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next.fixed
+++ b/src/tools/clippy/tests/ui/iter_skip_next.fixed
@@ -1,10 +1,10 @@
-//@run-rustfix
//@aux-build:option_helpers.rs
#![warn(clippy::iter_skip_next)]
#![allow(clippy::disallowed_names)]
#![allow(clippy::iter_nth)]
#![allow(clippy::useless_vec)]
+#![allow(clippy::iter_out_of_bounds)]
#![allow(unused_mut, dead_code)]
extern crate option_helpers;
diff --git a/src/tools/clippy/tests/ui/iter_skip_next.rs b/src/tools/clippy/tests/ui/iter_skip_next.rs
index e44efdebc..6d96441ca 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next.rs
+++ b/src/tools/clippy/tests/ui/iter_skip_next.rs
@@ -1,10 +1,10 @@
-//@run-rustfix
//@aux-build:option_helpers.rs
#![warn(clippy::iter_skip_next)]
#![allow(clippy::disallowed_names)]
#![allow(clippy::iter_nth)]
#![allow(clippy::useless_vec)]
+#![allow(clippy::iter_out_of_bounds)]
#![allow(unused_mut, dead_code)]
extern crate option_helpers;
diff --git a/src/tools/clippy/tests/ui/iter_skip_next.stderr b/src/tools/clippy/tests/ui/iter_skip_next.stderr
index 4ee26e088..39b173e75 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next.stderr
+++ b/src/tools/clippy/tests/ui/iter_skip_next.stderr
@@ -5,6 +5,7 @@ LL | let _ = some_vec.iter().skip(42).next();
| ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)`
|
= note: `-D clippy::iter-skip-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_skip_next)]`
error: called `skip(..).next()` on an iterator
--> $DIR/iter_skip_next.rs:18:36
diff --git a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.rs b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.rs
index 3607330cf..6c98bdc8c 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.rs
+++ b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.rs
@@ -1,19 +1,22 @@
#![warn(clippy::iter_skip_next)]
-#![allow(dead_code)]
-
+#![allow(dead_code, clippy::iter_out_of_bounds)]
+//@no-rustfix
/// Checks implementation of `ITER_SKIP_NEXT` lint
fn main() {
// fix #8128
let test_string = "1|1 2";
let sp = test_string.split('|').map(|s| s.trim());
let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect();
+ //~^ ERROR: called `skip(..).next()` on an iterator
if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) {
let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();
+ //~^ ERROR: called `skip(..).next()` on an iterator
};
fn check<T>(s: T)
where
T: Iterator<Item = String>,
{
let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();
+ //~^ ERROR: called `skip(..).next()` on an iterator
}
}
diff --git a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr
index 4062706f9..09a467793 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr
@@ -10,27 +10,28 @@ help: for this change `sp` has to be mutable
LL | let sp = test_string.split('|').map(|s| s.trim());
| ^^
= note: `-D clippy::iter-skip-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_skip_next)]`
error: called `skip(..).next()` on an iterator
- --> $DIR/iter_skip_next_unfixable.rs:11:29
+ --> $DIR/iter_skip_next_unfixable.rs:12:29
|
LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();
| ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`
|
help: for this change `s` has to be mutable
- --> $DIR/iter_skip_next_unfixable.rs:10:17
+ --> $DIR/iter_skip_next_unfixable.rs:11:17
|
LL | if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) {
| ^
error: called `skip(..).next()` on an iterator
- --> $DIR/iter_skip_next_unfixable.rs:17:29
+ --> $DIR/iter_skip_next_unfixable.rs:19:29
|
LL | let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();
| ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`
|
help: for this change `s` has to be mutable
- --> $DIR/iter_skip_next_unfixable.rs:13:17
+ --> $DIR/iter_skip_next_unfixable.rs:15:17
|
LL | fn check<T>(s: T)
| ^
diff --git a/src/tools/clippy/tests/ui/iter_skip_zero.fixed b/src/tools/clippy/tests/ui/iter_skip_zero.fixed
index 1eb0984fe..447d07100 100644
--- a/src/tools/clippy/tests/ui/iter_skip_zero.fixed
+++ b/src/tools/clippy/tests/ui/iter_skip_zero.fixed
@@ -1,6 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
-#![allow(clippy::useless_vec, unused)]
+//@aux-build:proc_macros.rs
+#![allow(clippy::useless_vec, clippy::iter_out_of_bounds, unused)]
#![warn(clippy::iter_skip_zero)]
#[macro_use]
diff --git a/src/tools/clippy/tests/ui/iter_skip_zero.rs b/src/tools/clippy/tests/ui/iter_skip_zero.rs
index 8c103ab1d..ba63c3981 100644
--- a/src/tools/clippy/tests/ui/iter_skip_zero.rs
+++ b/src/tools/clippy/tests/ui/iter_skip_zero.rs
@@ -1,6 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
-#![allow(clippy::useless_vec, unused)]
+//@aux-build:proc_macros.rs
+#![allow(clippy::useless_vec, clippy::iter_out_of_bounds, unused)]
#![warn(clippy::iter_skip_zero)]
#[macro_use]
diff --git a/src/tools/clippy/tests/ui/iter_skip_zero.stderr b/src/tools/clippy/tests/ui/iter_skip_zero.stderr
index 80fecd59e..6b8b3b105 100644
--- a/src/tools/clippy/tests/ui/iter_skip_zero.stderr
+++ b/src/tools/clippy/tests/ui/iter_skip_zero.stderr
@@ -1,14 +1,15 @@
error: usage of `.skip(0)`
- --> $DIR/iter_skip_zero.rs:12:35
+ --> $DIR/iter_skip_zero.rs:11:35
|
LL | let _ = [1, 2, 3].iter().skip(0);
| ^ help: if you meant to skip the first element, use: `1`
|
= note: this call to `skip` does nothing and is useless; remove it
= note: `-D clippy::iter-skip-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_skip_zero)]`
error: usage of `.skip(0)`
- --> $DIR/iter_skip_zero.rs:13:39
+ --> $DIR/iter_skip_zero.rs:12:39
|
LL | let _ = vec![1, 2, 3].iter().skip(0);
| ^ help: if you meant to skip the first element, use: `1`
@@ -16,7 +17,7 @@ LL | let _ = vec![1, 2, 3].iter().skip(0);
= note: this call to `skip` does nothing and is useless; remove it
error: usage of `.skip(0)`
- --> $DIR/iter_skip_zero.rs:14:34
+ --> $DIR/iter_skip_zero.rs:13:34
|
LL | let _ = once([1, 2, 3]).skip(0);
| ^ help: if you meant to skip the first element, use: `1`
@@ -24,7 +25,7 @@ LL | let _ = once([1, 2, 3]).skip(0);
= note: this call to `skip` does nothing and is useless; remove it
error: usage of `.skip(0)`
- --> $DIR/iter_skip_zero.rs:15:71
+ --> $DIR/iter_skip_zero.rs:14:71
|
LL | let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0);
| ^ help: if you meant to skip the first element, use: `1`
@@ -32,7 +33,7 @@ LL | let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0);
= note: this call to `skip` does nothing and is useless; remove it
error: usage of `.skip(0)`
- --> $DIR/iter_skip_zero.rs:15:62
+ --> $DIR/iter_skip_zero.rs:14:62
|
LL | let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0);
| ^ help: if you meant to skip the first element, use: `1`
diff --git a/src/tools/clippy/tests/ui/iter_with_drain.fixed b/src/tools/clippy/tests/ui/iter_with_drain.fixed
index 7a8c67701..a03efceed 100644
--- a/src/tools/clippy/tests/ui/iter_with_drain.fixed
+++ b/src/tools/clippy/tests/ui/iter_with_drain.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
// will emits unused mut warnings after fixing
#![allow(unused_mut)]
// will emits needless collect warnings after fixing
diff --git a/src/tools/clippy/tests/ui/iter_with_drain.rs b/src/tools/clippy/tests/ui/iter_with_drain.rs
index cf3a935c3..a8cd47f83 100644
--- a/src/tools/clippy/tests/ui/iter_with_drain.rs
+++ b/src/tools/clippy/tests/ui/iter_with_drain.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
// will emits unused mut warnings after fixing
#![allow(unused_mut)]
// will emits needless collect warnings after fixing
diff --git a/src/tools/clippy/tests/ui/iter_with_drain.stderr b/src/tools/clippy/tests/ui/iter_with_drain.stderr
index bfaed29a0..ac04f9396 100644
--- a/src/tools/clippy/tests/ui/iter_with_drain.stderr
+++ b/src/tools/clippy/tests/ui/iter_with_drain.stderr
@@ -1,37 +1,38 @@
error: `drain(..)` used on a `Vec`
- --> $DIR/iter_with_drain.rs:11:34
+ --> $DIR/iter_with_drain.rs:10:34
|
LL | let mut a: BinaryHeap<_> = a.drain(..).collect();
| ^^^^^^^^^ help: try: `into_iter()`
|
= note: `-D clippy::iter-with-drain` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iter_with_drain)]`
error: `drain(..)` used on a `VecDeque`
- --> $DIR/iter_with_drain.rs:14:27
+ --> $DIR/iter_with_drain.rs:13:27
|
LL | let mut a: Vec<_> = a.drain(..).collect();
| ^^^^^^^^^ help: try: `into_iter()`
error: `drain(..)` used on a `Vec`
- --> $DIR/iter_with_drain.rs:15:34
+ --> $DIR/iter_with_drain.rs:14:34
|
LL | let mut a: HashMap<_, _> = a.drain(..).map(|x| (x.clone(), x)).collect();
| ^^^^^^^^^ help: try: `into_iter()`
error: `drain(..)` used on a `Vec`
- --> $DIR/iter_with_drain.rs:21:34
+ --> $DIR/iter_with_drain.rs:20:34
|
LL | let mut a: BinaryHeap<_> = a.drain(0..).collect();
| ^^^^^^^^^^ help: try: `into_iter()`
error: `drain(..)` used on a `VecDeque`
- --> $DIR/iter_with_drain.rs:24:27
+ --> $DIR/iter_with_drain.rs:23:27
|
LL | let mut a: Vec<_> = a.drain(..a.len()).collect();
| ^^^^^^^^^^^^^^^^ help: try: `into_iter()`
error: `drain(..)` used on a `Vec`
- --> $DIR/iter_with_drain.rs:25:34
+ --> $DIR/iter_with_drain.rs:24:34
|
LL | let mut a: HashMap<_, _> = a.drain(0..a.len()).map(|x| (x.clone(), x)).collect();
| ^^^^^^^^^^^^^^^^^ help: try: `into_iter()`
diff --git a/src/tools/clippy/tests/ui/iterator_step_by_zero.rs b/src/tools/clippy/tests/ui/iterator_step_by_zero.rs
index 33ec78e9a..0b51842df 100644
--- a/src/tools/clippy/tests/ui/iterator_step_by_zero.rs
+++ b/src/tools/clippy/tests/ui/iterator_step_by_zero.rs
@@ -2,8 +2,12 @@
#[warn(clippy::iterator_step_by_zero)]
fn main() {
let _ = vec!["A", "B", "B"].iter().step_by(0);
+ //~^ ERROR: `Iterator::step_by(0)` will panic at runtime
+ //~| NOTE: `-D clippy::iterator-step-by-zero` implied by `-D warnings`
let _ = "XXX".chars().step_by(0);
+ //~^ ERROR: `Iterator::step_by(0)` will panic at runtime
let _ = (0..1).step_by(0);
+ //~^ ERROR: `Iterator::step_by(0)` will panic at runtime
// No error, not an iterator.
let y = NotIterator;
@@ -13,14 +17,18 @@ fn main() {
let _ = (0..1).step_by(1);
let _ = (1..).step_by(0);
+ //~^ ERROR: `Iterator::step_by(0)` will panic at runtime
let _ = (1..=2).step_by(0);
+ //~^ ERROR: `Iterator::step_by(0)` will panic at runtime
let x = 0..1;
let _ = x.step_by(0);
+ //~^ ERROR: `Iterator::step_by(0)` will panic at runtime
// check const eval
let v1 = vec![1, 2, 3];
let _ = v1.iter().step_by(2 / 3);
+ //~^ ERROR: `Iterator::step_by(0)` will panic at runtime
}
struct NotIterator;
diff --git a/src/tools/clippy/tests/ui/iterator_step_by_zero.stderr b/src/tools/clippy/tests/ui/iterator_step_by_zero.stderr
index b470e2ed2..20ea29322 100644
--- a/src/tools/clippy/tests/ui/iterator_step_by_zero.stderr
+++ b/src/tools/clippy/tests/ui/iterator_step_by_zero.stderr
@@ -5,39 +5,40 @@ LL | let _ = vec!["A", "B", "B"].iter().step_by(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::iterator-step-by-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::iterator_step_by_zero)]`
error: `Iterator::step_by(0)` will panic at runtime
- --> $DIR/iterator_step_by_zero.rs:5:13
+ --> $DIR/iterator_step_by_zero.rs:7:13
|
LL | let _ = "XXX".chars().step_by(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: `Iterator::step_by(0)` will panic at runtime
- --> $DIR/iterator_step_by_zero.rs:6:13
+ --> $DIR/iterator_step_by_zero.rs:9:13
|
LL | let _ = (0..1).step_by(0);
| ^^^^^^^^^^^^^^^^^
error: `Iterator::step_by(0)` will panic at runtime
- --> $DIR/iterator_step_by_zero.rs:15:13
+ --> $DIR/iterator_step_by_zero.rs:19:13
|
LL | let _ = (1..).step_by(0);
| ^^^^^^^^^^^^^^^^
error: `Iterator::step_by(0)` will panic at runtime
- --> $DIR/iterator_step_by_zero.rs:16:13
+ --> $DIR/iterator_step_by_zero.rs:21:13
|
LL | let _ = (1..=2).step_by(0);
| ^^^^^^^^^^^^^^^^^^
error: `Iterator::step_by(0)` will panic at runtime
- --> $DIR/iterator_step_by_zero.rs:19:13
+ --> $DIR/iterator_step_by_zero.rs:25:13
|
LL | let _ = x.step_by(0);
| ^^^^^^^^^^^^
error: `Iterator::step_by(0)` will panic at runtime
- --> $DIR/iterator_step_by_zero.rs:23:13
+ --> $DIR/iterator_step_by_zero.rs:30:13
|
LL | let _ = v1.iter().step_by(2 / 3);
| ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/large_const_arrays.fixed b/src/tools/clippy/tests/ui/large_const_arrays.fixed
index f7ce6fbe6..6011bb99d 100644
--- a/src/tools/clippy/tests/ui/large_const_arrays.fixed
+++ b/src/tools/clippy/tests/ui/large_const_arrays.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::large_const_arrays)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/large_const_arrays.rs b/src/tools/clippy/tests/ui/large_const_arrays.rs
index 002ac77dd..a78425d7b 100644
--- a/src/tools/clippy/tests/ui/large_const_arrays.rs
+++ b/src/tools/clippy/tests/ui/large_const_arrays.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::large_const_arrays)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/large_const_arrays.stderr b/src/tools/clippy/tests/ui/large_const_arrays.stderr
index 3fb0acbca..e522550ff 100644
--- a/src/tools/clippy/tests/ui/large_const_arrays.stderr
+++ b/src/tools/clippy/tests/ui/large_const_arrays.stderr
@@ -1,5 +1,5 @@
error: large array defined as const
- --> $DIR/large_const_arrays.rs:12:1
+ --> $DIR/large_const_arrays.rs:10:1
|
LL | pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];
| ^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,9 +7,10 @@ LL | pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];
| help: make this a static item: `static`
|
= note: `-D clippy::large-const-arrays` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_const_arrays)]`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:13:1
+ --> $DIR/large_const_arrays.rs:11:1
|
LL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +18,7 @@ LL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
| help: make this a static item: `static`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:14:1
+ --> $DIR/large_const_arrays.rs:12:1
|
LL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000];
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +26,7 @@ LL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000];
| help: make this a static item: `static`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:23:5
+ --> $DIR/large_const_arrays.rs:21:5
|
LL | pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +34,7 @@ LL | pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
| help: make this a static item: `static`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:24:5
+ --> $DIR/large_const_arrays.rs:22:5
|
LL | const BAR: [u32; 1_000_000] = [0u32; 1_000_000];
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +42,7 @@ LL | const BAR: [u32; 1_000_000] = [0u32; 1_000_000];
| help: make this a static item: `static`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:25:5
+ --> $DIR/large_const_arrays.rs:23:5
|
LL | pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +50,7 @@ LL | pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];
| help: make this a static item: `static`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:26:5
+ --> $DIR/large_const_arrays.rs:24:5
|
LL | const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -57,7 +58,7 @@ LL | const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];
| help: make this a static item: `static`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:27:5
+ --> $DIR/large_const_arrays.rs:25:5
|
LL | pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000];
| ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -65,7 +66,7 @@ LL | pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000];
| help: make this a static item: `static`
error: large array defined as const
- --> $DIR/large_const_arrays.rs:28:5
+ --> $DIR/large_const_arrays.rs:26:5
|
LL | const BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000];
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/large_digit_groups.fixed b/src/tools/clippy/tests/ui/large_digit_groups.fixed
index f42fcd96d..cdb001e47 100644
--- a/src/tools/clippy/tests/ui/large_digit_groups.fixed
+++ b/src/tools/clippy/tests/ui/large_digit_groups.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::large_digit_groups)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/large_digit_groups.rs b/src/tools/clippy/tests/ui/large_digit_groups.rs
index 3db9da6a3..3c30c8670 100644
--- a/src/tools/clippy/tests/ui/large_digit_groups.rs
+++ b/src/tools/clippy/tests/ui/large_digit_groups.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::large_digit_groups)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/large_digit_groups.stderr b/src/tools/clippy/tests/ui/large_digit_groups.stderr
index 19c0fae98..e5f37a6cc 100644
--- a/src/tools/clippy/tests/ui/large_digit_groups.stderr
+++ b/src/tools/clippy/tests/ui/large_digit_groups.stderr
@@ -1,33 +1,35 @@
error: digits of hex, binary or octal literal not in groups of equal size
- --> $DIR/large_digit_groups.rs:23:9
+ --> $DIR/large_digit_groups.rs:22:9
|
LL | 0xd_e_adbee_f_usize,
| ^^^^^^^^^^^^^^^^^^^ help: consider: `0xdead_beef_usize`
|
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]`
error: digit groups should be smaller
- --> $DIR/large_digit_groups.rs:24:9
+ --> $DIR/large_digit_groups.rs:23:9
|
LL | 1_23456_f32,
| ^^^^^^^^^^^ help: consider: `123_456_f32`
|
= note: `-D clippy::large-digit-groups` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_digit_groups)]`
error: digit groups should be smaller
- --> $DIR/large_digit_groups.rs:25:9
+ --> $DIR/large_digit_groups.rs:24:9
|
LL | 1_23456.12_f32,
| ^^^^^^^^^^^^^^ help: consider: `123_456.12_f32`
error: digit groups should be smaller
- --> $DIR/large_digit_groups.rs:26:9
+ --> $DIR/large_digit_groups.rs:25:9
|
LL | 1_23456.12345_f64,
| ^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_45_f64`
error: digit groups should be smaller
- --> $DIR/large_digit_groups.rs:27:9
+ --> $DIR/large_digit_groups.rs:26:9
|
LL | 1_23456.12345_6_f64,
| ^^^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_456_f64`
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr b/src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr
new file mode 100644
index 000000000..0e0eee21c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr
@@ -0,0 +1,280 @@
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:11:1
+ |
+LL | / enum LargeEnum {
+LL | | A(i32),
+ | | ------ the second-largest variant contains at least 4 bytes
+LL | | B([i32; 8000]),
+ | | -------------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
+ |
+ = note: `-D clippy::large-enum-variant` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | B(Box<[i32; 8000]>),
+ | ~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:35:1
+ |
+LL | / enum LargeEnum2 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | ContainingLargeEnum(LargeEnum),
+ | | ------------------------------ the largest variant contains at least 32004 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | ContainingLargeEnum(Box<LargeEnum>),
+ | ~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:40:1
+ |
+LL | / enum LargeEnum3 {
+LL | | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
+ | | --------------------------------------------------------- the largest variant contains at least 70004 bytes
+LL | | VoidVariant,
+LL | | StructLikeLittle { x: i32, y: i32 },
+ | | ----------------------------------- the second-largest variant contains at least 8 bytes
+LL | | }
+ | |_^ the entire enum is at least 70008 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
+ | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:46:1
+ |
+LL | / enum LargeEnum4 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | StructLikeLarge { x: [i32; 8000], y: i32 },
+ | | ------------------------------------------ the largest variant contains at least 32004 bytes
+LL | | }
+ | |_^ the entire enum is at least 32008 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
+ | ~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:51:1
+ |
+LL | / enum LargeEnum5 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | StructLikeLarge2 { x: [i32; 8000] },
+ | | ----------------------------------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | StructLikeLarge2 { x: Box<[i32; 8000]> },
+ | ~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:67:1
+ |
+LL | / enum LargeEnum7 {
+LL | | A,
+LL | | B([u8; 1255]),
+ | | ------------- the largest variant contains at least 1255 bytes
+LL | | C([u8; 200]),
+ | | ------------ the second-largest variant contains at least 200 bytes
+LL | | }
+ | |_^ the entire enum is at least 1256 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | B(Box<[u8; 1255]>),
+ | ~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:73:1
+ |
+LL | / enum LargeEnum8 {
+LL | | VariantOk(i32, u32),
+ | | ------------------- the second-largest variant contains at least 8 bytes
+LL | | ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
+ | | ------------------------------------------------------------------------- the largest variant contains at least 70128 bytes
+LL | | }
+ | |_^ the entire enum is at least 70132 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
+ | ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:78:1
+ |
+LL | / enum LargeEnum9 {
+LL | | A(Struct<()>),
+ | | ------------- the second-largest variant contains at least 4 bytes
+LL | | B(Struct2),
+ | | ---------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | B(Box<Struct2>),
+ | ~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:83:1
+ |
+LL | / enum LargeEnumOk2<T> {
+LL | | A(T),
+ | | ---- the second-largest variant contains at least 0 bytes
+LL | | B(Struct2),
+ | | ---------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32000 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | B(Box<Struct2>),
+ | ~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:88:1
+ |
+LL | / enum LargeEnumOk3<T> {
+LL | | A(Struct<T>),
+ | | ------------ the second-largest variant contains at least 4 bytes
+LL | | B(Struct2),
+ | | ---------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32000 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | B(Box<Struct2>),
+ | ~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:103:1
+ |
+LL | / enum CopyableLargeEnum {
+LL | | A(bool),
+ | | ------- the second-largest variant contains at least 1 bytes
+LL | | B([u64; 8000]),
+ | | -------------- the largest variant contains at least 64000 bytes
+LL | | }
+ | |_^ the entire enum is at least 64004 bytes
+ |
+note: boxing a variant would require the type no longer be `Copy`
+ --> $DIR/large_enum_variant.rs:103:6
+ |
+LL | enum CopyableLargeEnum {
+ | ^^^^^^^^^^^^^^^^^
+help: consider boxing the large fields to reduce the total size of the enum
+ --> $DIR/large_enum_variant.rs:105:5
+ |
+LL | B([u64; 8000]),
+ | ^^^^^^^^^^^^^^
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:108:1
+ |
+LL | / enum ManuallyCopyLargeEnum {
+LL | | A(bool),
+ | | ------- the second-largest variant contains at least 1 bytes
+LL | | B([u64; 8000]),
+ | | -------------- the largest variant contains at least 64000 bytes
+LL | | }
+ | |_^ the entire enum is at least 64004 bytes
+ |
+note: boxing a variant would require the type no longer be `Copy`
+ --> $DIR/large_enum_variant.rs:108:6
+ |
+LL | enum ManuallyCopyLargeEnum {
+ | ^^^^^^^^^^^^^^^^^^^^^
+help: consider boxing the large fields to reduce the total size of the enum
+ --> $DIR/large_enum_variant.rs:110:5
+ |
+LL | B([u64; 8000]),
+ | ^^^^^^^^^^^^^^
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:121:1
+ |
+LL | / enum SomeGenericPossiblyCopyEnum<T> {
+LL | | A(bool, std::marker::PhantomData<T>),
+ | | ------------------------------------ the second-largest variant contains at least 1 bytes
+LL | | B([u64; 4000]),
+ | | -------------- the largest variant contains at least 32000 bytes
+LL | | }
+ | |_^ the entire enum is at least 32004 bytes
+ |
+note: boxing a variant would require the type no longer be `Copy`
+ --> $DIR/large_enum_variant.rs:121:6
+ |
+LL | enum SomeGenericPossiblyCopyEnum<T> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider boxing the large fields to reduce the total size of the enum
+ --> $DIR/large_enum_variant.rs:123:5
+ |
+LL | B([u64; 4000]),
+ | ^^^^^^^^^^^^^^
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:134:1
+ |
+LL | / enum LargeEnumWithGenerics<T> {
+LL | | Small,
+ | | ----- the second-largest variant carries no data at all
+LL | | Large((T, [u8; 512])),
+ | | --------------------- the largest variant contains at least 512 bytes
+LL | | }
+ | |_^ the entire enum is at least 512 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | Large(Box<(T, [u8; 512])>),
+ | ~~~~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:143:1
+ |
+LL | / enum WithGenerics {
+LL | | Large([Foo<u64>; 64]),
+ | | --------------------- the largest variant contains at least 512 bytes
+LL | | Small(u8),
+ | | --------- the second-largest variant contains at least 1 bytes
+LL | | }
+ | |_^ the entire enum is at least 516 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | Large(Box<[Foo<u64>; 64]>),
+ | ~~~~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+ --> $DIR/large_enum_variant.rs:153:1
+ |
+LL | / enum LargeEnumOfConst {
+LL | | Ok,
+ | | -- the second-largest variant carries no data at all
+LL | | Error(PossiblyLargeEnumWithConst<256>),
+ | | -------------------------------------- the largest variant contains at least 514 bytes
+LL | | }
+ | |_^ the entire enum is at least 514 bytes
+ |
+help: consider boxing the large fields to reduce the total size of the enum
+ |
+LL | Error(Box<PossiblyLargeEnumWithConst<256>>),
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 16 previous errors
+
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.stderr b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
index 709972b4a..3eba43e05 100644
--- a/src/tools/clippy/tests/ui/large_enum_variant.stderr
+++ b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
@@ -1,5 +1,5 @@
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:10:1
+ --> $DIR/large_enum_variant.rs:11:1
|
LL | / enum LargeEnum {
LL | | A(i32),
@@ -10,13 +10,14 @@ LL | | }
| |_^ the entire enum is at least 32004 bytes
|
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
help: consider boxing the large fields to reduce the total size of the enum
|
LL | B(Box<[i32; 8000]>),
| ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:34:1
+ --> $DIR/large_enum_variant.rs:35:1
|
LL | / enum LargeEnum2 {
LL | | VariantOk(i32, u32),
@@ -32,7 +33,7 @@ LL | ContainingLargeEnum(Box<LargeEnum>),
| ~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:39:1
+ --> $DIR/large_enum_variant.rs:40:1
|
LL | / enum LargeEnum3 {
LL | | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
@@ -49,7 +50,7 @@ LL | ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:45:1
+ --> $DIR/large_enum_variant.rs:46:1
|
LL | / enum LargeEnum4 {
LL | | VariantOk(i32, u32),
@@ -65,7 +66,7 @@ LL | StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
| ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:50:1
+ --> $DIR/large_enum_variant.rs:51:1
|
LL | / enum LargeEnum5 {
LL | | VariantOk(i32, u32),
@@ -81,7 +82,7 @@ LL | StructLikeLarge2 { x: Box<[i32; 8000]> },
| ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:66:1
+ --> $DIR/large_enum_variant.rs:67:1
|
LL | / enum LargeEnum7 {
LL | | A,
@@ -98,7 +99,7 @@ LL | B(Box<[u8; 1255]>),
| ~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:72:1
+ --> $DIR/large_enum_variant.rs:73:1
|
LL | / enum LargeEnum8 {
LL | | VariantOk(i32, u32),
@@ -114,7 +115,7 @@ LL | ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>
| ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:77:1
+ --> $DIR/large_enum_variant.rs:78:1
|
LL | / enum LargeEnum9 {
LL | | A(Struct<()>),
@@ -130,7 +131,7 @@ LL | B(Box<Struct2>),
| ~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:82:1
+ --> $DIR/large_enum_variant.rs:83:1
|
LL | / enum LargeEnumOk2<T> {
LL | | A(T),
@@ -146,7 +147,7 @@ LL | B(Box<Struct2>),
| ~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:87:1
+ --> $DIR/large_enum_variant.rs:88:1
|
LL | / enum LargeEnumOk3<T> {
LL | | A(Struct<T>),
@@ -162,7 +163,7 @@ LL | B(Box<Struct2>),
| ~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:102:1
+ --> $DIR/large_enum_variant.rs:103:1
|
LL | / enum CopyableLargeEnum {
LL | | A(bool),
@@ -173,18 +174,18 @@ LL | | }
| |_^ the entire enum is at least 64008 bytes
|
note: boxing a variant would require the type no longer be `Copy`
- --> $DIR/large_enum_variant.rs:102:6
+ --> $DIR/large_enum_variant.rs:103:6
|
LL | enum CopyableLargeEnum {
| ^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
- --> $DIR/large_enum_variant.rs:104:5
+ --> $DIR/large_enum_variant.rs:105:5
|
LL | B([u64; 8000]),
| ^^^^^^^^^^^^^^
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:107:1
+ --> $DIR/large_enum_variant.rs:108:1
|
LL | / enum ManuallyCopyLargeEnum {
LL | | A(bool),
@@ -195,18 +196,18 @@ LL | | }
| |_^ the entire enum is at least 64008 bytes
|
note: boxing a variant would require the type no longer be `Copy`
- --> $DIR/large_enum_variant.rs:107:6
+ --> $DIR/large_enum_variant.rs:108:6
|
LL | enum ManuallyCopyLargeEnum {
| ^^^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
- --> $DIR/large_enum_variant.rs:109:5
+ --> $DIR/large_enum_variant.rs:110:5
|
LL | B([u64; 8000]),
| ^^^^^^^^^^^^^^
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:120:1
+ --> $DIR/large_enum_variant.rs:121:1
|
LL | / enum SomeGenericPossiblyCopyEnum<T> {
LL | | A(bool, std::marker::PhantomData<T>),
@@ -217,18 +218,18 @@ LL | | }
| |_^ the entire enum is at least 32008 bytes
|
note: boxing a variant would require the type no longer be `Copy`
- --> $DIR/large_enum_variant.rs:120:6
+ --> $DIR/large_enum_variant.rs:121:6
|
LL | enum SomeGenericPossiblyCopyEnum<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider boxing the large fields to reduce the total size of the enum
- --> $DIR/large_enum_variant.rs:122:5
+ --> $DIR/large_enum_variant.rs:123:5
|
LL | B([u64; 4000]),
| ^^^^^^^^^^^^^^
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:133:1
+ --> $DIR/large_enum_variant.rs:134:1
|
LL | / enum LargeEnumWithGenerics<T> {
LL | | Small,
@@ -244,7 +245,7 @@ LL | Large(Box<(T, [u8; 512])>),
| ~~~~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:142:1
+ --> $DIR/large_enum_variant.rs:143:1
|
LL | / enum WithGenerics {
LL | | Large([Foo<u64>; 64]),
@@ -260,7 +261,7 @@ LL | Large(Box<[Foo<u64>; 64]>),
| ~~~~~~~~~~~~~~~~~~~
error: large size difference between variants
- --> $DIR/large_enum_variant.rs:152:1
+ --> $DIR/large_enum_variant.rs:153:1
|
LL | / enum LargeEnumOfConst {
LL | | Ok,
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.rs b/src/tools/clippy/tests/ui/large_enum_variant.rs
index e677cc9a7..3625c011d 100644
--- a/src/tools/clippy/tests/ui/large_enum_variant.rs
+++ b/src/tools/clippy/tests/ui/large_enum_variant.rs
@@ -1,5 +1,6 @@
-//@aux-build:proc_macros.rs:proc-macro
-
+//@stderr-per-bitwidth
+//@aux-build:proc_macros.rs
+//@no-rustfix
#![allow(dead_code)]
#![allow(unused_variables)]
#![warn(clippy::large_enum_variant)]
diff --git a/src/tools/clippy/tests/ui/large_futures.fixed b/src/tools/clippy/tests/ui/large_futures.fixed
new file mode 100644
index 000000000..4c192d1c8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/large_futures.fixed
@@ -0,0 +1,70 @@
+#![feature(generators)]
+#![warn(clippy::large_futures)]
+#![allow(clippy::never_loop)]
+#![allow(clippy::future_not_send)]
+#![allow(clippy::manual_async_fn)]
+
+async fn big_fut(_arg: [u8; 1024 * 16]) {}
+
+async fn wait() {
+ let f = async {
+ Box::pin(big_fut([0u8; 1024 * 16])).await;
+ //~^ ERROR: large future with a size of 16385 bytes
+ //~| NOTE: `-D clippy::large-futures` implied by `-D warnings`
+ };
+ Box::pin(f).await
+ //~^ ERROR: large future with a size of 16386 bytes
+}
+async fn calls_fut(fut: impl std::future::Future<Output = ()>) {
+ loop {
+ Box::pin(wait()).await;
+ //~^ ERROR: large future with a size of 16387 bytes
+ if true {
+ return fut.await;
+ } else {
+ Box::pin(wait()).await;
+ //~^ ERROR: large future with a size of 16387 bytes
+ }
+ }
+}
+
+pub async fn test() {
+ let fut = big_fut([0u8; 1024 * 16]);
+ Box::pin(foo()).await;
+ //~^ ERROR: large future with a size of 65540 bytes
+ Box::pin(calls_fut(fut)).await;
+ //~^ ERROR: large future with a size of 49159 bytes
+}
+
+pub fn foo() -> impl std::future::Future<Output = ()> {
+ async {
+ let x = [0i32; 1024 * 16];
+ async {}.await;
+ dbg!(x);
+ }
+}
+
+pub async fn lines() {
+ Box::pin(async {
+ //~^ ERROR: large future with a size of 65540 bytes
+ let x = [0i32; 1024 * 16];
+ async {}.await;
+ println!("{:?}", x);
+ })
+ .await;
+}
+
+pub async fn macro_expn() {
+ macro_rules! macro_ {
+ () => {
+ Box::pin(async {
+ let x = [0i32; 1024 * 16];
+ async {}.await;
+ println!("macro: {:?}", x);
+ })
+ };
+ }
+ macro_!().await
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/large_futures.rs b/src/tools/clippy/tests/ui/large_futures.rs
index e0f6b3d9d..557d89a9c 100644
--- a/src/tools/clippy/tests/ui/large_futures.rs
+++ b/src/tools/clippy/tests/ui/large_futures.rs
@@ -9,16 +9,21 @@ async fn big_fut(_arg: [u8; 1024 * 16]) {}
async fn wait() {
let f = async {
big_fut([0u8; 1024 * 16]).await;
+ //~^ ERROR: large future with a size of 16385 bytes
+ //~| NOTE: `-D clippy::large-futures` implied by `-D warnings`
};
f.await
+ //~^ ERROR: large future with a size of 16386 bytes
}
async fn calls_fut(fut: impl std::future::Future<Output = ()>) {
loop {
wait().await;
+ //~^ ERROR: large future with a size of 16387 bytes
if true {
return fut.await;
} else {
wait().await;
+ //~^ ERROR: large future with a size of 16387 bytes
}
}
}
@@ -26,7 +31,9 @@ async fn calls_fut(fut: impl std::future::Future<Output = ()>) {
pub async fn test() {
let fut = big_fut([0u8; 1024 * 16]);
foo().await;
+ //~^ ERROR: large future with a size of 65540 bytes
calls_fut(fut).await;
+ //~^ ERROR: large future with a size of 49159 bytes
}
pub fn foo() -> impl std::future::Future<Output = ()> {
@@ -39,6 +46,7 @@ pub fn foo() -> impl std::future::Future<Output = ()> {
pub async fn lines() {
async {
+ //~^ ERROR: large future with a size of 65540 bytes
let x = [0i32; 1024 * 16];
async {}.await;
println!("{:?}", x);
diff --git a/src/tools/clippy/tests/ui/large_futures.stderr b/src/tools/clippy/tests/ui/large_futures.stderr
index 5bcf05488..861366daf 100644
--- a/src/tools/clippy/tests/ui/large_futures.stderr
+++ b/src/tools/clippy/tests/ui/large_futures.stderr
@@ -5,41 +5,43 @@ LL | big_fut([0u8; 1024 * 16]).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(big_fut([0u8; 1024 * 16]))`
|
= note: `-D clippy::large-futures` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_futures)]`
error: large future with a size of 16386 bytes
- --> $DIR/large_futures.rs:13:5
+ --> $DIR/large_futures.rs:15:5
|
LL | f.await
| ^ help: consider `Box::pin` on it: `Box::pin(f)`
error: large future with a size of 16387 bytes
- --> $DIR/large_futures.rs:17:9
+ --> $DIR/large_futures.rs:20:9
|
LL | wait().await;
| ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())`
error: large future with a size of 16387 bytes
- --> $DIR/large_futures.rs:21:13
+ --> $DIR/large_futures.rs:25:13
|
LL | wait().await;
| ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())`
error: large future with a size of 65540 bytes
- --> $DIR/large_futures.rs:28:5
+ --> $DIR/large_futures.rs:33:5
|
LL | foo().await;
| ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())`
error: large future with a size of 49159 bytes
- --> $DIR/large_futures.rs:29:5
+ --> $DIR/large_futures.rs:35:5
|
LL | calls_fut(fut).await;
| ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))`
error: large future with a size of 65540 bytes
- --> $DIR/large_futures.rs:41:5
+ --> $DIR/large_futures.rs:48:5
|
LL | / async {
+LL | |
LL | | let x = [0i32; 1024 * 16];
LL | | async {}.await;
LL | | println!("{:?}", x);
@@ -49,6 +51,7 @@ LL | | }
help: consider `Box::pin` on it
|
LL ~ Box::pin(async {
+LL +
LL + let x = [0i32; 1024 * 16];
LL + async {}.await;
LL + println!("{:?}", x);
@@ -56,7 +59,7 @@ LL + })
|
error: large future with a size of 65540 bytes
- --> $DIR/large_futures.rs:52:13
+ --> $DIR/large_futures.rs:60:13
|
LL | / async {
LL | | let x = [0i32; 1024 * 16];
diff --git a/src/tools/clippy/tests/ui/large_stack_arrays.rs b/src/tools/clippy/tests/ui/large_stack_arrays.rs
index 3e9d5e6a4..d5c4f95f8 100644
--- a/src/tools/clippy/tests/ui/large_stack_arrays.rs
+++ b/src/tools/clippy/tests/ui/large_stack_arrays.rs
@@ -27,17 +27,24 @@ fn issue_10741() {
}
let _x = [build(); 3];
+ //~^ ERROR: allocating a local array larger than 512000 bytes
let _y = [build(), build(), build()];
+ //~^ ERROR: allocating a local array larger than 512000 bytes
}
fn main() {
let bad = (
[0u32; 20_000_000],
+ //~^ ERROR: allocating a local array larger than 512000 bytes
[S { data: [0; 32] }; 5000],
+ //~^ ERROR: allocating a local array larger than 512000 bytes
[Some(""); 20_000_000],
+ //~^ ERROR: allocating a local array larger than 512000 bytes
[E::T(0); 5000],
+ //~^ ERROR: allocating a local array larger than 512000 bytes
[0u8; usize::MAX],
+ //~^ ERROR: allocating a local array larger than 512000 bytes
);
let good = (
diff --git a/src/tools/clippy/tests/ui/large_stack_arrays.stderr b/src/tools/clippy/tests/ui/large_stack_arrays.stderr
index 118d39566..0dfb6732b 100644
--- a/src/tools/clippy/tests/ui/large_stack_arrays.stderr
+++ b/src/tools/clippy/tests/ui/large_stack_arrays.stderr
@@ -6,9 +6,10 @@ LL | let _x = [build(); 3];
|
= help: consider allocating on the heap with `vec![build(); 3].into_boxed_slice()`
= note: `-D clippy::large-stack-arrays` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_stack_arrays)]`
error: allocating a local array larger than 512000 bytes
- --> $DIR/large_stack_arrays.rs:31:14
+ --> $DIR/large_stack_arrays.rs:32:14
|
LL | let _y = [build(), build(), build()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let _y = [build(), build(), build()];
= help: consider allocating on the heap with `vec![build(), build(), build()].into_boxed_slice()`
error: allocating a local array larger than 512000 bytes
- --> $DIR/large_stack_arrays.rs:36:9
+ --> $DIR/large_stack_arrays.rs:38:9
|
LL | [0u32; 20_000_000],
| ^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | [0u32; 20_000_000],
= help: consider allocating on the heap with `vec![0u32; 20_000_000].into_boxed_slice()`
error: allocating a local array larger than 512000 bytes
- --> $DIR/large_stack_arrays.rs:37:9
+ --> $DIR/large_stack_arrays.rs:40:9
|
LL | [S { data: [0; 32] }; 5000],
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | [S { data: [0; 32] }; 5000],
= help: consider allocating on the heap with `vec![S { data: [0; 32] }; 5000].into_boxed_slice()`
error: allocating a local array larger than 512000 bytes
- --> $DIR/large_stack_arrays.rs:38:9
+ --> $DIR/large_stack_arrays.rs:42:9
|
LL | [Some(""); 20_000_000],
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | [Some(""); 20_000_000],
= help: consider allocating on the heap with `vec![Some(""); 20_000_000].into_boxed_slice()`
error: allocating a local array larger than 512000 bytes
- --> $DIR/large_stack_arrays.rs:39:9
+ --> $DIR/large_stack_arrays.rs:44:9
|
LL | [E::T(0); 5000],
| ^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | [E::T(0); 5000],
= help: consider allocating on the heap with `vec![E::T(0); 5000].into_boxed_slice()`
error: allocating a local array larger than 512000 bytes
- --> $DIR/large_stack_arrays.rs:40:9
+ --> $DIR/large_stack_arrays.rs:46:9
|
LL | [0u8; usize::MAX],
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/large_stack_frames.rs b/src/tools/clippy/tests/ui/large_stack_frames.rs
index cd9d0c8a6..f32368f93 100644
--- a/src/tools/clippy/tests/ui/large_stack_frames.rs
+++ b/src/tools/clippy/tests/ui/large_stack_frames.rs
@@ -23,6 +23,8 @@ impl<const N: usize> Default for ArrayDefault<N> {
}
fn many_small_arrays() {
+ //~^ ERROR: this function allocates a large amount of stack space
+ //~| NOTE: allocating large amounts of stack space can overflow the stack
let x = [0u8; 500_000];
let x2 = [0u8; 500_000];
let x3 = [0u8; 500_000];
@@ -32,10 +34,14 @@ fn many_small_arrays() {
}
fn large_return_value() -> ArrayDefault<1_000_000> {
+ //~^ ERROR: this function allocates a large amount of stack space
+ //~| NOTE: allocating large amounts of stack space can overflow the stack
Default::default()
}
fn large_fn_arg(x: ArrayDefault<1_000_000>) {
+ //~^ ERROR: this function allocates a large amount of stack space
+ //~| NOTE: allocating large amounts of stack space can overflow the stack
black_box(&x);
}
diff --git a/src/tools/clippy/tests/ui/large_stack_frames.stderr b/src/tools/clippy/tests/ui/large_stack_frames.stderr
index d57df8596..12a458db8 100644
--- a/src/tools/clippy/tests/ui/large_stack_frames.stderr
+++ b/src/tools/clippy/tests/ui/large_stack_frames.stderr
@@ -2,9 +2,9 @@ error: this function allocates a large amount of stack space
--> $DIR/large_stack_frames.rs:25:1
|
LL | / fn many_small_arrays() {
+LL | |
+LL | |
LL | | let x = [0u8; 500_000];
-LL | | let x2 = [0u8; 500_000];
-LL | | let x3 = [0u8; 500_000];
... |
LL | | black_box((&x, &x2, &x3, &x4, &x5));
LL | | }
@@ -12,11 +12,14 @@ LL | | }
|
= note: allocating large amounts of stack space can overflow the stack
= note: `-D clippy::large-stack-frames` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
error: this function allocates a large amount of stack space
- --> $DIR/large_stack_frames.rs:34:1
+ --> $DIR/large_stack_frames.rs:36:1
|
LL | / fn large_return_value() -> ArrayDefault<1_000_000> {
+LL | |
+LL | |
LL | | Default::default()
LL | | }
| |_^
@@ -24,9 +27,11 @@ LL | | }
= note: allocating large amounts of stack space can overflow the stack
error: this function allocates a large amount of stack space
- --> $DIR/large_stack_frames.rs:38:1
+ --> $DIR/large_stack_frames.rs:42:1
|
LL | / fn large_fn_arg(x: ArrayDefault<1_000_000>) {
+LL | |
+LL | |
LL | | black_box(&x);
LL | | }
| |_^
diff --git a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
index f9e3c7192..78994a298 100644
--- a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
+++ b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
@@ -1,6 +1,6 @@
//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)"
//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)"
-
+//@no-rustfix
#![warn(clippy::large_types_passed_by_value)]
pub struct Large([u8; 2048]);
diff --git a/src/tools/clippy/tests/ui/large_types_passed_by_value.stderr b/src/tools/clippy/tests/ui/large_types_passed_by_value.stderr
index 5f42dcfb9..b3f102cc4 100644
--- a/src/tools/clippy/tests/ui/large_types_passed_by_value.stderr
+++ b/src/tools/clippy/tests/ui/large_types_passed_by_value.stderr
@@ -5,6 +5,7 @@ LL | fn bad(a: LargeAndCopy) {}
| ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy`
|
= note: `-D clippy::large-types-passed-by-value` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_types_passed_by_value)]`
error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)
--> $DIR/large_types_passed_by_value.rs:25:37
diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.rs b/src/tools/clippy/tests/ui/len_without_is_empty.rs
index 52aabefae..d62360111 100644
--- a/src/tools/clippy/tests/ui/len_without_is_empty.rs
+++ b/src/tools/clippy/tests/ui/len_without_is_empty.rs
@@ -5,6 +5,8 @@ pub struct PubOne;
impl PubOne {
pub fn len(&self) -> isize {
+ //~^ ERROR: struct `PubOne` has a public `len` method, but no `is_empty` method
+ //~| NOTE: `-D clippy::len-without-is-empty` implied by `-D warnings`
1
}
}
@@ -53,6 +55,7 @@ impl PubAllowedStruct {
}
pub trait PubTraitsToo {
+ //~^ ERROR: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty`
fn len(&self) -> isize;
}
@@ -66,6 +69,7 @@ pub struct HasIsEmpty;
impl HasIsEmpty {
pub fn len(&self) -> isize {
+ //~^ ERROR: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` me
1
}
@@ -78,6 +82,7 @@ pub struct HasWrongIsEmpty;
impl HasWrongIsEmpty {
pub fn len(&self) -> isize {
+ //~^ ERROR: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` met
1
}
@@ -90,6 +95,7 @@ pub struct MismatchedSelf;
impl MismatchedSelf {
pub fn len(self) -> isize {
+ //~^ ERROR: struct `MismatchedSelf` has a public `len` method, but the `is_empty` meth
1
}
@@ -169,6 +175,7 @@ pub trait InheritingEmpty: Empty {
pub trait Foo: Sized {}
pub trait DependsOnFoo: Foo {
+ //~^ ERROR: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty`
fn len(&mut self) -> usize;
}
@@ -214,6 +221,7 @@ impl OptionalLen2 {
pub struct OptionalLen3;
impl OptionalLen3 {
pub fn len(&self) -> usize {
+ //~^ ERROR: struct `OptionalLen3` has a public `len` method, but the `is_empty` method
0
}
@@ -226,6 +234,8 @@ impl OptionalLen3 {
pub struct ResultLen;
impl ResultLen {
pub fn len(&self) -> Result<usize, ()> {
+ //~^ ERROR: struct `ResultLen` has a public `len` method, but the `is_empty` method ha
+ //~| ERROR: this returns a `Result<_, ()>`
Ok(0)
}
@@ -238,10 +248,12 @@ impl ResultLen {
pub struct ResultLen2;
impl ResultLen2 {
pub fn len(&self) -> Result<usize, ()> {
+ //~^ ERROR: this returns a `Result<_, ()>`
Ok(0)
}
pub fn is_empty(&self) -> Result<bool, ()> {
+ //~^ ERROR: this returns a `Result<_, ()>`
Ok(true)
}
}
@@ -249,6 +261,7 @@ impl ResultLen2 {
pub struct ResultLen3;
impl ResultLen3 {
pub fn len(&self) -> Result<usize, ()> {
+ //~^ ERROR: this returns a `Result<_, ()>`
Ok(0)
}
@@ -290,6 +303,7 @@ impl AsyncLenWithoutIsEmpty {
}
pub async fn len(&self) -> usize {
+ //~^ ERROR: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empt
usize::from(!self.async_task().await)
}
}
@@ -302,6 +316,7 @@ impl AsyncOptionLenWithoutIsEmpty {
}
pub async fn len(&self) -> Option<usize> {
+ //~^ ERROR: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `i
None
}
}
@@ -323,6 +338,7 @@ impl AsyncResultLenWithoutIsEmpty {
}
pub async fn len(&self) -> Result<usize, ()> {
+ //~^ ERROR: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `i
Err(())
}
}
@@ -420,4 +436,27 @@ impl DifferingErrors {
}
}
+// Issue #11165
+pub struct Aliased1;
+pub type Alias1 = Aliased1;
+
+impl Alias1 {
+ pub fn len(&self) -> usize {
+ todo!()
+ }
+
+ pub fn is_empty(&self) -> bool {
+ todo!()
+ }
+}
+
+pub struct Aliased2;
+pub type Alias2 = Aliased2;
+impl Alias2 {
+ pub fn len(&self) -> usize {
+ //~^ ERROR: type `Alias2` has a public `len` method, but no `is_empty` method
+ todo!()
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.stderr b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
index 1bce1734b..8e51c28b3 100644
--- a/src/tools/clippy/tests/ui/len_without_is_empty.stderr
+++ b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
@@ -5,98 +5,102 @@ LL | pub fn len(&self) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::len-without-is-empty` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::len_without_is_empty)]`
error: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` method
- --> $DIR/len_without_is_empty.rs:55:1
+ --> $DIR/len_without_is_empty.rs:57:1
|
LL | / pub trait PubTraitsToo {
+LL | |
LL | | fn len(&self) -> isize;
LL | | }
| |_^
error: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` method
- --> $DIR/len_without_is_empty.rs:68:5
+ --> $DIR/len_without_is_empty.rs:71:5
|
LL | pub fn len(&self) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `is_empty` defined here
- --> $DIR/len_without_is_empty.rs:72:5
+ --> $DIR/len_without_is_empty.rs:76:5
|
LL | fn is_empty(&self) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` method has an unexpected signature
- --> $DIR/len_without_is_empty.rs:80:5
+ --> $DIR/len_without_is_empty.rs:84:5
|
LL | pub fn len(&self) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `is_empty` defined here
- --> $DIR/len_without_is_empty.rs:84:5
+ --> $DIR/len_without_is_empty.rs:89:5
|
LL | pub fn is_empty(&self, x: u32) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected signature: `(&self) -> bool`
error: struct `MismatchedSelf` has a public `len` method, but the `is_empty` method has an unexpected signature
- --> $DIR/len_without_is_empty.rs:92:5
+ --> $DIR/len_without_is_empty.rs:97:5
|
LL | pub fn len(self) -> isize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `is_empty` defined here
- --> $DIR/len_without_is_empty.rs:96:5
+ --> $DIR/len_without_is_empty.rs:102:5
|
LL | pub fn is_empty(&self) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected signature: `(self) -> bool`
error: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method
- --> $DIR/len_without_is_empty.rs:171:1
+ --> $DIR/len_without_is_empty.rs:177:1
|
LL | / pub trait DependsOnFoo: Foo {
+LL | |
LL | | fn len(&mut self) -> usize;
LL | | }
| |_^
error: struct `OptionalLen3` has a public `len` method, but the `is_empty` method has an unexpected signature
- --> $DIR/len_without_is_empty.rs:216:5
+ --> $DIR/len_without_is_empty.rs:223:5
|
LL | pub fn len(&self) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `is_empty` defined here
- --> $DIR/len_without_is_empty.rs:221:5
+ --> $DIR/len_without_is_empty.rs:229:5
|
LL | pub fn is_empty(&self) -> Option<bool> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected signature: `(&self) -> bool`
error: struct `ResultLen` has a public `len` method, but the `is_empty` method has an unexpected signature
- --> $DIR/len_without_is_empty.rs:228:5
+ --> $DIR/len_without_is_empty.rs:236:5
|
LL | pub fn len(&self) -> Result<usize, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `is_empty` defined here
- --> $DIR/len_without_is_empty.rs:233:5
+ --> $DIR/len_without_is_empty.rs:243:5
|
LL | pub fn is_empty(&self) -> Option<bool> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected signature: `(&self) -> bool` or `(&self) -> Result<bool>
error: this returns a `Result<_, ()>`
- --> $DIR/len_without_is_empty.rs:228:5
+ --> $DIR/len_without_is_empty.rs:236:5
|
LL | pub fn len(&self) -> Result<usize, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: use a custom `Error` type instead
= note: `-D clippy::result-unit-err` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]`
error: this returns a `Result<_, ()>`
- --> $DIR/len_without_is_empty.rs:240:5
+ --> $DIR/len_without_is_empty.rs:250:5
|
LL | pub fn len(&self) -> Result<usize, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +108,7 @@ LL | pub fn len(&self) -> Result<usize, ()> {
= help: use a custom `Error` type instead
error: this returns a `Result<_, ()>`
- --> $DIR/len_without_is_empty.rs:244:5
+ --> $DIR/len_without_is_empty.rs:255:5
|
LL | pub fn is_empty(&self) -> Result<bool, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +116,7 @@ LL | pub fn is_empty(&self) -> Result<bool, ()> {
= help: use a custom `Error` type instead
error: this returns a `Result<_, ()>`
- --> $DIR/len_without_is_empty.rs:251:5
+ --> $DIR/len_without_is_empty.rs:263:5
|
LL | pub fn len(&self) -> Result<usize, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,22 +124,28 @@ LL | pub fn len(&self) -> Result<usize, ()> {
= help: use a custom `Error` type instead
error: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method
- --> $DIR/len_without_is_empty.rs:292:5
+ --> $DIR/len_without_is_empty.rs:305:5
|
LL | pub async fn len(&self) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method
- --> $DIR/len_without_is_empty.rs:304:5
+ --> $DIR/len_without_is_empty.rs:318:5
|
LL | pub async fn len(&self) -> Option<usize> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method
- --> $DIR/len_without_is_empty.rs:325:5
+ --> $DIR/len_without_is_empty.rs:340:5
|
LL | pub async fn len(&self) -> Result<usize, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 15 previous errors
+error: type `Alias2` has a public `len` method, but no `is_empty` method
+ --> $DIR/len_without_is_empty.rs:456:5
+ |
+LL | pub fn len(&self) -> usize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/len_zero.fixed b/src/tools/clippy/tests/ui/len_zero.fixed
index fafee6a0d..745fc7e1a 100644
--- a/src/tools/clippy/tests/ui/len_zero.fixed
+++ b/src/tools/clippy/tests/ui/len_zero.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::len_zero)]
#![allow(dead_code, unused, clippy::needless_if, clippy::len_without_is_empty)]
diff --git a/src/tools/clippy/tests/ui/len_zero.rs b/src/tools/clippy/tests/ui/len_zero.rs
index 6a9006c47..048ad2f4f 100644
--- a/src/tools/clippy/tests/ui/len_zero.rs
+++ b/src/tools/clippy/tests/ui/len_zero.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::len_zero)]
#![allow(dead_code, unused, clippy::needless_if, clippy::len_without_is_empty)]
diff --git a/src/tools/clippy/tests/ui/len_zero.stderr b/src/tools/clippy/tests/ui/len_zero.stderr
index 396cfb75f..e1f243441 100644
--- a/src/tools/clippy/tests/ui/len_zero.stderr
+++ b/src/tools/clippy/tests/ui/len_zero.stderr
@@ -1,141 +1,143 @@
error: length comparison to zero
- --> $DIR/len_zero.rs:84:8
+ --> $DIR/len_zero.rs:82:8
|
LL | if x.len() == 0 {
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `x.is_empty()`
|
= note: `-D clippy::len-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::len_zero)]`
error: length comparison to zero
- --> $DIR/len_zero.rs:88:8
+ --> $DIR/len_zero.rs:86:8
|
LL | if "".len() == 0 {}
| ^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `"".is_empty()`
error: comparison to empty slice
- --> $DIR/len_zero.rs:97:20
+ --> $DIR/len_zero.rs:95:20
|
LL | println!("{}", *s1 == "");
| ^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s1.is_empty()`
|
= note: `-D clippy::comparison-to-empty` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::comparison_to_empty)]`
error: comparison to empty slice
- --> $DIR/len_zero.rs:98:20
+ --> $DIR/len_zero.rs:96:20
|
LL | println!("{}", **s2 == "");
| ^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s2.is_empty()`
error: comparison to empty slice
- --> $DIR/len_zero.rs:99:20
+ --> $DIR/len_zero.rs:97:20
|
LL | println!("{}", ***s3 == "");
| ^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s3.is_empty()`
error: comparison to empty slice
- --> $DIR/len_zero.rs:100:20
+ --> $DIR/len_zero.rs:98:20
|
LL | println!("{}", ****s4 == "");
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s4.is_empty()`
error: comparison to empty slice
- --> $DIR/len_zero.rs:101:20
+ --> $DIR/len_zero.rs:99:20
|
LL | println!("{}", *****s5 == "");
| ^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s5.is_empty()`
error: comparison to empty slice
- --> $DIR/len_zero.rs:102:20
+ --> $DIR/len_zero.rs:100:20
|
LL | println!("{}", ******(s6) == "");
| ^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(s6).is_empty()`
error: comparison to empty slice
- --> $DIR/len_zero.rs:105:20
+ --> $DIR/len_zero.rs:103:20
|
LL | println!("{}", &**d2s == "");
| ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(**d2s).is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:120:8
+ --> $DIR/len_zero.rs:118:8
|
LL | if has_is_empty.len() == 0 {
| ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:123:8
+ --> $DIR/len_zero.rs:121:8
|
LL | if has_is_empty.len() != 0 {
| ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:126:8
+ --> $DIR/len_zero.rs:124:8
|
LL | if has_is_empty.len() > 0 {
| ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
error: length comparison to one
- --> $DIR/len_zero.rs:129:8
+ --> $DIR/len_zero.rs:127:8
|
LL | if has_is_empty.len() < 1 {
| ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`
error: length comparison to one
- --> $DIR/len_zero.rs:132:8
+ --> $DIR/len_zero.rs:130:8
|
LL | if has_is_empty.len() >= 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:143:8
+ --> $DIR/len_zero.rs:141:8
|
LL | if 0 == has_is_empty.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:146:8
+ --> $DIR/len_zero.rs:144:8
|
LL | if 0 != has_is_empty.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:149:8
+ --> $DIR/len_zero.rs:147:8
|
LL | if 0 < has_is_empty.len() {
| ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
error: length comparison to one
- --> $DIR/len_zero.rs:152:8
+ --> $DIR/len_zero.rs:150:8
|
LL | if 1 <= has_is_empty.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
error: length comparison to one
- --> $DIR/len_zero.rs:155:8
+ --> $DIR/len_zero.rs:153:8
|
LL | if 1 > has_is_empty.len() {
| ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:169:8
+ --> $DIR/len_zero.rs:167:8
|
LL | if with_is_empty.len() == 0 {
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `with_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:181:6
+ --> $DIR/len_zero.rs:179:6
|
LL | (has_is_empty.len() > 0).then(|| println!("This can happen."));
| ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:182:6
+ --> $DIR/len_zero.rs:180:6
|
LL | (has_is_empty.len() == 0).then(|| println!("Or this!"));
| ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`
error: length comparison to zero
- --> $DIR/len_zero.rs:186:8
+ --> $DIR/len_zero.rs:184:8
|
LL | if b.len() != 0 {}
| ^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!b.is_empty()`
diff --git a/src/tools/clippy/tests/ui/len_zero_ranges.fixed b/src/tools/clippy/tests/ui/len_zero_ranges.fixed
index 4b1241ec8..1fdeb2c7a 100644
--- a/src/tools/clippy/tests/ui/len_zero_ranges.fixed
+++ b/src/tools/clippy/tests/ui/len_zero_ranges.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::len_zero)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/len_zero_ranges.rs b/src/tools/clippy/tests/ui/len_zero_ranges.rs
index 4b47132c7..a5c9a969a 100644
--- a/src/tools/clippy/tests/ui/len_zero_ranges.rs
+++ b/src/tools/clippy/tests/ui/len_zero_ranges.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::len_zero)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/len_zero_ranges.stderr b/src/tools/clippy/tests/ui/len_zero_ranges.stderr
index d0defb5a7..1922e9b30 100644
--- a/src/tools/clippy/tests/ui/len_zero_ranges.stderr
+++ b/src/tools/clippy/tests/ui/len_zero_ranges.stderr
@@ -1,13 +1,14 @@
error: length comparison to zero
- --> $DIR/len_zero_ranges.rs:9:17
+ --> $DIR/len_zero_ranges.rs:7:17
|
LL | let _ = (0..42).len() == 0;
| ^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(0..42).is_empty()`
|
= note: `-D clippy::len-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::len_zero)]`
error: length comparison to zero
- --> $DIR/len_zero_ranges.rs:13:17
+ --> $DIR/len_zero_ranges.rs:11:17
|
LL | let _ = (0_u8..=42).len() == 0;
| ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(0_u8..=42).is_empty()`
diff --git a/src/tools/clippy/tests/ui/let_and_return.fixed b/src/tools/clippy/tests/ui/let_and_return.fixed
new file mode 100644
index 000000000..88b8ae673
--- /dev/null
+++ b/src/tools/clippy/tests/ui/let_and_return.fixed
@@ -0,0 +1,187 @@
+#![allow(unused)]
+#![warn(clippy::let_and_return)]
+
+use std::cell::RefCell;
+
+fn test() -> i32 {
+ let _y = 0; // no warning
+
+ 5
+ //~^ ERROR: returning the result of a `let` binding from a block
+ //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings`
+}
+
+fn test_inner() -> i32 {
+ if true {
+
+ 5
+ //~^ ERROR: returning the result of a `let` binding from a block
+ } else {
+ 0
+ }
+}
+
+fn test_nowarn_1() -> i32 {
+ let mut x = 5;
+ x += 1;
+ x
+}
+
+fn test_nowarn_2() -> i32 {
+ let x = 5;
+ x + 1
+}
+
+fn test_nowarn_3() -> (i32, i32) {
+ // this should technically warn, but we do not compare complex patterns
+ let (x, y) = (5, 9);
+ (x, y)
+}
+
+fn test_nowarn_4() -> i32 {
+ // this should technically warn, but not b/c of clippy::let_and_return, but b/c of useless type
+ let x: i32 = 5;
+ x
+}
+
+fn test_nowarn_5(x: i16) -> u16 {
+ #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
+ let x = x as u16;
+ x
+}
+
+// False positive example
+trait Decode {
+ fn decode<D: std::io::Read>(d: D) -> Result<Self, ()>
+ where
+ Self: Sized;
+}
+
+macro_rules! tuple_encode {
+ ($($x:ident),*) => (
+ impl<$($x: Decode),*> Decode for ($($x),*) {
+ #[inline]
+ #[allow(non_snake_case)]
+ fn decode<D: std::io::Read>(mut d: D) -> Result<Self, ()> {
+ // Shouldn't trigger lint
+ Ok(($({let $x = Decode::decode(&mut d)?; $x }),*))
+ }
+ }
+ );
+}
+
+fn issue_3792() -> String {
+ use std::io::{self, BufRead, Stdin};
+
+ let stdin = io::stdin();
+ // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin`
+ // https://github.com/rust-lang/rust/pull/93965
+
+ stdin.lock().lines().next().unwrap().unwrap()
+ //~^ ERROR: returning the result of a `let` binding from a block
+}
+
+tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
+
+mod no_lint_if_stmt_borrows {
+ use std::cell::RefCell;
+ use std::rc::{Rc, Weak};
+ struct Bar;
+
+ impl Bar {
+ fn new() -> Self {
+ Bar {}
+ }
+ fn baz(&self) -> u32 {
+ 0
+ }
+ }
+
+ fn issue_3324(value: Weak<RefCell<Bar>>) -> u32 {
+ let value = value.upgrade().unwrap();
+ let ret = value.borrow().baz();
+ ret
+ }
+
+ fn borrows_in_closure(value: Weak<RefCell<Bar>>) -> u32 {
+ fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 {
+ x
+ }
+
+ let value = value.upgrade().unwrap();
+ let ret = f(|| value.borrow().baz())();
+ ret
+ }
+
+ mod free_function {
+ struct Inner;
+
+ struct Foo<'a> {
+ inner: &'a Inner,
+ }
+
+ impl Drop for Foo<'_> {
+ fn drop(&mut self) {}
+ }
+
+ impl<'a> Foo<'a> {
+ fn new(inner: &'a Inner) -> Self {
+ Self { inner }
+ }
+
+ fn value(&self) -> i32 {
+ 42
+ }
+ }
+
+ fn some_foo(inner: &Inner) -> Foo<'_> {
+ Foo { inner }
+ }
+
+ fn test() -> i32 {
+ let x = Inner {};
+ let value = some_foo(&x).value();
+ value
+ }
+
+ fn test2() -> i32 {
+ let x = Inner {};
+ let value = Foo::new(&x).value();
+ value
+ }
+ }
+}
+
+mod issue_5729 {
+ use std::sync::Arc;
+
+ trait Foo {}
+
+ trait FooStorage {
+ fn foo_cloned(&self) -> Arc<dyn Foo>;
+ }
+
+ struct FooStorageImpl<T: Foo> {
+ foo: Arc<T>,
+ }
+
+ impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> {
+ fn foo_cloned(&self) -> Arc<dyn Foo> {
+
+ Arc::clone(&self.foo) as _
+ //~^ ERROR: returning the result of a `let` binding from a block
+ }
+ }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/11167
+macro_rules! fn_in_macro {
+ ($b:block) => {
+ fn f() -> usize $b
+ }
+}
+fn_in_macro!({
+ return 1;
+});
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs
index 64665cc90..f366842c5 100644
--- a/src/tools/clippy/tests/ui/let_and_return.rs
+++ b/src/tools/clippy/tests/ui/let_and_return.rs
@@ -7,12 +7,15 @@ fn test() -> i32 {
let _y = 0; // no warning
let x = 5;
x
+ //~^ ERROR: returning the result of a `let` binding from a block
+ //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings`
}
fn test_inner() -> i32 {
if true {
let x = 5;
x
+ //~^ ERROR: returning the result of a `let` binding from a block
} else {
0
}
@@ -75,6 +78,7 @@ fn issue_3792() -> String {
// https://github.com/rust-lang/rust/pull/93965
let line = stdin.lock().lines().next().unwrap().unwrap();
line
+ //~^ ERROR: returning the result of a `let` binding from a block
}
tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
@@ -165,6 +169,7 @@ mod issue_5729 {
fn foo_cloned(&self) -> Arc<dyn Foo> {
let clone = Arc::clone(&self.foo);
clone
+ //~^ ERROR: returning the result of a `let` binding from a block
}
}
}
diff --git a/src/tools/clippy/tests/ui/let_and_return.stderr b/src/tools/clippy/tests/ui/let_and_return.stderr
index 4ca0a05c8..c09c2b32a 100644
--- a/src/tools/clippy/tests/ui/let_and_return.stderr
+++ b/src/tools/clippy/tests/ui/let_and_return.stderr
@@ -7,6 +7,7 @@ LL | x
| ^
|
= note: `-D clippy::let-and-return` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`
help: return the expression directly
|
LL ~
@@ -14,7 +15,7 @@ LL ~ 5
|
error: returning the result of a `let` binding from a block
- --> $DIR/let_and_return.rs:15:9
+ --> $DIR/let_and_return.rs:17:9
|
LL | let x = 5;
| ---------- unnecessary `let` binding
@@ -28,7 +29,7 @@ LL ~ 5
|
error: returning the result of a `let` binding from a block
- --> $DIR/let_and_return.rs:77:5
+ --> $DIR/let_and_return.rs:80:5
|
LL | let line = stdin.lock().lines().next().unwrap().unwrap();
| --------------------------------------------------------- unnecessary `let` binding
@@ -42,7 +43,7 @@ LL ~ stdin.lock().lines().next().unwrap().unwrap()
|
error: returning the result of a `let` binding from a block
- --> $DIR/let_and_return.rs:167:13
+ --> $DIR/let_and_return.rs:171:13
|
LL | let clone = Arc::clone(&self.foo);
| ---------------------------------- unnecessary `let` binding
diff --git a/src/tools/clippy/tests/ui/let_if_seq.rs b/src/tools/clippy/tests/ui/let_if_seq.rs
index 959567f68..9869d9452 100644
--- a/src/tools/clippy/tests/ui/let_if_seq.rs
+++ b/src/tools/clippy/tests/ui/let_if_seq.rs
@@ -7,7 +7,7 @@
clippy::needless_late_init
)]
#![warn(clippy::useless_let_if_seq)]
-
+//@no-rustfix
fn f() -> bool {
true
}
@@ -64,11 +64,15 @@ fn main() {
issue985_alt();
let mut foo = 0;
+ //~^ ERROR: `if _ { .. } else { .. }` is an expression
+ //~| NOTE: you might not need `mut` at all
if f() {
foo = 42;
}
let mut bar = 0;
+ //~^ ERROR: `if _ { .. } else { .. }` is an expression
+ //~| NOTE: you might not need `mut` at all
if f() {
f();
bar = 42;
@@ -77,6 +81,7 @@ fn main() {
}
let quz;
+ //~^ ERROR: `if _ { .. } else { .. }` is an expression
if f() {
quz = 42;
} else {
@@ -106,6 +111,8 @@ fn main() {
// baz needs to be mut
let mut baz = 0;
+ //~^ ERROR: `if _ { .. } else { .. }` is an expression
+ //~| NOTE: you might not need `mut` at all
if f() {
baz = 42;
}
diff --git a/src/tools/clippy/tests/ui/let_if_seq.stderr b/src/tools/clippy/tests/ui/let_if_seq.stderr
index f2e0edb6f..bfb4bb9d0 100644
--- a/src/tools/clippy/tests/ui/let_if_seq.stderr
+++ b/src/tools/clippy/tests/ui/let_if_seq.stderr
@@ -2,6 +2,8 @@ error: `if _ { .. } else { .. }` is an expression
--> $DIR/let_if_seq.rs:66:5
|
LL | / let mut foo = 0;
+LL | |
+LL | |
LL | | if f() {
LL | | foo = 42;
LL | | }
@@ -9,15 +11,16 @@ LL | | }
|
= note: you might not need `mut` at all
= note: `-D clippy::useless-let-if-seq` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::useless_let_if_seq)]`
error: `if _ { .. } else { .. }` is an expression
- --> $DIR/let_if_seq.rs:71:5
+ --> $DIR/let_if_seq.rs:73:5
|
LL | / let mut bar = 0;
+LL | |
+LL | |
LL | | if f() {
-LL | | f();
-LL | | bar = 42;
-LL | | } else {
+... |
LL | | f();
LL | | }
| |_____^ help: it is more idiomatic to write: `let <mut> bar = if f() { ..; 42 } else { ..; 0 };`
@@ -25,9 +28,10 @@ LL | | }
= note: you might not need `mut` at all
error: `if _ { .. } else { .. }` is an expression
- --> $DIR/let_if_seq.rs:79:5
+ --> $DIR/let_if_seq.rs:83:5
|
LL | / let quz;
+LL | |
LL | | if f() {
LL | | quz = 42;
LL | | } else {
@@ -36,9 +40,11 @@ LL | | }
| |_____^ help: it is more idiomatic to write: `let quz = if f() { 42 } else { 0 };`
error: `if _ { .. } else { .. }` is an expression
- --> $DIR/let_if_seq.rs:108:5
+ --> $DIR/let_if_seq.rs:113:5
|
LL | / let mut baz = 0;
+LL | |
+LL | |
LL | | if f() {
LL | | baz = 42;
LL | | }
diff --git a/src/tools/clippy/tests/ui/let_underscore_future.rs b/src/tools/clippy/tests/ui/let_underscore_future.rs
index d8f54cdca..c2185e978 100644
--- a/src/tools/clippy/tests/ui/let_underscore_future.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_future.rs
@@ -1,5 +1,5 @@
use std::future::Future;
-
+//@no-rustfix
async fn some_async_fn() {}
fn sync_side_effects() {}
@@ -12,9 +12,12 @@ fn do_something_to_future(future: &mut impl Future<Output = ()>) {}
fn main() {
let _ = some_async_fn();
+ //~^ ERROR: non-binding `let` on a future
let _ = custom();
+ //~^ ERROR: non-binding `let` on a future
let mut future = some_async_fn();
do_something_to_future(&mut future);
let _ = future;
+ //~^ ERROR: non-binding `let` on a future
}
diff --git a/src/tools/clippy/tests/ui/let_underscore_future.stderr b/src/tools/clippy/tests/ui/let_underscore_future.stderr
index 33a748736..ef927a808 100644
--- a/src/tools/clippy/tests/ui/let_underscore_future.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_future.stderr
@@ -6,9 +6,10 @@ LL | let _ = some_async_fn();
|
= help: consider awaiting the future or dropping explicitly with `std::mem::drop`
= note: `-D clippy::let-underscore-future` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_underscore_future)]`
error: non-binding `let` on a future
- --> $DIR/let_underscore_future.rs:15:5
+ --> $DIR/let_underscore_future.rs:16:5
|
LL | let _ = custom();
| ^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let _ = custom();
= help: consider awaiting the future or dropping explicitly with `std::mem::drop`
error: non-binding `let` on a future
- --> $DIR/let_underscore_future.rs:19:5
+ --> $DIR/let_underscore_future.rs:21:5
|
LL | let _ = future;
| ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/let_underscore_lock.rs b/src/tools/clippy/tests/ui/let_underscore_lock.rs
index 87f12e278..ccac73be7 100644
--- a/src/tools/clippy/tests/ui/let_underscore_lock.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_lock.rs
@@ -8,13 +8,17 @@ fn main() {
let p_m: Mutex<()> = Mutex::const_new(RawMutex::INIT, ());
let _ = p_m.lock();
+ //~^ ERROR: non-binding `let` on a synchronization lock
let p_m1 = Mutex::new(0);
let _ = p_m1.lock();
+ //~^ ERROR: non-binding `let` on a synchronization lock
let p_rw = RwLock::new(0);
let _ = p_rw.read();
+ //~^ ERROR: non-binding `let` on a synchronization lock
let _ = p_rw.write();
+ //~^ ERROR: non-binding `let` on a synchronization lock
// These shouldn't throw an error.
let _ = p_m;
diff --git a/src/tools/clippy/tests/ui/let_underscore_lock.stderr b/src/tools/clippy/tests/ui/let_underscore_lock.stderr
index 5027e6b3c..ac6e0978e 100644
--- a/src/tools/clippy/tests/ui/let_underscore_lock.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_lock.stderr
@@ -6,9 +6,10 @@ LL | let _ = p_m.lock();
|
= help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
= note: `-D clippy::let-underscore-lock` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_underscore_lock)]`
error: non-binding `let` on a synchronization lock
- --> $DIR/let_underscore_lock.rs:13:5
+ --> $DIR/let_underscore_lock.rs:14:5
|
LL | let _ = p_m1.lock();
| ^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let _ = p_m1.lock();
= help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
error: non-binding `let` on a synchronization lock
- --> $DIR/let_underscore_lock.rs:16:5
+ --> $DIR/let_underscore_lock.rs:18:5
|
LL | let _ = p_rw.read();
| ^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let _ = p_rw.read();
= help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
error: non-binding `let` on a synchronization lock
- --> $DIR/let_underscore_lock.rs:17:5
+ --> $DIR/let_underscore_lock.rs:20:5
|
LL | let _ = p_rw.write();
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/let_underscore_must_use.rs b/src/tools/clippy/tests/ui/let_underscore_must_use.rs
index 1edb77c74..3290d0877 100644
--- a/src/tools/clippy/tests/ui/let_underscore_must_use.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_must_use.rs
@@ -65,30 +65,42 @@ impl Trait for S {
fn main() {
let _ = f();
+ //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function
let _ = g();
+ //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type
let _ = h();
let _ = l(0_u32);
+ //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function
let s = S {};
let _ = s.f();
+ //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function
let _ = s.g();
+ //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type
let _ = s.k();
let _ = S::h();
+ //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function
let _ = S::p();
+ //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type
let _ = S::a();
+ //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function
let _ = if true { Ok(()) } else { Err(()) };
+ //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type
let a = Result::<(), ()>::Ok(());
let _ = a.is_ok();
+ //~^ ERROR: non-binding `let` on a result of a `#[must_use]` function
let _ = a.map(|_| ());
+ //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type
let _ = a;
+ //~^ ERROR: non-binding `let` on an expression with `#[must_use]` type
#[allow(clippy::let_underscore_must_use)]
let _ = a;
diff --git a/src/tools/clippy/tests/ui/let_underscore_must_use.stderr b/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
index 28d760eb4..83d0372e6 100644
--- a/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
@@ -6,9 +6,10 @@ LL | let _ = f();
|
= help: consider explicitly using function result
= note: `-D clippy::let-underscore-must-use` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_underscore_must_use)]`
error: non-binding `let` on an expression with `#[must_use]` type
- --> $DIR/let_underscore_must_use.rs:68:5
+ --> $DIR/let_underscore_must_use.rs:69:5
|
LL | let _ = g();
| ^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let _ = g();
= help: consider explicitly using expression value
error: non-binding `let` on a result of a `#[must_use]` function
- --> $DIR/let_underscore_must_use.rs:70:5
+ --> $DIR/let_underscore_must_use.rs:72:5
|
LL | let _ = l(0_u32);
| ^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let _ = l(0_u32);
= help: consider explicitly using function result
error: non-binding `let` on a result of a `#[must_use]` function
- --> $DIR/let_underscore_must_use.rs:74:5
+ --> $DIR/let_underscore_must_use.rs:77:5
|
LL | let _ = s.f();
| ^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | let _ = s.f();
= help: consider explicitly using function result
error: non-binding `let` on an expression with `#[must_use]` type
- --> $DIR/let_underscore_must_use.rs:75:5
+ --> $DIR/let_underscore_must_use.rs:79:5
|
LL | let _ = s.g();
| ^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | let _ = s.g();
= help: consider explicitly using expression value
error: non-binding `let` on a result of a `#[must_use]` function
- --> $DIR/let_underscore_must_use.rs:78:5
+ --> $DIR/let_underscore_must_use.rs:83:5
|
LL | let _ = S::h();
| ^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | let _ = S::h();
= help: consider explicitly using function result
error: non-binding `let` on an expression with `#[must_use]` type
- --> $DIR/let_underscore_must_use.rs:79:5
+ --> $DIR/let_underscore_must_use.rs:85:5
|
LL | let _ = S::p();
| ^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | let _ = S::p();
= help: consider explicitly using expression value
error: non-binding `let` on a result of a `#[must_use]` function
- --> $DIR/let_underscore_must_use.rs:81:5
+ --> $DIR/let_underscore_must_use.rs:88:5
|
LL | let _ = S::a();
| ^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | let _ = S::a();
= help: consider explicitly using function result
error: non-binding `let` on an expression with `#[must_use]` type
- --> $DIR/let_underscore_must_use.rs:83:5
+ --> $DIR/let_underscore_must_use.rs:91:5
|
LL | let _ = if true { Ok(()) } else { Err(()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | let _ = if true { Ok(()) } else { Err(()) };
= help: consider explicitly using expression value
error: non-binding `let` on a result of a `#[must_use]` function
- --> $DIR/let_underscore_must_use.rs:87:5
+ --> $DIR/let_underscore_must_use.rs:96:5
|
LL | let _ = a.is_ok();
| ^^^^^^^^^^^^^^^^^^
@@ -80,7 +81,7 @@ LL | let _ = a.is_ok();
= help: consider explicitly using function result
error: non-binding `let` on an expression with `#[must_use]` type
- --> $DIR/let_underscore_must_use.rs:89:5
+ --> $DIR/let_underscore_must_use.rs:99:5
|
LL | let _ = a.map(|_| ());
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +89,7 @@ LL | let _ = a.map(|_| ());
= help: consider explicitly using expression value
error: non-binding `let` on an expression with `#[must_use]` type
- --> $DIR/let_underscore_must_use.rs:91:5
+ --> $DIR/let_underscore_must_use.rs:102:5
|
LL | let _ = a;
| ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.rs b/src/tools/clippy/tests/ui/let_underscore_untyped.rs
index 18630c27f..bd94a3ada 100644
--- a/src/tools/clippy/tests/ui/let_underscore_untyped.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_untyped.rs
@@ -1,4 +1,4 @@
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![allow(unused)]
#![warn(clippy::let_underscore_untyped)]
diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.stderr b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr
index e0c39b6ee..0e5647fa1 100644
--- a/src/tools/clippy/tests/ui/let_underscore_untyped.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr
@@ -10,6 +10,7 @@ help: consider adding a type annotation
LL | let _ = a();
| ^
= note: `-D clippy::let-underscore-untyped` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_underscore_untyped)]`
error: non-binding `let` without a type annotation
--> $DIR/let_underscore_untyped.rs:52:5
diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed
index 8ba89ec78..f98ce9d50 100644
--- a/src/tools/clippy/tests/ui/let_unit.fixed
+++ b/src/tools/clippy/tests/ui/let_unit.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(lint_reasons)]
#![warn(clippy::let_unit_value)]
#![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
@@ -179,3 +177,5 @@ fn attributes() {
async fn issue10433() {
let _pending: () = std::future::pending().await;
}
+
+pub async fn issue11502(a: ()) {}
diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs
index 7e8764a48..6d942ca89 100644
--- a/src/tools/clippy/tests/ui/let_unit.rs
+++ b/src/tools/clippy/tests/ui/let_unit.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(lint_reasons)]
#![warn(clippy::let_unit_value)]
#![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
@@ -179,3 +177,5 @@ fn attributes() {
async fn issue10433() {
let _pending: () = std::future::pending().await;
}
+
+pub async fn issue11502(a: ()) {}
diff --git a/src/tools/clippy/tests/ui/let_unit.stderr b/src/tools/clippy/tests/ui/let_unit.stderr
index 49da74ca7..de106f50e 100644
--- a/src/tools/clippy/tests/ui/let_unit.stderr
+++ b/src/tools/clippy/tests/ui/let_unit.stderr
@@ -1,19 +1,20 @@
error: this let-binding has unit value
- --> $DIR/let_unit.rs:14:5
+ --> $DIR/let_unit.rs:12:5
|
LL | let _x = println!("x");
| ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `println!("x");`
|
= note: `-D clippy::let-unit-value` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`
error: this let-binding has unit value
- --> $DIR/let_unit.rs:18:9
+ --> $DIR/let_unit.rs:16:9
|
LL | let _a = ();
| ^^^^^^^^^^^^ help: omit the `let` binding: `();`
error: this let-binding has unit value
- --> $DIR/let_unit.rs:53:5
+ --> $DIR/let_unit.rs:51:5
|
LL | / let _ = v
LL | | .into_iter()
@@ -36,7 +37,7 @@ LL + .unwrap();
|
error: this let-binding has unit value
- --> $DIR/let_unit.rs:80:5
+ --> $DIR/let_unit.rs:78:5
|
LL | let x: () = f(); // Lint.
| ^^^^-^^^^^^^^^^^
@@ -44,7 +45,7 @@ LL | let x: () = f(); // Lint.
| help: use a wild (`_`) binding: `_`
error: this let-binding has unit value
- --> $DIR/let_unit.rs:83:5
+ --> $DIR/let_unit.rs:81:5
|
LL | let x: () = f2(0i32); // Lint.
| ^^^^-^^^^^^^^^^^^^^^^
@@ -52,19 +53,19 @@ LL | let x: () = f2(0i32); // Lint.
| help: use a wild (`_`) binding: `_`
error: this let-binding has unit value
- --> $DIR/let_unit.rs:85:5
+ --> $DIR/let_unit.rs:83:5
|
LL | let _: () = f3(()); // Lint
| ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
error: this let-binding has unit value
- --> $DIR/let_unit.rs:86:5
+ --> $DIR/let_unit.rs:84:5
|
LL | let x: () = f3(()); // Lint
| ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
error: this let-binding has unit value
- --> $DIR/let_unit.rs:102:5
+ --> $DIR/let_unit.rs:100:5
|
LL | let x: () = if true { f() } else { f2(0) }; // Lint
| ^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | let x: () = if true { f() } else { f2(0) }; // Lint
| help: use a wild (`_`) binding: `_`
error: this let-binding has unit value
- --> $DIR/let_unit.rs:113:5
+ --> $DIR/let_unit.rs:111:5
|
LL | / let _: () = match Some(0) {
LL | | None => f2(1),
@@ -93,7 +94,7 @@ LL + };
|
error: this let-binding has unit value
- --> $DIR/let_unit.rs:160:13
+ --> $DIR/let_unit.rs:158:13
|
LL | let _: () = z;
| ^^^^^^^^^^^^^^ help: omit the `let` binding: `z;`
diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.rs b/src/tools/clippy/tests/ui/let_with_type_underscore.rs
index 8214176cf..ae1a480bc 100644
--- a/src/tools/clippy/tests/ui/let_with_type_underscore.rs
+++ b/src/tools/clippy/tests/ui/let_with_type_underscore.rs
@@ -1,4 +1,4 @@
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![allow(unused)]
#![warn(clippy::let_with_type_underscore)]
#![allow(clippy::let_unit_value, clippy::needless_late_init)]
diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.stderr b/src/tools/clippy/tests/ui/let_with_type_underscore.stderr
index a749552c7..d4c9ba19c 100644
--- a/src/tools/clippy/tests/ui/let_with_type_underscore.stderr
+++ b/src/tools/clippy/tests/ui/let_with_type_underscore.stderr
@@ -10,6 +10,7 @@ help: remove the explicit type `_` declaration
LL | let x: _ = 1;
| ^^^
= note: `-D clippy::let-with-type-underscore` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::let_with_type_underscore)]`
error: variable declared with type underscore
--> $DIR/let_with_type_underscore.rs:16:5
diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed
index 64114f658..74ef6f729 100644
--- a/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed
+++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::map_identity)]
#![warn(clippy::lines_filter_map_ok)]
diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.rs b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs
index 5aedc6863..345f4dc5f 100644
--- a/src/tools/clippy/tests/ui/lines_filter_map_ok.rs
+++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::map_identity)]
#![warn(clippy::lines_filter_map_ok)]
diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr b/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr
index cddd403d5..fa2ba0a9a 100644
--- a/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr
+++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.stderr
@@ -1,48 +1,49 @@
error: `filter_map()` will run forever if the iterator repeatedly produces an `Err`
- --> $DIR/lines_filter_map_ok.rs:11:31
+ --> $DIR/lines_filter_map_ok.rs:9:31
|
LL | BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`
|
note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error
- --> $DIR/lines_filter_map_ok.rs:11:5
+ --> $DIR/lines_filter_map_ok.rs:9:5
|
LL | BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::lines-filter-map-ok` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::lines_filter_map_ok)]`
error: `flat_map()` will run forever if the iterator repeatedly produces an `Err`
- --> $DIR/lines_filter_map_ok.rs:14:31
+ --> $DIR/lines_filter_map_ok.rs:12:31
|
LL | BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`
|
note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error
- --> $DIR/lines_filter_map_ok.rs:14:5
+ --> $DIR/lines_filter_map_ok.rs:12:5
|
LL | BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `filter_map()` will run forever if the iterator repeatedly produces an `Err`
- --> $DIR/lines_filter_map_ok.rs:17:25
+ --> $DIR/lines_filter_map_ok.rs:15:25
|
LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`
|
note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error
- --> $DIR/lines_filter_map_ok.rs:17:5
+ --> $DIR/lines_filter_map_ok.rs:15:5
|
LL | io::stdin().lines().filter_map(Result::ok).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^
error: `filter_map()` will run forever if the iterator repeatedly produces an `Err`
- --> $DIR/lines_filter_map_ok.rs:19:25
+ --> $DIR/lines_filter_map_ok.rs:17:25
|
LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`
|
note: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error
- --> $DIR/lines_filter_map_ok.rs:19:5
+ --> $DIR/lines_filter_map_ok.rs:17:5
|
LL | io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ());
| ^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/linkedlist.rs b/src/tools/clippy/tests/ui/linkedlist.rs
index 690ea810a..e1e6cff98 100644
--- a/src/tools/clippy/tests/ui/linkedlist.rs
+++ b/src/tools/clippy/tests/ui/linkedlist.rs
@@ -6,12 +6,17 @@ extern crate alloc;
use alloc::collections::linked_list::LinkedList;
const C: LinkedList<i32> = LinkedList::new();
+//~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu
static S: LinkedList<i32> = LinkedList::new();
+//~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu
trait Foo {
type Baz = LinkedList<u8>;
+ //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str
fn foo(_: LinkedList<u8>);
+ //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str
const BAR: Option<LinkedList<u8>>;
+ //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str
}
// Ok, we don’t want to warn for implementations; see issue #605.
@@ -22,16 +27,20 @@ impl Foo for LinkedList<u8> {
pub struct Bar {
priv_linked_list_field: LinkedList<u8>,
+ //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str
pub pub_linked_list_field: LinkedList<u8>,
}
impl Bar {
fn foo(_: LinkedList<u8>) {}
+ //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data str
}
// All of these test should be trigger the lint because they are not
// part of the public api
fn test(my_favorite_linked_list: LinkedList<u8>) {}
+//~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu
fn test_ret() -> Option<LinkedList<u8>> {
+ //~^ ERROR: you seem to be using a `LinkedList`! Perhaps you meant some other data structu
None
}
fn test_local_not_linted() {
diff --git a/src/tools/clippy/tests/ui/linkedlist.stderr b/src/tools/clippy/tests/ui/linkedlist.stderr
index c76c94961..792af4dd0 100644
--- a/src/tools/clippy/tests/ui/linkedlist.stderr
+++ b/src/tools/clippy/tests/ui/linkedlist.stderr
@@ -6,9 +6,10 @@ LL | const C: LinkedList<i32> = LinkedList::new();
|
= help: a `VecDeque` might work
= note: `-D clippy::linkedlist` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::linkedlist)]`
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:9:11
+ --> $DIR/linkedlist.rs:10:11
|
LL | static S: LinkedList<i32> = LinkedList::new();
| ^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | static S: LinkedList<i32> = LinkedList::new();
= help: a `VecDeque` might work
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:12:16
+ --> $DIR/linkedlist.rs:14:16
|
LL | type Baz = LinkedList<u8>;
| ^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | type Baz = LinkedList<u8>;
= help: a `VecDeque` might work
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:13:15
+ --> $DIR/linkedlist.rs:16:15
|
LL | fn foo(_: LinkedList<u8>);
| ^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | fn foo(_: LinkedList<u8>);
= help: a `VecDeque` might work
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:14:23
+ --> $DIR/linkedlist.rs:18:23
|
LL | const BAR: Option<LinkedList<u8>>;
| ^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | const BAR: Option<LinkedList<u8>>;
= help: a `VecDeque` might work
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:24:29
+ --> $DIR/linkedlist.rs:29:29
|
LL | priv_linked_list_field: LinkedList<u8>,
| ^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | priv_linked_list_field: LinkedList<u8>,
= help: a `VecDeque` might work
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:28:15
+ --> $DIR/linkedlist.rs:34:15
|
LL | fn foo(_: LinkedList<u8>) {}
| ^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | fn foo(_: LinkedList<u8>) {}
= help: a `VecDeque` might work
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:33:34
+ --> $DIR/linkedlist.rs:40:34
|
LL | fn test(my_favorite_linked_list: LinkedList<u8>) {}
| ^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | fn test(my_favorite_linked_list: LinkedList<u8>) {}
= help: a `VecDeque` might work
error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
- --> $DIR/linkedlist.rs:34:25
+ --> $DIR/linkedlist.rs:42:25
|
LL | fn test_ret() -> Option<LinkedList<u8>> {
| ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/literals.rs b/src/tools/clippy/tests/ui/literals.rs
index 1a646e49c..c275b04d8 100644
--- a/src/tools/clippy/tests/ui/literals.rs
+++ b/src/tools/clippy/tests/ui/literals.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
// does not test any rustfixable lints
#![warn(clippy::mixed_case_hex_literals)]
@@ -10,16 +11,32 @@ fn main() {
let ok1 = 0xABCD;
let ok3 = 0xab_cd;
let ok4 = 0xab_cd_i32;
+ //~^ ERROR: integer type suffix should not be separated by an underscore
+ //~| NOTE: `-D clippy::separated-literal-suffix` implied by `-D warnings`
let ok5 = 0xAB_CD_u32;
+ //~^ ERROR: integer type suffix should not be separated by an underscore
let ok5 = 0xAB_CD_isize;
+ //~^ ERROR: integer type suffix should not be separated by an underscore
let fail1 = 0xabCD;
+ //~^ ERROR: inconsistent casing in hexadecimal literal
+ //~| NOTE: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
let fail2 = 0xabCD_u32;
+ //~^ ERROR: integer type suffix should not be separated by an underscore
+ //~| ERROR: inconsistent casing in hexadecimal literal
let fail2 = 0xabCD_isize;
+ //~^ ERROR: integer type suffix should not be separated by an underscore
+ //~| ERROR: inconsistent casing in hexadecimal literal
let fail_multi_zero = 000_123usize;
+ //~^ ERROR: integer type suffix should be separated by an underscore
+ //~| NOTE: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
+ //~| ERROR: this is a decimal constant
+ //~| NOTE: `-D clippy::zero-prefixed-literal` implied by `-D warnings`
let ok9 = 0;
let ok10 = 0_i64;
+ //~^ ERROR: integer type suffix should not be separated by an underscore
let fail8 = 0123;
+ //~^ ERROR: this is a decimal constant
let ok11 = 0o123;
let ok12 = 0b10_1010;
@@ -29,13 +46,20 @@ fn main() {
let ok15 = 0xab_cabc_abca_bcab_cabc;
let ok16 = 0xFE_BAFE_ABAB_ABCD;
let ok17 = 0x123_4567_8901_usize;
+ //~^ ERROR: integer type suffix should not be separated by an underscore
let ok18 = 0xF;
let fail19 = 12_3456_21;
+ //~^ ERROR: digits grouped inconsistently by underscores
+ //~| NOTE: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
let fail22 = 3__4___23;
+ //~^ ERROR: digits grouped inconsistently by underscores
let fail23 = 3__16___23;
+ //~^ ERROR: digits grouped inconsistently by underscores
let fail24 = 0xAB_ABC_AB;
+ //~^ ERROR: digits of hex, binary or octal literal not in groups of equal size
+ //~| NOTE: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
let fail25 = 0b01_100_101;
let ok26 = 0x6_A0_BF;
let ok27 = 0b1_0010_0101;
@@ -44,6 +68,9 @@ fn main() {
fn issue9651() {
// lint but octal form is not possible here
let _ = 08;
+ //~^ ERROR: this is a decimal constant
let _ = 09;
+ //~^ ERROR: this is a decimal constant
let _ = 089;
+ //~^ ERROR: this is a decimal constant
}
diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr
index 9bc7948c7..bc755b112 100644
--- a/src/tools/clippy/tests/ui/literals.stderr
+++ b/src/tools/clippy/tests/ui/literals.stderr
@@ -1,70 +1,74 @@
error: integer type suffix should not be separated by an underscore
- --> $DIR/literals.rs:12:15
+ --> $DIR/literals.rs:13:15
|
LL | let ok4 = 0xab_cd_i32;
| ^^^^^^^^^^^ help: remove the underscore: `0xab_cdi32`
|
= note: `-D clippy::separated-literal-suffix` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::separated_literal_suffix)]`
error: integer type suffix should not be separated by an underscore
- --> $DIR/literals.rs:13:15
+ --> $DIR/literals.rs:16:15
|
LL | let ok5 = 0xAB_CD_u32;
| ^^^^^^^^^^^ help: remove the underscore: `0xAB_CDu32`
error: integer type suffix should not be separated by an underscore
- --> $DIR/literals.rs:14:15
+ --> $DIR/literals.rs:18:15
|
LL | let ok5 = 0xAB_CD_isize;
| ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CDisize`
error: inconsistent casing in hexadecimal literal
- --> $DIR/literals.rs:15:17
+ --> $DIR/literals.rs:20:17
|
LL | let fail1 = 0xabCD;
| ^^^^^^
|
= note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mixed_case_hex_literals)]`
error: integer type suffix should not be separated by an underscore
- --> $DIR/literals.rs:16:17
+ --> $DIR/literals.rs:23:17
|
LL | let fail2 = 0xabCD_u32;
| ^^^^^^^^^^ help: remove the underscore: `0xabCDu32`
error: inconsistent casing in hexadecimal literal
- --> $DIR/literals.rs:16:17
+ --> $DIR/literals.rs:23:17
|
LL | let fail2 = 0xabCD_u32;
| ^^^^^^^^^^
error: integer type suffix should not be separated by an underscore
- --> $DIR/literals.rs:17:17
+ --> $DIR/literals.rs:26:17
|
LL | let fail2 = 0xabCD_isize;
| ^^^^^^^^^^^^ help: remove the underscore: `0xabCDisize`
error: inconsistent casing in hexadecimal literal
- --> $DIR/literals.rs:17:17
+ --> $DIR/literals.rs:26:17
|
LL | let fail2 = 0xabCD_isize;
| ^^^^^^^^^^^^
error: integer type suffix should be separated by an underscore
- --> $DIR/literals.rs:18:27
+ --> $DIR/literals.rs:29:27
|
LL | let fail_multi_zero = 000_123usize;
| ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`
|
= note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]`
error: this is a decimal constant
- --> $DIR/literals.rs:18:27
+ --> $DIR/literals.rs:29:27
|
LL | let fail_multi_zero = 000_123usize;
| ^^^^^^^^^^^^
|
= note: `-D clippy::zero-prefixed-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::zero_prefixed_literal)]`
help: if you mean to use a decimal constant, remove the `0` to avoid confusion
|
LL | let fail_multi_zero = 123usize;
@@ -75,13 +79,13 @@ LL | let fail_multi_zero = 0o123usize;
| ~~~~~~~~~~
error: integer type suffix should not be separated by an underscore
- --> $DIR/literals.rs:21:16
+ --> $DIR/literals.rs:36:16
|
LL | let ok10 = 0_i64;
| ^^^^^ help: remove the underscore: `0i64`
error: this is a decimal constant
- --> $DIR/literals.rs:22:17
+ --> $DIR/literals.rs:38:17
|
LL | let fail8 = 0123;
| ^^^^
@@ -96,41 +100,43 @@ LL | let fail8 = 0o123;
| ~~~~~
error: integer type suffix should not be separated by an underscore
- --> $DIR/literals.rs:31:16
+ --> $DIR/literals.rs:48:16
|
LL | let ok17 = 0x123_4567_8901_usize;
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize`
error: digits grouped inconsistently by underscores
- --> $DIR/literals.rs:34:18
+ --> $DIR/literals.rs:52:18
|
LL | let fail19 = 12_3456_21;
| ^^^^^^^^^^ help: consider: `12_345_621`
|
= note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`
error: digits grouped inconsistently by underscores
- --> $DIR/literals.rs:35:18
+ --> $DIR/literals.rs:55:18
|
LL | let fail22 = 3__4___23;
| ^^^^^^^^^ help: consider: `3_423`
error: digits grouped inconsistently by underscores
- --> $DIR/literals.rs:36:18
+ --> $DIR/literals.rs:57:18
|
LL | let fail23 = 3__16___23;
| ^^^^^^^^^^ help: consider: `31_623`
error: digits of hex, binary or octal literal not in groups of equal size
- --> $DIR/literals.rs:38:18
+ --> $DIR/literals.rs:60:18
|
LL | let fail24 = 0xAB_ABC_AB;
| ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
|
= note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]`
error: this is a decimal constant
- --> $DIR/literals.rs:46:13
+ --> $DIR/literals.rs:70:13
|
LL | let _ = 08;
| ^^
@@ -141,7 +147,7 @@ LL | let _ = 8;
| ~
error: this is a decimal constant
- --> $DIR/literals.rs:47:13
+ --> $DIR/literals.rs:72:13
|
LL | let _ = 09;
| ^^
@@ -152,7 +158,7 @@ LL | let _ = 9;
| ~
error: this is a decimal constant
- --> $DIR/literals.rs:48:13
+ --> $DIR/literals.rs:74:13
|
LL | let _ = 089;
| ^^^
diff --git a/src/tools/clippy/tests/ui/lossy_float_literal.fixed b/src/tools/clippy/tests/ui/lossy_float_literal.fixed
index e19f4980c..92a0084a6 100644
--- a/src/tools/clippy/tests/ui/lossy_float_literal.fixed
+++ b/src/tools/clippy/tests/ui/lossy_float_literal.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::lossy_float_literal)]
#![allow(overflowing_literals, unused)]
diff --git a/src/tools/clippy/tests/ui/lossy_float_literal.rs b/src/tools/clippy/tests/ui/lossy_float_literal.rs
index a2a1cfb31..5abef3c44 100644
--- a/src/tools/clippy/tests/ui/lossy_float_literal.rs
+++ b/src/tools/clippy/tests/ui/lossy_float_literal.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::lossy_float_literal)]
#![allow(overflowing_literals, unused)]
diff --git a/src/tools/clippy/tests/ui/lossy_float_literal.stderr b/src/tools/clippy/tests/ui/lossy_float_literal.stderr
index 2d72b1643..ea787f572 100644
--- a/src/tools/clippy/tests/ui/lossy_float_literal.stderr
+++ b/src/tools/clippy/tests/ui/lossy_float_literal.stderr
@@ -1,67 +1,68 @@
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:7:18
+ --> $DIR/lossy_float_literal.rs:6:18
|
LL | let _: f32 = 16_777_217.0;
| ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_216.0`
|
= note: `-D clippy::lossy-float-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::lossy_float_literal)]`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:8:18
+ --> $DIR/lossy_float_literal.rs:7:18
|
LL | let _: f32 = 16_777_219.0;
| ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:9:18
+ --> $DIR/lossy_float_literal.rs:8:18
|
LL | let _: f32 = 16_777_219.;
| ^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:10:18
+ --> $DIR/lossy_float_literal.rs:9:18
|
LL | let _: f32 = 16_777_219.000;
| ^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:11:13
+ --> $DIR/lossy_float_literal.rs:10:13
|
LL | let _ = 16_777_219f32;
| ^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220_f32`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:12:19
+ --> $DIR/lossy_float_literal.rs:11:19
|
LL | let _: f32 = -16_777_219.0;
| ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:13:18
+ --> $DIR/lossy_float_literal.rs:12:18
|
LL | let _: f64 = 9_007_199_254_740_993.0;
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:14:18
+ --> $DIR/lossy_float_literal.rs:13:18
|
LL | let _: f64 = 9_007_199_254_740_993.;
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:15:18
+ --> $DIR/lossy_float_literal.rs:14:18
|
LL | let _: f64 = 9_007_199_254_740_993.00;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:16:13
+ --> $DIR/lossy_float_literal.rs:15:13
|
LL | let _ = 9_007_199_254_740_993f64;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992_f64`
error: literal cannot be represented as the underlying type without loss of precision
- --> $DIR/lossy_float_literal.rs:17:19
+ --> $DIR/lossy_float_literal.rs:16:19
|
LL | let _: f64 = -9_007_199_254_740_993.0;
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0`
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.fixed b/src/tools/clippy/tests/ui/macro_use_imports.fixed
index 53b6a0250..46c053b77 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.fixed
+++ b/src/tools/clippy/tests/ui/macro_use_imports.fixed
@@ -1,7 +1,7 @@
//@aux-build:macro_rules.rs
//@aux-build:macro_use_helper.rs
-//@aux-build:proc_macro_derive.rs:proc-macro
-//@run-rustfix
+//@aux-build:proc_macro_derive.rs
+
//@ignore-32bit
#![feature(lint_reasons)]
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.rs b/src/tools/clippy/tests/ui/macro_use_imports.rs
index a40fa3898..47f5c9bf8 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.rs
+++ b/src/tools/clippy/tests/ui/macro_use_imports.rs
@@ -1,7 +1,7 @@
//@aux-build:macro_rules.rs
//@aux-build:macro_use_helper.rs
-//@aux-build:proc_macro_derive.rs:proc-macro
-//@run-rustfix
+//@aux-build:proc_macro_derive.rs
+
//@ignore-32bit
#![feature(lint_reasons)]
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.stderr b/src/tools/clippy/tests/ui/macro_use_imports.stderr
index 67a833e85..6de869699 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.stderr
+++ b/src/tools/clippy/tests/ui/macro_use_imports.stderr
@@ -1,10 +1,11 @@
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
- --> $DIR/macro_use_imports.rs:19:5
+ --> $DIR/macro_use_imports.rs:25:5
|
LL | #[macro_use]
- | ^^^^^^^^^^^^ 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};`
+ | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
|
= note: `-D clippy::macro-use-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::macro_use_imports)]`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:23:5
@@ -13,16 +14,16 @@ LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
- --> $DIR/macro_use_imports.rs:25:5
+ --> $DIR/macro_use_imports.rs:21:5
|
LL | #[macro_use]
- | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
+ | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
- --> $DIR/macro_use_imports.rs:21:5
+ --> $DIR/macro_use_imports.rs:19:5
|
LL | #[macro_use]
- | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
+ | ^^^^^^^^^^^^ 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};`
error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs
index 3971aadbe..b9677851b 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs
+++ b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs
@@ -1,6 +1,6 @@
//@aux-build:macro_rules.rs
//@aux-build:macro_use_helper.rs
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
//@ignore-32bit
#![feature(lint_reasons)]
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
index d8dde0236..75beedfa4 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
@@ -1,7 +1,6 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
#![warn(clippy::manual_assert)]
#![allow(dead_code, unused_doc_comments)]
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
index 3555ac292..b19cca4d5 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
@@ -1,5 +1,5 @@
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:31:5
+ --> $DIR/manual_assert.rs:30:5
|
LL | / if !a.is_empty() {
LL | | panic!("qaqaq{:?}", a);
@@ -7,9 +7,10 @@ LL | | }
| |_____^ help: try instead: `assert!(a.is_empty(), "qaqaq{:?}", a);`
|
= note: `-D clippy::manual-assert` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:34:5
+ --> $DIR/manual_assert.rs:33:5
|
LL | / if !a.is_empty() {
LL | | panic!("qwqwq");
@@ -17,7 +18,7 @@ LL | | }
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:51:5
+ --> $DIR/manual_assert.rs:50:5
|
LL | / if b.is_empty() {
LL | | panic!("panic1");
@@ -25,7 +26,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:54:5
+ --> $DIR/manual_assert.rs:53:5
|
LL | / if b.is_empty() && a.is_empty() {
LL | | panic!("panic2");
@@ -33,7 +34,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:57:5
+ --> $DIR/manual_assert.rs:56:5
|
LL | / if a.is_empty() && !b.is_empty() {
LL | | panic!("panic3");
@@ -41,7 +42,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:60:5
+ --> $DIR/manual_assert.rs:59:5
|
LL | / if b.is_empty() || a.is_empty() {
LL | | panic!("panic4");
@@ -49,7 +50,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:63:5
+ --> $DIR/manual_assert.rs:62:5
|
LL | / if a.is_empty() || !b.is_empty() {
LL | | panic!("panic5");
@@ -57,7 +58,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:66:5
+ --> $DIR/manual_assert.rs:65:5
|
LL | / if a.is_empty() {
LL | | panic!("with expansion {}", one!())
@@ -65,7 +66,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:78:5
+ --> $DIR/manual_assert.rs:77:5
|
LL | / if a > 2 {
LL | | // comment
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
index d8dde0236..75beedfa4 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
@@ -1,7 +1,6 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
#![warn(clippy::manual_assert)]
#![allow(dead_code, unused_doc_comments)]
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
index 3555ac292..b19cca4d5 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
@@ -1,5 +1,5 @@
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:31:5
+ --> $DIR/manual_assert.rs:30:5
|
LL | / if !a.is_empty() {
LL | | panic!("qaqaq{:?}", a);
@@ -7,9 +7,10 @@ LL | | }
| |_____^ help: try instead: `assert!(a.is_empty(), "qaqaq{:?}", a);`
|
= note: `-D clippy::manual-assert` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:34:5
+ --> $DIR/manual_assert.rs:33:5
|
LL | / if !a.is_empty() {
LL | | panic!("qwqwq");
@@ -17,7 +18,7 @@ LL | | }
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:51:5
+ --> $DIR/manual_assert.rs:50:5
|
LL | / if b.is_empty() {
LL | | panic!("panic1");
@@ -25,7 +26,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:54:5
+ --> $DIR/manual_assert.rs:53:5
|
LL | / if b.is_empty() && a.is_empty() {
LL | | panic!("panic2");
@@ -33,7 +34,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:57:5
+ --> $DIR/manual_assert.rs:56:5
|
LL | / if a.is_empty() && !b.is_empty() {
LL | | panic!("panic3");
@@ -41,7 +42,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:60:5
+ --> $DIR/manual_assert.rs:59:5
|
LL | / if b.is_empty() || a.is_empty() {
LL | | panic!("panic4");
@@ -49,7 +50,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:63:5
+ --> $DIR/manual_assert.rs:62:5
|
LL | / if a.is_empty() || !b.is_empty() {
LL | | panic!("panic5");
@@ -57,7 +58,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:66:5
+ --> $DIR/manual_assert.rs:65:5
|
LL | / if a.is_empty() {
LL | | panic!("with expansion {}", one!())
@@ -65,7 +66,7 @@ LL | | }
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
error: only a `panic!` in `if`-then statement
- --> $DIR/manual_assert.rs:78:5
+ --> $DIR/manual_assert.rs:77:5
|
LL | / if a > 2 {
LL | | // comment
diff --git a/src/tools/clippy/tests/ui/manual_assert.rs b/src/tools/clippy/tests/ui/manual_assert.rs
index 0f87d6e2d..5979496ca 100644
--- a/src/tools/clippy/tests/ui/manual_assert.rs
+++ b/src/tools/clippy/tests/ui/manual_assert.rs
@@ -1,7 +1,6 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
#![warn(clippy::manual_assert)]
#![allow(dead_code, unused_doc_comments)]
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed
index e609b4b1b..18444090a 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.fixed
+++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_async_fn)]
#![allow(clippy::needless_pub_self, unused)]
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs
index 6c1a9edaa..d42165bbe 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.rs
+++ b/src/tools/clippy/tests/ui/manual_async_fn.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_async_fn)]
#![allow(clippy::needless_pub_self, unused)]
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr
index f5ee3eb7c..c0c471912 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.stderr
+++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr
@@ -1,10 +1,11 @@
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:7:1
+ --> $DIR/manual_async_fn.rs:6:1
|
LL | fn fut() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::manual-async-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_async_fn)]`
help: make the function `async` and return the output of the future directly
|
LL | async fn fut() -> i32 {
@@ -15,7 +16,7 @@ LL | fn fut() -> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:12:1
+ --> $DIR/manual_async_fn.rs:11:1
|
LL | fn fut2() ->impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,7 +31,7 @@ LL | fn fut2() ->impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:17:1
+ --> $DIR/manual_async_fn.rs:16:1
|
LL | fn fut3()-> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | fn fut3()-> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:21:1
+ --> $DIR/manual_async_fn.rs:20:1
|
LL | fn empty_fut() -> impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL | fn empty_fut() -> impl Future<Output = ()> {}
| ~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:26:1
+ --> $DIR/manual_async_fn.rs:25:1
|
LL | fn empty_fut2() ->impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -75,7 +76,7 @@ LL | fn empty_fut2() ->impl Future<Output = ()> {}
| ~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:31:1
+ --> $DIR/manual_async_fn.rs:30:1
|
LL | fn empty_fut3()-> impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +91,7 @@ LL | fn empty_fut3()-> impl Future<Output = ()> {}
| ~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:35:1
+ --> $DIR/manual_async_fn.rs:34:1
|
LL | fn core_fut() -> impl core::future::Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -105,7 +106,7 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:57:5
+ --> $DIR/manual_async_fn.rs:56:5
|
LL | fn inh_fut() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,7 +133,7 @@ LL + }
|
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:92:1
+ --> $DIR/manual_async_fn.rs:91:1
|
LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -147,7 +148,7 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:101:1
+ --> $DIR/manual_async_fn.rs:100:1
|
LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -162,7 +163,7 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> +
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:130:1
+ --> $DIR/manual_async_fn.rs:129:1
|
LL | pub fn issue_10450() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,7 +178,7 @@ LL | pub fn issue_10450() -> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:134:1
+ --> $DIR/manual_async_fn.rs:133:1
|
LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -192,7 +193,7 @@ LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> { 42 }
| ~~~~~~
error: this function can be simplified using the `async fn` syntax
- --> $DIR/manual_async_fn.rs:138:1
+ --> $DIR/manual_async_fn.rs:137:1
|
LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/manual_bits.fixed b/src/tools/clippy/tests/ui/manual_bits.fixed
index 037de0262..4de01905e 100644
--- a/src/tools/clippy/tests/ui/manual_bits.fixed
+++ b/src/tools/clippy/tests/ui/manual_bits.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_bits)]
#![allow(
clippy::no_effect,
diff --git a/src/tools/clippy/tests/ui/manual_bits.rs b/src/tools/clippy/tests/ui/manual_bits.rs
index b15a531ec..d4f369fcf 100644
--- a/src/tools/clippy/tests/ui/manual_bits.rs
+++ b/src/tools/clippy/tests/ui/manual_bits.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_bits)]
#![allow(
clippy::no_effect,
diff --git a/src/tools/clippy/tests/ui/manual_bits.stderr b/src/tools/clippy/tests/ui/manual_bits.stderr
index 652fafbc4..2f2ed5909 100644
--- a/src/tools/clippy/tests/ui/manual_bits.stderr
+++ b/src/tools/clippy/tests/ui/manual_bits.stderr
@@ -1,175 +1,176 @@
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:16:5
+ --> $DIR/manual_bits.rs:14:5
|
LL | size_of::<i8>() * 8;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
|
= note: `-D clippy::manual-bits` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_bits)]`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:17:5
+ --> $DIR/manual_bits.rs:15:5
|
LL | size_of::<i16>() * 8;
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:18:5
+ --> $DIR/manual_bits.rs:16:5
|
LL | size_of::<i32>() * 8;
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:19:5
+ --> $DIR/manual_bits.rs:17:5
|
LL | size_of::<i64>() * 8;
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:20:5
+ --> $DIR/manual_bits.rs:18:5
|
LL | size_of::<i128>() * 8;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:21:5
+ --> $DIR/manual_bits.rs:19:5
|
LL | size_of::<isize>() * 8;
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:23:5
+ --> $DIR/manual_bits.rs:21:5
|
LL | size_of::<u8>() * 8;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:24:5
+ --> $DIR/manual_bits.rs:22:5
|
LL | size_of::<u16>() * 8;
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:25:5
+ --> $DIR/manual_bits.rs:23:5
|
LL | size_of::<u32>() * 8;
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:26:5
+ --> $DIR/manual_bits.rs:24:5
|
LL | size_of::<u64>() * 8;
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:27:5
+ --> $DIR/manual_bits.rs:25:5
|
LL | size_of::<u128>() * 8;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:28:5
+ --> $DIR/manual_bits.rs:26:5
|
LL | size_of::<usize>() * 8;
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:30:5
+ --> $DIR/manual_bits.rs:28:5
|
LL | 8 * size_of::<i8>();
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:31:5
+ --> $DIR/manual_bits.rs:29:5
|
LL | 8 * size_of::<i16>();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:32:5
+ --> $DIR/manual_bits.rs:30:5
|
LL | 8 * size_of::<i32>();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:33:5
+ --> $DIR/manual_bits.rs:31:5
|
LL | 8 * size_of::<i64>();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:34:5
+ --> $DIR/manual_bits.rs:32:5
|
LL | 8 * size_of::<i128>();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:35:5
+ --> $DIR/manual_bits.rs:33:5
|
LL | 8 * size_of::<isize>();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:37:5
+ --> $DIR/manual_bits.rs:35:5
|
LL | 8 * size_of::<u8>();
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:38:5
+ --> $DIR/manual_bits.rs:36:5
|
LL | 8 * size_of::<u16>();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:39:5
+ --> $DIR/manual_bits.rs:37:5
|
LL | 8 * size_of::<u32>();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:40:5
+ --> $DIR/manual_bits.rs:38:5
|
LL | 8 * size_of::<u64>();
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:41:5
+ --> $DIR/manual_bits.rs:39:5
|
LL | 8 * size_of::<u128>();
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:42:5
+ --> $DIR/manual_bits.rs:40:5
|
LL | 8 * size_of::<usize>();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:52:5
+ --> $DIR/manual_bits.rs:50:5
|
LL | size_of::<Word>() * 8;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:56:18
+ --> $DIR/manual_bits.rs:54:18
|
LL | let _: u32 = (size_of::<u128>() * 8) as u32;
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:57:18
+ --> $DIR/manual_bits.rs:55:18
|
LL | let _: u32 = (size_of::<u128>() * 8).try_into().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:58:13
+ --> $DIR/manual_bits.rs:56:13
|
LL | let _ = (size_of::<u128>() * 8).pow(5);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`
error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
- --> $DIR/manual_bits.rs:59:14
+ --> $DIR/manual_bits.rs:57:14
|
LL | let _ = &(size_of::<u128>() * 8);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`
diff --git a/src/tools/clippy/tests/ui/manual_clamp.fixed b/src/tools/clippy/tests/ui/manual_clamp.fixed
new file mode 100644
index 000000000..c5355cce8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_clamp.fixed
@@ -0,0 +1,296 @@
+#![warn(clippy::manual_clamp)]
+#![allow(
+ unused,
+ dead_code,
+ clippy::unnecessary_operation,
+ clippy::no_effect,
+ clippy::if_same_then_else
+)]
+
+use std::cmp::{max as cmp_max, min as cmp_min};
+
+const CONST_MAX: i32 = 10;
+const CONST_MIN: i32 = 4;
+
+const CONST_F64_MAX: f64 = 10.0;
+const CONST_F64_MIN: f64 = 4.0;
+
+fn main() {
+ let (input, min, max) = (0, -2, 3);
+ // Lint
+ let x0 = input.clamp(min, max);
+
+ let x1 = input.clamp(min, max);
+
+ let x2 = input.clamp(min, max);
+
+ let x3 = input.clamp(min, max);
+
+ let x4 = input.clamp(min, max);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+
+ let x5 = input.clamp(min, max);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+
+ let x6 = input.clamp(min, max);
+
+ let x7 = input.clamp(min, max);
+
+ let x8 = input.clamp(min, max);
+
+ let mut x9 = input;
+ x9 = x9.clamp(min, max);
+
+ let x10 = input.clamp(min, max);
+
+ let mut x11 = input;
+ let _ = 1;
+ x11 = x11.clamp(min, max);
+
+ let mut x12 = input;
+ x12 = x12.clamp(min, max);
+
+ let mut x13 = input;
+ x13 = x13.clamp(min, max);
+
+ let x14 = input.clamp(CONST_MIN, CONST_MAX);
+ {
+ let (input, min, max) = (0.0f64, -2.0, 3.0);
+ let x15 = input.clamp(min, max);
+ }
+ {
+ let input: i32 = cmp_min_max(1);
+ // These can only be detected if exactly one of the arguments to the inner function is const.
+ let x16 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let x17 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let x18 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let x19 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let x20 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let x21 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let x22 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let x23 = input.clamp(CONST_MIN, CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
+ let input: f64 = cmp_min_max(1) as f64;
+ let x24 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ let x25 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ let x26 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ let x27 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ let x28 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ let x29 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ let x30 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ let x31 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
+ }
+ let mut x32 = input;
+ x32 = x32.clamp(min, max);
+
+ // It's important this be the last set of statements
+ let mut x33 = input;
+ x33 = x33.clamp(min, max);
+}
+
+// This code intentionally nonsense.
+fn no_lint() {
+ let (input, min, max) = (0, -2, 3);
+ let x0 = if max < input {
+ max
+ } else if min > input {
+ max
+ } else {
+ min
+ };
+
+ let x1 = if input > max {
+ max
+ } else if input > min {
+ min
+ } else {
+ max
+ };
+
+ let x2 = if max < min {
+ min
+ } else if input > max {
+ input
+ } else {
+ input
+ };
+
+ let x3 = if min > input {
+ input
+ } else if max < input {
+ max
+ } else {
+ max
+ };
+
+ let x6 = match input {
+ x if x < max => x,
+ x if x < min => x,
+ x => x,
+ };
+
+ let x7 = match input {
+ x if x < min => max,
+ x if x > max => min,
+ x => x,
+ };
+
+ let x8 = match input {
+ x if max > x => max,
+ x if min > x => min,
+ x => x,
+ };
+
+ let mut x9 = input;
+ if x9 > min {
+ x9 = min;
+ }
+ if x9 > max {
+ x9 = max;
+ }
+
+ let x10 = match input {
+ x if min > x => min,
+ x if max < x => max,
+ x => min,
+ };
+
+ let mut x11 = input;
+ if x11 > max {
+ x11 = min;
+ }
+ if x11 < min {
+ x11 = max;
+ }
+
+ let mut x12 = input;
+ if min > x12 {
+ x12 = max * 3;
+ }
+ if max < x12 {
+ x12 = min;
+ }
+
+ let mut x13 = input;
+ if max < x13 {
+ let x13 = max;
+ }
+ if min > x13 {
+ x13 = min;
+ }
+ let mut x14 = input;
+ if x14 < min {
+ x14 = 3;
+ } else if x14 > max {
+ x14 = max;
+ }
+ {
+ let input: i32 = cmp_min_max(1);
+ // These can only be detected if exactly one of the arguments to the inner function is const.
+ let x16 = cmp_max(cmp_max(input, CONST_MAX), CONST_MIN);
+ let x17 = cmp_min(cmp_min(input, CONST_MIN), CONST_MAX);
+ let x18 = cmp_max(CONST_MIN, cmp_max(input, CONST_MAX));
+ let x19 = cmp_min(CONST_MAX, cmp_min(input, CONST_MIN));
+ let x20 = cmp_max(cmp_max(CONST_MAX, input), CONST_MIN);
+ let x21 = cmp_min(cmp_min(CONST_MIN, input), CONST_MAX);
+ let x22 = cmp_max(CONST_MIN, cmp_max(CONST_MAX, input));
+ let x23 = cmp_min(CONST_MAX, cmp_min(CONST_MIN, input));
+ let input: f64 = cmp_min_max(1) as f64;
+ let x24 = f64::max(f64::max(input, CONST_F64_MAX), CONST_F64_MIN);
+ let x25 = f64::min(f64::min(input, CONST_F64_MIN), CONST_F64_MAX);
+ let x26 = f64::max(CONST_F64_MIN, f64::max(input, CONST_F64_MAX));
+ let x27 = f64::min(CONST_F64_MAX, f64::min(input, CONST_F64_MIN));
+ let x28 = f64::max(f64::max(CONST_F64_MAX, input), CONST_F64_MIN);
+ let x29 = f64::min(f64::min(CONST_F64_MIN, input), CONST_F64_MAX);
+ let x30 = f64::max(CONST_F64_MIN, f64::max(CONST_F64_MAX, input));
+ let x31 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, input));
+ let x32 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, CONST_F64_MAX));
+ }
+}
+
+fn dont_tell_me_what_to_do() {
+ let (input, min, max) = (0, -2, 3);
+ let mut x_never = input;
+ #[allow(clippy::manual_clamp)]
+ if x_never < min {
+ x_never = min;
+ }
+ if x_never > max {
+ x_never = max;
+ }
+}
+
+/// Just to ensure this isn't const evaled
+fn cmp_min_max(input: i32) -> i32 {
+ input * 3
+}
+
+#[clippy::msrv = "1.49"]
+fn msrv_1_49() {
+ let (input, min, max) = (0, -1, 2);
+ let _ = if input < min {
+ min
+ } else if input > max {
+ max
+ } else {
+ input
+ };
+}
+
+#[clippy::msrv = "1.50"]
+fn msrv_1_50() {
+ let (input, min, max) = (0, -1, 2);
+ let _ = input.clamp(min, max);
+}
+
+const fn _const() {
+ let (input, min, max) = (0, -1, 2);
+ let _ = if input < min {
+ min
+ } else if input > max {
+ max
+ } else {
+ input
+ };
+
+ let mut x = input;
+ if max < x {
+ let x = max;
+ }
+ if min > x {
+ x = min;
+ }
+}
diff --git a/src/tools/clippy/tests/ui/manual_clamp.rs b/src/tools/clippy/tests/ui/manual_clamp.rs
index cdfd8e4c3..cacb40ae0 100644
--- a/src/tools/clippy/tests/ui/manual_clamp.rs
+++ b/src/tools/clippy/tests/ui/manual_clamp.rs
@@ -19,6 +19,8 @@ fn main() {
let (input, min, max) = (0, -2, 3);
// Lint
let x0 = if max < input {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
max
} else if min > input {
min
@@ -27,6 +29,8 @@ fn main() {
};
let x1 = if input > max {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
max
} else if input < min {
min
@@ -35,6 +39,8 @@ fn main() {
};
let x2 = if input < min {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
min
} else if input > max {
max
@@ -43,6 +49,8 @@ fn main() {
};
let x3 = if min > input {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
min
} else if max < input {
max
@@ -51,22 +59,32 @@ fn main() {
};
let x4 = input.max(min).min(max);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x5 = input.min(max).max(min);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x6 = match input {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x if x > max => max,
x if x < min => min,
x => x,
};
let x7 = match input {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x if x < min => min,
x if x > max => max,
x => x,
};
let x8 = match input {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x if max < x => max,
x if min > x => min,
x => x,
@@ -74,6 +92,8 @@ fn main() {
let mut x9 = input;
if x9 < min {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x9 = min;
}
if x9 > max {
@@ -81,6 +101,8 @@ fn main() {
}
let x10 = match input {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x if min > x => min,
x if max < x => max,
x => x,
@@ -89,6 +111,8 @@ fn main() {
let mut x11 = input;
let _ = 1;
if x11 > max {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x11 = max;
}
if x11 < min {
@@ -97,6 +121,8 @@ fn main() {
let mut x12 = input;
if min > x12 {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x12 = min;
}
if max < x12 {
@@ -105,6 +131,8 @@ fn main() {
let mut x13 = input;
if max < x13 {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x13 = max;
}
if min > x13 {
@@ -112,6 +140,8 @@ fn main() {
}
let x14 = if input > CONST_MAX {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
CONST_MAX
} else if input < CONST_MIN {
CONST_MIN
@@ -121,6 +151,8 @@ fn main() {
{
let (input, min, max) = (0.0f64, -2.0, 3.0);
let x15 = if input > max {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
max
} else if input < min {
min
@@ -132,25 +164,59 @@ fn main() {
let input: i32 = cmp_min_max(1);
// These can only be detected if exactly one of the arguments to the inner function is const.
let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
let input: f64 = cmp_min_max(1) as f64;
let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
}
let mut x32 = input;
if x32 < min {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x32 = min;
} else if x32 > max {
x32 = max;
@@ -159,6 +225,8 @@ fn main() {
// It's important this be the last set of statements
let mut x33 = input;
if max < x33 {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
x33 = max;
}
if min > x33 {
@@ -319,6 +387,8 @@ fn msrv_1_49() {
fn msrv_1_50() {
let (input, min, max) = (0, -1, 2);
let _ = if input < min {
+ //~^ ERROR: clamp-like pattern without using clamp function
+ //~| NOTE: clamp will panic if max < min
min
} else if input > max {
max
diff --git a/src/tools/clippy/tests/ui/manual_clamp.stderr b/src/tools/clippy/tests/ui/manual_clamp.stderr
index 988ad1527..2fa68ede1 100644
--- a/src/tools/clippy/tests/ui/manual_clamp.stderr
+++ b/src/tools/clippy/tests/ui/manual_clamp.stderr
@@ -1,24 +1,27 @@
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:76:5
+ --> $DIR/manual_clamp.rs:94:5
|
LL | / if x9 < min {
+LL | |
+LL | |
LL | | x9 = min;
-LL | | }
-LL | | if x9 > max {
+... |
LL | | x9 = max;
LL | | }
| |_____^ help: replace with clamp: `x9 = x9.clamp(min, max);`
|
= note: clamp will panic if max < min
= note: `-D clippy::manual-clamp` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_clamp)]`
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:91:5
+ --> $DIR/manual_clamp.rs:113:5
|
LL | / if x11 > max {
+LL | |
+LL | |
LL | | x11 = max;
-LL | | }
-LL | | if x11 < min {
+... |
LL | | x11 = min;
LL | | }
| |_____^ help: replace with clamp: `x11 = x11.clamp(min, max);`
@@ -26,12 +29,13 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:99:5
+ --> $DIR/manual_clamp.rs:123:5
|
LL | / if min > x12 {
+LL | |
+LL | |
LL | | x12 = min;
-LL | | }
-LL | | if max < x12 {
+... |
LL | | x12 = max;
LL | | }
| |_____^ help: replace with clamp: `x12 = x12.clamp(min, max);`
@@ -39,12 +43,13 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:107:5
+ --> $DIR/manual_clamp.rs:133:5
|
LL | / if max < x13 {
+LL | |
+LL | |
LL | | x13 = max;
-LL | | }
-LL | | if min > x13 {
+... |
LL | | x13 = min;
LL | | }
| |_____^ help: replace with clamp: `x13 = x13.clamp(min, max);`
@@ -52,12 +57,13 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:161:5
+ --> $DIR/manual_clamp.rs:227:5
|
LL | / if max < x33 {
+LL | |
+LL | |
LL | | x33 = max;
-LL | | }
-LL | | if min > x33 {
+... |
LL | | x33 = min;
LL | | }
| |_____^ help: replace with clamp: `x33 = x33.clamp(min, max);`
@@ -69,10 +75,10 @@ error: clamp-like pattern without using clamp function
|
LL | let x0 = if max < input {
| ______________^
+LL | |
+LL | |
LL | | max
-LL | | } else if min > input {
-LL | | min
-LL | | } else {
+... |
LL | | input
LL | | };
| |_____^ help: replace with clamp: `input.clamp(min, max)`
@@ -80,14 +86,14 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:29:14
+ --> $DIR/manual_clamp.rs:31:14
|
LL | let x1 = if input > max {
| ______________^
+LL | |
+LL | |
LL | | max
-LL | | } else if input < min {
-LL | | min
-LL | | } else {
+... |
LL | | input
LL | | };
| |_____^ help: replace with clamp: `input.clamp(min, max)`
@@ -95,14 +101,14 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:37:14
+ --> $DIR/manual_clamp.rs:41:14
|
LL | let x2 = if input < min {
| ______________^
+LL | |
+LL | |
LL | | min
-LL | | } else if input > max {
-LL | | max
-LL | | } else {
+... |
LL | | input
LL | | };
| |_____^ help: replace with clamp: `input.clamp(min, max)`
@@ -110,14 +116,14 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:45:14
+ --> $DIR/manual_clamp.rs:51:14
|
LL | let x3 = if min > input {
| ______________^
+LL | |
+LL | |
LL | | min
-LL | | } else if max < input {
-LL | | max
-LL | | } else {
+... |
LL | | input
LL | | };
| |_____^ help: replace with clamp: `input.clamp(min, max)`
@@ -125,7 +131,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:53:14
+ --> $DIR/manual_clamp.rs:61:14
|
LL | let x4 = input.max(min).min(max);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
@@ -133,7 +139,7 @@ LL | let x4 = input.max(min).min(max);
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:55:14
+ --> $DIR/manual_clamp.rs:65:14
|
LL | let x5 = input.min(max).max(min);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
@@ -141,10 +147,12 @@ LL | let x5 = input.min(max).max(min);
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:57:14
+ --> $DIR/manual_clamp.rs:69:14
|
LL | let x6 = match input {
| ______________^
+LL | |
+LL | |
LL | | x if x > max => max,
LL | | x if x < min => min,
LL | | x => x,
@@ -154,10 +162,12 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:63:14
+ --> $DIR/manual_clamp.rs:77:14
|
LL | let x7 = match input {
| ______________^
+LL | |
+LL | |
LL | | x if x < min => min,
LL | | x if x > max => max,
LL | | x => x,
@@ -167,10 +177,12 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:69:14
+ --> $DIR/manual_clamp.rs:85:14
|
LL | let x8 = match input {
| ______________^
+LL | |
+LL | |
LL | | x if max < x => max,
LL | | x if min > x => min,
LL | | x => x,
@@ -180,10 +192,12 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:83:15
+ --> $DIR/manual_clamp.rs:103:15
|
LL | let x10 = match input {
| _______________^
+LL | |
+LL | |
LL | | x if min > x => min,
LL | | x if max < x => max,
LL | | x => x,
@@ -193,14 +207,14 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:114:15
+ --> $DIR/manual_clamp.rs:142:15
|
LL | let x14 = if input > CONST_MAX {
| _______________^
+LL | |
+LL | |
LL | | CONST_MAX
-LL | | } else if input < CONST_MIN {
-LL | | CONST_MIN
-LL | | } else {
+... |
LL | | input
LL | | };
| |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -208,14 +222,14 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:123:19
+ --> $DIR/manual_clamp.rs:153:19
|
LL | let x15 = if input > max {
| ___________________^
+LL | |
+LL | |
LL | | max
-LL | | } else if input < min {
-LL | | min
-LL | | } else {
+... |
LL | | input
LL | | };
| |_________^ help: replace with clamp: `input.clamp(min, max)`
@@ -224,7 +238,7 @@ LL | | };
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:134:19
+ --> $DIR/manual_clamp.rs:166:19
|
LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -232,7 +246,7 @@ LL | let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:135:19
+ --> $DIR/manual_clamp.rs:169:19
|
LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -240,7 +254,7 @@ LL | let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:136:19
+ --> $DIR/manual_clamp.rs:172:19
|
LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -248,7 +262,7 @@ LL | let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:137:19
+ --> $DIR/manual_clamp.rs:175:19
|
LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -256,7 +270,7 @@ LL | let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:138:19
+ --> $DIR/manual_clamp.rs:178:19
|
LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -264,7 +278,7 @@ LL | let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:139:19
+ --> $DIR/manual_clamp.rs:181:19
|
LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -272,7 +286,7 @@ LL | let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:140:19
+ --> $DIR/manual_clamp.rs:184:19
|
LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -280,7 +294,7 @@ LL | let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:141:19
+ --> $DIR/manual_clamp.rs:187:19
|
LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -288,7 +302,7 @@ LL | let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:143:19
+ --> $DIR/manual_clamp.rs:191:19
|
LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -297,7 +311,7 @@ LL | let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:144:19
+ --> $DIR/manual_clamp.rs:194:19
|
LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -306,7 +320,7 @@ LL | let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:145:19
+ --> $DIR/manual_clamp.rs:197:19
|
LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -315,7 +329,7 @@ LL | let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:146:19
+ --> $DIR/manual_clamp.rs:200:19
|
LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -324,7 +338,7 @@ LL | let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:147:19
+ --> $DIR/manual_clamp.rs:203:19
|
LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -333,7 +347,7 @@ LL | let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:148:19
+ --> $DIR/manual_clamp.rs:206:19
|
LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -342,7 +356,7 @@ LL | let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:149:19
+ --> $DIR/manual_clamp.rs:209:19
|
LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -351,7 +365,7 @@ LL | let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:150:19
+ --> $DIR/manual_clamp.rs:212:19
|
LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -360,9 +374,11 @@ LL | let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:153:5
+ --> $DIR/manual_clamp.rs:217:5
|
LL | / if x32 < min {
+LL | |
+LL | |
LL | | x32 = min;
LL | | } else if x32 > max {
LL | | x32 = max;
@@ -372,14 +388,14 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:321:13
+ --> $DIR/manual_clamp.rs:389:13
|
LL | let _ = if input < min {
| _____________^
+LL | |
+LL | |
LL | | min
-LL | | } else if input > max {
-LL | | max
-LL | | } else {
+... |
LL | | input
LL | | };
| |_____^ help: replace with clamp: `input.clamp(min, max)`
diff --git a/src/tools/clippy/tests/ui/manual_filter.fixed b/src/tools/clippy/tests/ui/manual_filter.fixed
index 5e3b12e51..c1bc4aae9 100644
--- a/src/tools/clippy/tests/ui/manual_filter.fixed
+++ b/src/tools/clippy/tests/ui/manual_filter.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_filter)]
#![allow(unused_variables, dead_code, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/manual_filter.rs b/src/tools/clippy/tests/ui/manual_filter.rs
index b81604b03..06968f8ba 100644
--- a/src/tools/clippy/tests/ui/manual_filter.rs
+++ b/src/tools/clippy/tests/ui/manual_filter.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_filter)]
#![allow(unused_variables, dead_code, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/manual_filter.stderr b/src/tools/clippy/tests/ui/manual_filter.stderr
index f62d3e960..1490f2097 100644
--- a/src/tools/clippy/tests/ui/manual_filter.stderr
+++ b/src/tools/clippy/tests/ui/manual_filter.stderr
@@ -1,5 +1,5 @@
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:7:5
+ --> $DIR/manual_filter.rs:5:5
|
LL | / match Some(0) {
LL | | None => None,
@@ -11,9 +11,10 @@ LL | | };
| |_____^ help: try: `Some(0).filter(|&x| x <= 0)`
|
= note: `-D clippy::manual-filter` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_filter)]`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:18:5
+ --> $DIR/manual_filter.rs:16:5
|
LL | / match Some(1) {
LL | | Some(x) => {
@@ -25,7 +26,7 @@ LL | | };
| |_____^ help: try: `Some(1).filter(|&x| x <= 0)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:29:5
+ --> $DIR/manual_filter.rs:27:5
|
LL | / match Some(2) {
LL | | Some(x) => {
@@ -37,7 +38,7 @@ LL | | };
| |_____^ help: try: `Some(2).filter(|&x| x <= 0)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:40:5
+ --> $DIR/manual_filter.rs:38:5
|
LL | / match Some(3) {
LL | | Some(x) => {
@@ -49,7 +50,7 @@ LL | | };
| |_____^ help: try: `Some(3).filter(|&x| x > 0)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:52:5
+ --> $DIR/manual_filter.rs:50:5
|
LL | / match y {
LL | | // Some(4)
@@ -61,7 +62,7 @@ LL | | };
| |_____^ help: try: `y.filter(|&x| x <= 0)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:64:5
+ --> $DIR/manual_filter.rs:62:5
|
LL | / match Some(5) {
LL | | Some(x) => {
@@ -73,7 +74,7 @@ LL | | };
| |_____^ help: try: `Some(5).filter(|&x| x > 0)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:75:5
+ --> $DIR/manual_filter.rs:73:5
|
LL | / match Some(6) {
LL | | Some(ref x) => {
@@ -85,7 +86,7 @@ LL | | };
| |_____^ help: try: `Some(6).as_ref().filter(|&x| x > &0)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:87:5
+ --> $DIR/manual_filter.rs:85:5
|
LL | / match Some(String::new()) {
LL | | Some(x) => {
@@ -97,7 +98,7 @@ LL | | };
| |_____^ help: try: `Some(String::new()).filter(|x| external_cond)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:98:5
+ --> $DIR/manual_filter.rs:96:5
|
LL | / if let Some(x) = Some(7) {
LL | | if external_cond { Some(x) } else { None }
@@ -107,7 +108,7 @@ LL | | };
| |_____^ help: try: `Some(7).filter(|&x| external_cond)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:104:5
+ --> $DIR/manual_filter.rs:102:5
|
LL | / match &Some(8) {
LL | | &Some(x) => {
@@ -119,7 +120,7 @@ LL | | };
| |_____^ help: try: `Some(8).filter(|&x| x != 0)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:115:5
+ --> $DIR/manual_filter.rs:113:5
|
LL | / match Some(9) {
LL | | Some(x) => {
@@ -131,7 +132,7 @@ LL | | };
| |_____^ help: try: `Some(9).filter(|&x| x > 10 && x < 100)`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:141:5
+ --> $DIR/manual_filter.rs:139:5
|
LL | / match Some(11) {
LL | | // Lint, statement is preserved by `.filter`
@@ -151,7 +152,7 @@ LL ~ });
|
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:185:13
+ --> $DIR/manual_filter.rs:183:13
|
LL | let _ = match Some(14) {
| _____________^
@@ -164,7 +165,7 @@ LL | | };
| |_____^ help: try: `Some(14).filter(|&x| unsafe { f(x) })`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:195:13
+ --> $DIR/manual_filter.rs:193:13
|
LL | let _ = match Some(15) {
| _____________^
@@ -176,7 +177,7 @@ LL | | };
| |_____^ help: try: `Some(15).filter(|&x| unsafe { f(x) })`
error: manual implementation of `Option::filter`
- --> $DIR/manual_filter.rs:205:12
+ --> $DIR/manual_filter.rs:203:12
|
LL | } else if let Some(x) = Some(16) {
| ____________^
diff --git a/src/tools/clippy/tests/ui/manual_filter_map.fixed b/src/tools/clippy/tests/ui/manual_filter_map.fixed
index 35872a39a..4de45e39b 100644
--- a/src/tools/clippy/tests/ui/manual_filter_map.fixed
+++ b/src/tools/clippy/tests/ui/manual_filter_map.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![warn(clippy::manual_filter_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
diff --git a/src/tools/clippy/tests/ui/manual_filter_map.rs b/src/tools/clippy/tests/ui/manual_filter_map.rs
index 50d8d2722..22f316f90 100644
--- a/src/tools/clippy/tests/ui/manual_filter_map.rs
+++ b/src/tools/clippy/tests/ui/manual_filter_map.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![warn(clippy::manual_filter_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
diff --git a/src/tools/clippy/tests/ui/manual_filter_map.stderr b/src/tools/clippy/tests/ui/manual_filter_map.stderr
index 0e8672c02..0bfc1f5c7 100644
--- a/src/tools/clippy/tests/ui/manual_filter_map.stderr
+++ b/src/tools/clippy/tests/ui/manual_filter_map.stderr
@@ -1,42 +1,43 @@
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:9:19
+ --> $DIR/manual_filter_map.rs:8:19
|
LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))`
|
note: 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
- --> $DIR/manual_filter_map.rs:9:30
+ --> $DIR/manual_filter_map.rs:8:30
|
LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^
= note: `-D clippy::manual-filter-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_filter_map)]`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:12:19
+ --> $DIR/manual_filter_map.rs:11:19
|
LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))`
|
note: 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
- --> $DIR/manual_filter_map.rs:12:31
+ --> $DIR/manual_filter_map.rs:11:31
|
LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:15:19
+ --> $DIR/manual_filter_map.rs:14:19
|
LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())`
|
note: 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
- --> $DIR/manual_filter_map.rs:15:31
+ --> $DIR/manual_filter_map.rs:14:31
|
LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:18:10
+ --> $DIR/manual_filter_map.rs:17:10
|
LL | .filter(|&x| to_ref(to_opt(x)).is_some())
| __________^
@@ -44,13 +45,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))`
|
note: 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
- --> $DIR/manual_filter_map.rs:18:22
+ --> $DIR/manual_filter_map.rs:17:22
|
LL | .filter(|&x| to_ref(to_opt(x)).is_some())
| ^^^^^^^^^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:21:10
+ --> $DIR/manual_filter_map.rs:20:10
|
LL | .filter(|x| to_ref(to_opt(*x)).is_some())
| __________^
@@ -58,13 +59,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))`
|
note: 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
- --> $DIR/manual_filter_map.rs:21:21
+ --> $DIR/manual_filter_map.rs:20:21
|
LL | .filter(|x| to_ref(to_opt(*x)).is_some())
| ^^^^^^^^^^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:25:10
+ --> $DIR/manual_filter_map.rs:24:10
|
LL | .filter(|&x| to_ref(to_res(x)).is_ok())
| __________^
@@ -72,13 +73,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())`
|
note: 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
- --> $DIR/manual_filter_map.rs:25:22
+ --> $DIR/manual_filter_map.rs:24:22
|
LL | .filter(|&x| to_ref(to_res(x)).is_ok())
| ^^^^^^^^^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:28:10
+ --> $DIR/manual_filter_map.rs:27:10
|
LL | .filter(|x| to_ref(to_res(*x)).is_ok())
| __________^
@@ -86,93 +87,94 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())`
|
note: 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
- --> $DIR/manual_filter_map.rs:28:21
+ --> $DIR/manual_filter_map.rs:27:21
|
LL | .filter(|x| to_ref(to_res(*x)).is_ok())
| ^^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:34:27
+ --> $DIR/manual_filter_map.rs:33:27
|
LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
|
= note: `-D clippy::manual-find-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:35:28
+ --> $DIR/manual_filter_map.rs:34:28
|
LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:36:31
+ --> $DIR/manual_filter_map.rs:35:31
|
LL | iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:37:31
+ --> $DIR/manual_filter_map.rs:36:31
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())`
|
note: 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
- --> $DIR/manual_filter_map.rs:37:41
+ --> $DIR/manual_filter_map.rs:36:41
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:39:30
+ --> $DIR/manual_filter_map.rs:38:30
|
LL | iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:40:31
+ --> $DIR/manual_filter_map.rs:39:31
|
LL | iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:41:32
+ --> $DIR/manual_filter_map.rs:40:32
|
LL | iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:42:31
+ --> $DIR/manual_filter_map.rs:41:31
|
LL | iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:43:32
+ --> $DIR/manual_filter_map.rs:42:32
|
LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:44:35
+ --> $DIR/manual_filter_map.rs:43:35
|
LL | iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_filter_map.rs:45:35
+ --> $DIR/manual_filter_map.rs:44:35
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())`
|
note: 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
- --> $DIR/manual_filter_map.rs:45:45
+ --> $DIR/manual_filter_map.rs:44:45
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:93:10
+ --> $DIR/manual_filter_map.rs:92:10
|
LL | .filter(|f| f.option_field.is_some())
| __________^
@@ -180,7 +182,7 @@ LL | | .map(|f| f.option_field.clone().unwrap());
| |_________________________________________________^ help: try: `filter_map(|f| f.option_field.clone())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:98:10
+ --> $DIR/manual_filter_map.rs:97:10
|
LL | .filter(|f| f.ref_field.is_some())
| __________^
@@ -188,7 +190,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap());
| |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.cloned())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:103:10
+ --> $DIR/manual_filter_map.rs:102:10
|
LL | .filter(|f| f.ref_field.is_some())
| __________^
@@ -196,7 +198,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap());
| |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.copied())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:108:10
+ --> $DIR/manual_filter_map.rs:107:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@@ -204,7 +206,7 @@ LL | | .map(|f| f.result_field.clone().unwrap());
| |_________________________________________________^ help: try: `filter_map(|f| f.result_field.clone().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:113:10
+ --> $DIR/manual_filter_map.rs:112:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@@ -212,7 +214,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap());
| |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_ref().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:118:10
+ --> $DIR/manual_filter_map.rs:117:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@@ -220,7 +222,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap());
| |____________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:123:10
+ --> $DIR/manual_filter_map.rs:122:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@@ -228,7 +230,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap());
| |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_mut().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:128:10
+ --> $DIR/manual_filter_map.rs:127:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@@ -236,7 +238,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap());
| |________________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref_mut().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:133:10
+ --> $DIR/manual_filter_map.rs:132:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@@ -244,7 +246,7 @@ LL | | .map(|f| f.result_field.to_owned().unwrap());
| |____________________________________________________^ help: try: `filter_map(|f| f.result_field.to_owned().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:146:27
+ --> $DIR/manual_filter_map.rs:145:27
|
LL | let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x {
| ___________________________^
@@ -254,7 +256,7 @@ LL | | });
| |______^ help: try: `filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
- --> $DIR/manual_filter_map.rs:156:10
+ --> $DIR/manual_filter_map.rs:155:10
|
LL | .filter(|x| matches!(x, Enum::A(_)))
| __________^
diff --git a/src/tools/clippy/tests/ui/manual_find.rs b/src/tools/clippy/tests/ui/manual_find.rs
index 257fe045f..0a105b035 100644
--- a/src/tools/clippy/tests/ui/manual_find.rs
+++ b/src/tools/clippy/tests/ui/manual_find.rs
@@ -1,8 +1,10 @@
#![allow(unused)]
#![warn(clippy::manual_find)]
-
+//@no-rustfix
fn vec_string(strings: Vec<String>) -> Option<String> {
for s in strings {
+ //~^ ERROR: manual implementation of `Iterator::find`
+ //~| NOTE: you may need to dereference some variables
if s == String::new() {
return Some(s);
}
@@ -12,6 +14,8 @@ fn vec_string(strings: Vec<String>) -> Option<String> {
fn tuple(arr: Vec<(String, i32)>) -> Option<String> {
for (s, _) in arr {
+ //~^ ERROR: manual implementation of `Iterator::find`
+ //~| NOTE: you may need to dereference some variables
if s == String::new() {
return Some(s);
}
diff --git a/src/tools/clippy/tests/ui/manual_find.stderr b/src/tools/clippy/tests/ui/manual_find.stderr
index ea04bb066..286ad5462 100644
--- a/src/tools/clippy/tests/ui/manual_find.stderr
+++ b/src/tools/clippy/tests/ui/manual_find.stderr
@@ -2,23 +2,26 @@ error: manual implementation of `Iterator::find`
--> $DIR/manual_find.rs:5:5
|
LL | / for s in strings {
+LL | |
+LL | |
LL | | if s == String::new() {
-LL | | return Some(s);
-LL | | }
+... |
LL | | }
LL | | None
| |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())`
|
= note: you may need to dereference some variables
= note: `-D clippy::manual-find` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_find)]`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find.rs:14:5
+ --> $DIR/manual_find.rs:16:5
|
LL | / for (s, _) in arr {
+LL | |
+LL | |
LL | | if s == String::new() {
-LL | | return Some(s);
-LL | | }
+... |
LL | | }
LL | | None
| |________^ help: replace with an iterator: `arr.into_iter().map(|(s, _)| s).find(|s| s == String::new())`
diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.fixed b/src/tools/clippy/tests/ui/manual_find_fixable.fixed
index 9c5eb20c8..5e6849a4d 100644
--- a/src/tools/clippy/tests/ui/manual_find_fixable.fixed
+++ b/src/tools/clippy/tests/ui/manual_find_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_find)]
#![allow(unused)]
#![allow(clippy::needless_return, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.rs b/src/tools/clippy/tests/ui/manual_find_fixable.rs
index 7b670320e..56c3f2629 100644
--- a/src/tools/clippy/tests/ui/manual_find_fixable.rs
+++ b/src/tools/clippy/tests/ui/manual_find_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_find)]
#![allow(unused)]
#![allow(clippy::needless_return, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.stderr b/src/tools/clippy/tests/ui/manual_find_fixable.stderr
index dbc4ff69a..387d1509c 100644
--- a/src/tools/clippy/tests/ui/manual_find_fixable.stderr
+++ b/src/tools/clippy/tests/ui/manual_find_fixable.stderr
@@ -1,5 +1,5 @@
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:11:5
+ --> $DIR/manual_find_fixable.rs:10:5
|
LL | / for &v in ARRAY {
LL | | if v == n {
@@ -10,9 +10,10 @@ LL | | None
| |________^ help: replace with an iterator: `ARRAY.iter().find(|&&v| v == n).copied()`
|
= note: `-D clippy::manual-find` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_find)]`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:20:5
+ --> $DIR/manual_find_fixable.rs:19:5
|
LL | / for (a, _) in arr {
LL | | if a % 2 == 0 {
@@ -23,7 +24,7 @@ LL | | None
| |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0)`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:33:5
+ --> $DIR/manual_find_fixable.rs:32:5
|
LL | / for el in arr {
LL | | if el.name.len() == 10 {
@@ -36,7 +37,7 @@ LL | | None
= note: you may need to dereference some variables
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:43:5
+ --> $DIR/manual_find_fixable.rs:42:5
|
LL | / for Tuple(a, _) in arr {
LL | | if a >= 3 {
@@ -47,7 +48,7 @@ LL | | None
| |________^ help: replace with an iterator: `arr.into_iter().map(|Tuple(a, _)| a).find(|&a| a >= 3)`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:58:5
+ --> $DIR/manual_find_fixable.rs:57:5
|
LL | / for el in arr {
LL | | if el.should_keep() {
@@ -60,7 +61,7 @@ LL | | None
= note: you may need to dereference some variables
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:68:5
+ --> $DIR/manual_find_fixable.rs:67:5
|
LL | / for el in arr {
LL | | if f(el) == 20 {
@@ -71,7 +72,7 @@ LL | | None
| |________^ help: replace with an iterator: `arr.into_iter().find(|&el| f(el) == 20)`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:78:5
+ --> $DIR/manual_find_fixable.rs:77:5
|
LL | / for &el in arr.values() {
LL | | if f(el) {
@@ -82,7 +83,7 @@ LL | | None
| |________^ help: replace with an iterator: `arr.values().find(|&&el| f(el)).copied()`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:87:5
+ --> $DIR/manual_find_fixable.rs:86:5
|
LL | / for el in arr {
LL | | if el.is_true {
@@ -95,7 +96,7 @@ LL | | None
= note: you may need to dereference some variables
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:117:5
+ --> $DIR/manual_find_fixable.rs:116:5
|
LL | / for (_, &x) in v {
LL | | if x > 10 {
@@ -106,7 +107,7 @@ LL | | None
| |________^ help: replace with an iterator: `v.into_iter().map(|(_, &x)| x).find(|&x| x > 10)`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:126:5
+ --> $DIR/manual_find_fixable.rs:125:5
|
LL | / for &(_, &x) in v {
LL | | if x > 10 {
@@ -117,7 +118,7 @@ LL | | None
| |________^ help: replace with an iterator: `v.iter().map(|&(_, &x)| x).find(|&x| x > 10)`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:135:5
+ --> $DIR/manual_find_fixable.rs:134:5
|
LL | / for x in arr {
LL | | if x >= 5 {
@@ -128,7 +129,7 @@ LL | | return None;
| |________________^ help: replace with an iterator: `arr.into_iter().find(|&x| x >= 5)`
error: manual implementation of `Iterator::find`
- --> $DIR/manual_find_fixable.rs:190:9
+ --> $DIR/manual_find_fixable.rs:189:9
|
LL | / for x in arr {
LL | | if x < 1 {
diff --git a/src/tools/clippy/tests/ui/manual_find_map.fixed b/src/tools/clippy/tests/ui/manual_find_map.fixed
index 0c8eebf04..0e92d25e6 100644
--- a/src/tools/clippy/tests/ui/manual_find_map.fixed
+++ b/src/tools/clippy/tests/ui/manual_find_map.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![warn(clippy::manual_find_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
diff --git a/src/tools/clippy/tests/ui/manual_find_map.rs b/src/tools/clippy/tests/ui/manual_find_map.rs
index b2feb48a8..b2568c823 100644
--- a/src/tools/clippy/tests/ui/manual_find_map.rs
+++ b/src/tools/clippy/tests/ui/manual_find_map.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![warn(clippy::manual_find_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
diff --git a/src/tools/clippy/tests/ui/manual_find_map.stderr b/src/tools/clippy/tests/ui/manual_find_map.stderr
index 4e52b5efa..0dc9ae1df 100644
--- a/src/tools/clippy/tests/ui/manual_find_map.stderr
+++ b/src/tools/clippy/tests/ui/manual_find_map.stderr
@@ -1,42 +1,43 @@
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:9:19
+ --> $DIR/manual_find_map.rs:8:19
|
LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))`
|
note: 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
- --> $DIR/manual_find_map.rs:9:28
+ --> $DIR/manual_find_map.rs:8:28
|
LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^
= note: `-D clippy::manual-find-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:12:19
+ --> $DIR/manual_find_map.rs:11:19
|
LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))`
|
note: 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
- --> $DIR/manual_find_map.rs:12:29
+ --> $DIR/manual_find_map.rs:11:29
|
LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:15:19
+ --> $DIR/manual_find_map.rs:14:19
|
LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())`
|
note: 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
- --> $DIR/manual_find_map.rs:15:29
+ --> $DIR/manual_find_map.rs:14:29
|
LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:18:10
+ --> $DIR/manual_find_map.rs:17:10
|
LL | .find(|&x| to_ref(to_opt(x)).is_some())
| __________^
@@ -44,13 +45,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))`
|
note: 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
- --> $DIR/manual_find_map.rs:18:20
+ --> $DIR/manual_find_map.rs:17:20
|
LL | .find(|&x| to_ref(to_opt(x)).is_some())
| ^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:21:10
+ --> $DIR/manual_find_map.rs:20:10
|
LL | .find(|x| to_ref(to_opt(*x)).is_some())
| __________^
@@ -58,13 +59,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))`
|
note: 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
- --> $DIR/manual_find_map.rs:21:19
+ --> $DIR/manual_find_map.rs:20:19
|
LL | .find(|x| to_ref(to_opt(*x)).is_some())
| ^^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:25:10
+ --> $DIR/manual_find_map.rs:24:10
|
LL | .find(|&x| to_ref(to_res(x)).is_ok())
| __________^
@@ -72,13 +73,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())`
|
note: 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
- --> $DIR/manual_find_map.rs:25:20
+ --> $DIR/manual_find_map.rs:24:20
|
LL | .find(|&x| to_ref(to_res(x)).is_ok())
| ^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:28:10
+ --> $DIR/manual_find_map.rs:27:10
|
LL | .find(|x| to_ref(to_res(*x)).is_ok())
| __________^
@@ -86,109 +87,109 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())`
|
note: 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
- --> $DIR/manual_find_map.rs:28:19
+ --> $DIR/manual_find_map.rs:27:19
|
LL | .find(|x| to_ref(to_res(*x)).is_ok())
| ^^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:34:26
+ --> $DIR/manual_find_map.rs:33:26
|
LL | iter::<Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x)`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:35:27
+ --> $DIR/manual_find_map.rs:34:27
|
LL | iter::<&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| *x)`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:36:28
+ --> $DIR/manual_find_map.rs:35:28
|
LL | iter::<&&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| **x)`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:37:27
+ --> $DIR/manual_find_map.rs:36:27
|
LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:38:28
+ --> $DIR/manual_find_map.rs:37:28
|
LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:39:31
+ --> $DIR/manual_find_map.rs:38:31
|
LL | iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:40:31
+ --> $DIR/manual_find_map.rs:39:31
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())`
|
note: 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
- --> $DIR/manual_find_map.rs:40:41
+ --> $DIR/manual_find_map.rs:39:41
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:42:30
+ --> $DIR/manual_find_map.rs:41:30
|
LL | iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:43:31
+ --> $DIR/manual_find_map.rs:42:31
|
LL | iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:44:32
+ --> $DIR/manual_find_map.rs:43:32
|
LL | iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:45:31
+ --> $DIR/manual_find_map.rs:44:31
|
LL | iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:46:32
+ --> $DIR/manual_find_map.rs:45:32
|
LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:47:35
+ --> $DIR/manual_find_map.rs:46:35
|
LL | iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:48:35
+ --> $DIR/manual_find_map.rs:47:35
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())`
|
note: 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
- --> $DIR/manual_find_map.rs:48:45
+ --> $DIR/manual_find_map.rs:47:45
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:96:10
+ --> $DIR/manual_find_map.rs:95:10
|
LL | .find(|f| f.option_field.is_some())
| __________^
@@ -196,7 +197,7 @@ LL | | .map(|f| f.option_field.clone().unwrap());
| |_________________________________________________^ help: try: `find_map(|f| f.option_field.clone())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:101:10
+ --> $DIR/manual_find_map.rs:100:10
|
LL | .find(|f| f.ref_field.is_some())
| __________^
@@ -204,7 +205,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap());
| |_______________________________________________^ help: try: `find_map(|f| f.ref_field.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:106:10
+ --> $DIR/manual_find_map.rs:105:10
|
LL | .find(|f| f.ref_field.is_some())
| __________^
@@ -212,7 +213,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap());
| |_______________________________________________^ help: try: `find_map(|f| f.ref_field.copied())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:111:10
+ --> $DIR/manual_find_map.rs:110:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@@ -220,7 +221,7 @@ LL | | .map(|f| f.result_field.clone().unwrap());
| |_________________________________________________^ help: try: `find_map(|f| f.result_field.clone().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:116:10
+ --> $DIR/manual_find_map.rs:115:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@@ -228,7 +229,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap());
| |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_ref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:121:10
+ --> $DIR/manual_find_map.rs:120:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@@ -236,7 +237,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap());
| |____________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:126:10
+ --> $DIR/manual_find_map.rs:125:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@@ -244,7 +245,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap());
| |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_mut().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:131:10
+ --> $DIR/manual_find_map.rs:130:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@@ -252,7 +253,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap());
| |________________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref_mut().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
- --> $DIR/manual_find_map.rs:136:10
+ --> $DIR/manual_find_map.rs:135:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
diff --git a/src/tools/clippy/tests/ui/manual_flatten.rs b/src/tools/clippy/tests/ui/manual_flatten.rs
index 552213a7f..d57333ace 100644
--- a/src/tools/clippy/tests/ui/manual_flatten.rs
+++ b/src/tools/clippy/tests/ui/manual_flatten.rs
@@ -1,10 +1,11 @@
#![warn(clippy::manual_flatten)]
#![allow(clippy::useless_vec, clippy::uninlined_format_args)]
-
+//@no-rustfix
fn main() {
// Test for loop over implicitly adjusted `Iterator` with `if let` expression
let x = vec![Some(1), Some(2), Some(3)];
for n in x {
+ //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element
if let Some(y) = n {
println!("{}", y);
}
@@ -13,6 +14,7 @@ fn main() {
// Test for loop over implicitly adjusted `Iterator` with `if let` statement
let y: Vec<Result<i32, i32>> = vec![];
for n in y.clone() {
+ //~^ ERROR: unnecessary `if let` since only the `Ok` variant of the iterator element i
if let Ok(n) = n {
println!("{}", n);
};
@@ -20,6 +22,7 @@ fn main() {
// Test for loop over by reference
for n in &y {
+ //~^ ERROR: unnecessary `if let` since only the `Ok` variant of the iterator element i
if let Ok(n) = n {
println!("{}", n);
}
@@ -28,6 +31,7 @@ fn main() {
// Test for loop over an implicit reference
let z = &y;
for n in z {
+ //~^ ERROR: unnecessary `if let` since only the `Ok` variant of the iterator element i
if let Ok(n) = n {
println!("{}", n);
}
@@ -37,6 +41,7 @@ fn main() {
let z = vec![Some(1), Some(2), Some(3)];
let z = z.iter();
for n in z {
+ //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element
if let Some(m) = n {
println!("{}", m);
}
@@ -70,6 +75,7 @@ fn main() {
let vec_of_ref = vec![&Some(1)];
for n in &vec_of_ref {
+ //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element
if let Some(n) = n {
println!("{:?}", n);
}
@@ -77,6 +83,7 @@ fn main() {
let vec_of_ref = &vec_of_ref;
for n in vec_of_ref {
+ //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element
if let Some(n) = n {
println!("{:?}", n);
}
@@ -84,6 +91,7 @@ fn main() {
let slice_of_ref = &[&Some(1)];
for n in slice_of_ref {
+ //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element
if let Some(n) = n {
println!("{:?}", n);
}
@@ -114,6 +122,7 @@ fn main() {
fn run_unformatted_tests() {
// Skip rustfmt here on purpose so the suggestion does not fit in one line
for n in vec![
+ //~^ ERROR: unnecessary `if let` since only the `Some` variant of the iterator element
Some(1),
Some(2),
Some(3)
diff --git a/src/tools/clippy/tests/ui/manual_flatten.stderr b/src/tools/clippy/tests/ui/manual_flatten.stderr
index 180a6ff4e..aa5c2104f 100644
--- a/src/tools/clippy/tests/ui/manual_flatten.stderr
+++ b/src/tools/clippy/tests/ui/manual_flatten.stderr
@@ -5,6 +5,7 @@ LL | for n in x {
| ^ - help: try: `x.into_iter().flatten()`
| _____|
| |
+LL | |
LL | | if let Some(y) = n {
LL | | println!("{}", y);
LL | | }
@@ -12,21 +13,23 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:8:9
+ --> $DIR/manual_flatten.rs:9:9
|
LL | / if let Some(y) = n {
LL | | println!("{}", y);
LL | | }
| |_________^
= note: `-D clippy::manual-flatten` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_flatten)]`
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:15:5
+ --> $DIR/manual_flatten.rs:16:5
|
LL | for n in y.clone() {
| ^ --------- help: try: `y.clone().into_iter().flatten()`
| _____|
| |
+LL | |
LL | | if let Ok(n) = n {
LL | | println!("{}", n);
LL | | };
@@ -34,7 +37,7 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:16:9
+ --> $DIR/manual_flatten.rs:18:9
|
LL | / if let Ok(n) = n {
LL | | println!("{}", n);
@@ -42,12 +45,13 @@ LL | | };
| |_________^
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:22:5
+ --> $DIR/manual_flatten.rs:24:5
|
LL | for n in &y {
| ^ -- help: try: `y.iter().flatten()`
| _____|
| |
+LL | |
LL | | if let Ok(n) = n {
LL | | println!("{}", n);
LL | | }
@@ -55,7 +59,7 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:23:9
+ --> $DIR/manual_flatten.rs:26:9
|
LL | / if let Ok(n) = n {
LL | | println!("{}", n);
@@ -63,12 +67,13 @@ LL | | }
| |_________^
error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:30:5
+ --> $DIR/manual_flatten.rs:33:5
|
LL | for n in z {
| ^ - help: try: `z.iter().flatten()`
| _____|
| |
+LL | |
LL | | if let Ok(n) = n {
LL | | println!("{}", n);
LL | | }
@@ -76,7 +81,7 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:31:9
+ --> $DIR/manual_flatten.rs:35:9
|
LL | / if let Ok(n) = n {
LL | | println!("{}", n);
@@ -84,12 +89,13 @@ LL | | }
| |_________^
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:39:5
+ --> $DIR/manual_flatten.rs:43:5
|
LL | for n in z {
| ^ - help: try: `z.flatten()`
| _____|
| |
+LL | |
LL | | if let Some(m) = n {
LL | | println!("{}", m);
LL | | }
@@ -97,7 +103,7 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:40:9
+ --> $DIR/manual_flatten.rs:45:9
|
LL | / if let Some(m) = n {
LL | | println!("{}", m);
@@ -105,12 +111,13 @@ LL | | }
| |_________^
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:72:5
+ --> $DIR/manual_flatten.rs:77:5
|
LL | for n in &vec_of_ref {
| ^ ----------- help: try: `vec_of_ref.iter().copied().flatten()`
| _____|
| |
+LL | |
LL | | if let Some(n) = n {
LL | | println!("{:?}", n);
LL | | }
@@ -118,7 +125,7 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:73:9
+ --> $DIR/manual_flatten.rs:79:9
|
LL | / if let Some(n) = n {
LL | | println!("{:?}", n);
@@ -126,12 +133,13 @@ LL | | }
| |_________^
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:79:5
+ --> $DIR/manual_flatten.rs:85:5
|
LL | for n in vec_of_ref {
| ^ ---------- help: try: `vec_of_ref.iter().copied().flatten()`
| _____|
| |
+LL | |
LL | | if let Some(n) = n {
LL | | println!("{:?}", n);
LL | | }
@@ -139,7 +147,7 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:80:9
+ --> $DIR/manual_flatten.rs:87:9
|
LL | / if let Some(n) = n {
LL | | println!("{:?}", n);
@@ -147,12 +155,13 @@ LL | | }
| |_________^
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:86:5
+ --> $DIR/manual_flatten.rs:93:5
|
LL | for n in slice_of_ref {
| ^ ------------ help: try: `slice_of_ref.iter().copied().flatten()`
| _____|
| |
+LL | |
LL | | if let Some(n) = n {
LL | | println!("{:?}", n);
LL | | }
@@ -160,7 +169,7 @@ LL | | }
| |_____^
|
help: ...and remove the `if let` statement in the for loop
- --> $DIR/manual_flatten.rs:87:9
+ --> $DIR/manual_flatten.rs:95:9
|
LL | / if let Some(n) = n {
LL | | println!("{:?}", n);
@@ -168,19 +177,19 @@ LL | | }
| |_________^
error: unnecessary `if let` since only the `Some` variant of the iterator element is used
- --> $DIR/manual_flatten.rs:116:5
+ --> $DIR/manual_flatten.rs:124:5
|
LL | / for n in vec![
+LL | |
LL | | Some(1),
LL | | Some(2),
-LL | | Some(3)
... |
LL | | }
LL | | }
| |_____^
|
help: remove the `if let` statement in the for loop and then...
- --> $DIR/manual_flatten.rs:121:9
+ --> $DIR/manual_flatten.rs:130:9
|
LL | / if let Some(n) = n {
LL | | println!("{:?}", n);
@@ -189,6 +198,7 @@ LL | | }
help: try
|
LL ~ for n in vec![
+LL +
LL + Some(1),
LL + Some(2),
LL + Some(3)
diff --git a/src/tools/clippy/tests/ui/manual_float_methods.rs b/src/tools/clippy/tests/ui/manual_float_methods.rs
index af9076cfb..f3e95d680 100644
--- a/src/tools/clippy/tests/ui/manual_float_methods.rs
+++ b/src/tools/clippy/tests/ui/manual_float_methods.rs
@@ -1,4 +1,5 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@no-rustfix: overlapping suggestions
+//@aux-build:proc_macros.rs
#![allow(clippy::needless_if, unused)]
#![warn(clippy::manual_is_infinite, clippy::manual_is_finite)]
#![feature(inline_const)]
diff --git a/src/tools/clippy/tests/ui/manual_float_methods.stderr b/src/tools/clippy/tests/ui/manual_float_methods.stderr
index a56118b31..680ab2efa 100644
--- a/src/tools/clippy/tests/ui/manual_float_methods.stderr
+++ b/src/tools/clippy/tests/ui/manual_float_methods.stderr
@@ -1,18 +1,20 @@
error: manually checking if a float is infinite
- --> $DIR/manual_float_methods.rs:22:8
+ --> $DIR/manual_float_methods.rs:23:8
|
LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
|
= note: `-D clippy::manual-is-infinite` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_is_infinite)]`
error: manually checking if a float is finite
- --> $DIR/manual_float_methods.rs:23:8
+ --> $DIR/manual_float_methods.rs:24:8
|
LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::manual-is-finite` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_is_finite)]`
help: use the dedicated method instead
|
LL | if x.is_finite() {}
@@ -27,13 +29,13 @@ LL | if !x.is_infinite() {}
| ~~~~~~~~~~~~~~~~
error: manually checking if a float is infinite
- --> $DIR/manual_float_methods.rs:24:8
+ --> $DIR/manual_float_methods.rs:25:8
|
LL | if x == INFINITE || x == NEG_INFINITE {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
error: manually checking if a float is finite
- --> $DIR/manual_float_methods.rs:25:8
+ --> $DIR/manual_float_methods.rs:26:8
|
LL | if x != INFINITE && x != NEG_INFINITE {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,13 +54,13 @@ LL | if !x.is_infinite() {}
| ~~~~~~~~~~~~~~~~
error: manually checking if a float is infinite
- --> $DIR/manual_float_methods.rs:27:8
+ --> $DIR/manual_float_methods.rs:28:8
|
LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`
error: manually checking if a float is finite
- --> $DIR/manual_float_methods.rs:28:8
+ --> $DIR/manual_float_methods.rs:29:8
|
LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
index 55073c3b5..181133765 100644
--- a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_instant_elapsed)]
#![allow(clippy::unnecessary_operation)]
#![allow(clippy::unchecked_duration_subtraction)]
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
index c9029a049..fedca38b1 100644
--- a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_instant_elapsed)]
#![allow(clippy::unnecessary_operation)]
#![allow(clippy::unchecked_duration_subtraction)]
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
index 4ce1f6891..56d0b9cd7 100644
--- a/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
@@ -1,13 +1,14 @@
error: manual implementation of `Instant::elapsed`
- --> $DIR/manual_instant_elapsed.rs:18:20
+ --> $DIR/manual_instant_elapsed.rs:17:20
|
LL | let duration = Instant::now() - prev_instant;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `prev_instant.elapsed()`
|
= note: `-D clippy::manual-instant-elapsed` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_instant_elapsed)]`
error: manual implementation of `Instant::elapsed`
- --> $DIR/manual_instant_elapsed.rs:27:5
+ --> $DIR/manual_instant_elapsed.rs:26:5
|
LL | Instant::now() - *ref_to_instant; // to ensure parens are added correctly
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*ref_to_instant).elapsed()`
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
index 87e866586..5be2dd280 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, dead_code)]
#![warn(clippy::manual_is_ascii_check)]
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
index 931f0f202..f9249e22a 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, dead_code)]
#![warn(clippy::manual_is_ascii_check)]
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
index ee6018850..e0fb46e59 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
@@ -1,121 +1,122 @@
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:7:13
+ --> $DIR/manual_is_ascii_check.rs:5:13
|
LL | assert!(matches!('x', 'a'..='z'));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_lowercase()`
|
= note: `-D clippy::manual-is-ascii-check` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_is_ascii_check)]`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:8:13
+ --> $DIR/manual_is_ascii_check.rs:6:13
|
LL | assert!(matches!('X', 'A'..='Z'));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'X'.is_ascii_uppercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:9:13
+ --> $DIR/manual_is_ascii_check.rs:7:13
|
LL | assert!(matches!(b'x', b'a'..=b'z'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'x'.is_ascii_lowercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:10:13
+ --> $DIR/manual_is_ascii_check.rs:8:13
|
LL | assert!(matches!(b'X', b'A'..=b'Z'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'X'.is_ascii_uppercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:13:13
+ --> $DIR/manual_is_ascii_check.rs:11:13
|
LL | assert!(matches!(num, '0'..='9'));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.is_ascii_digit()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:14:13
+ --> $DIR/manual_is_ascii_check.rs:12:13
|
LL | assert!(matches!(b'1', b'0'..=b'9'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'1'.is_ascii_digit()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:15:13
+ --> $DIR/manual_is_ascii_check.rs:13:13
|
LL | assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_alphabetic()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:19:5
+ --> $DIR/manual_is_ascii_check.rs:17:5
|
LL | (b'0'..=b'9').contains(&b'0');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'0'.is_ascii_digit()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:20:5
+ --> $DIR/manual_is_ascii_check.rs:18:5
|
LL | (b'a'..=b'z').contains(&b'a');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'a'.is_ascii_lowercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:21:5
+ --> $DIR/manual_is_ascii_check.rs:19:5
|
LL | (b'A'..=b'Z').contains(&b'A');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'A'.is_ascii_uppercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:23:5
+ --> $DIR/manual_is_ascii_check.rs:21:5
|
LL | ('0'..='9').contains(&'0');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'0'.is_ascii_digit()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:24:5
+ --> $DIR/manual_is_ascii_check.rs:22:5
|
LL | ('a'..='z').contains(&'a');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'a'.is_ascii_lowercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:25:5
+ --> $DIR/manual_is_ascii_check.rs:23:5
|
LL | ('A'..='Z').contains(&'A');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'A'.is_ascii_uppercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:28:5
+ --> $DIR/manual_is_ascii_check.rs:26:5
|
LL | ('0'..='9').contains(cool_letter);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_digit()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:29:5
+ --> $DIR/manual_is_ascii_check.rs:27:5
|
LL | ('a'..='z').contains(cool_letter);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_lowercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:30:5
+ --> $DIR/manual_is_ascii_check.rs:28:5
|
LL | ('A'..='Z').contains(cool_letter);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cool_letter.is_ascii_uppercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:42:13
+ --> $DIR/manual_is_ascii_check.rs:40:13
|
LL | assert!(matches!(b'1', b'0'..=b'9'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b'1'.is_ascii_digit()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:43:13
+ --> $DIR/manual_is_ascii_check.rs:41:13
|
LL | assert!(matches!('X', 'A'..='Z'));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'X'.is_ascii_uppercase()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:44:13
+ --> $DIR/manual_is_ascii_check.rs:42:13
|
LL | assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_alphabetic()`
error: manual check for common ascii range
- --> $DIR/manual_is_ascii_check.rs:54:23
+ --> $DIR/manual_is_ascii_check.rs:52:23
|
LL | const FOO: bool = matches!('x', '0'..='9');
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_digit()`
diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs
index 381b83409..6775fdc92 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else.rs
@@ -8,7 +8,7 @@
clippy::needless_if
)]
#![warn(clippy::manual_let_else)]
-
+//@no-rustfix
enum Variant {
A(usize, usize),
B(usize),
@@ -23,13 +23,17 @@ fn main() {}
fn fire() {
let v = if let Some(v_some) = g() { v_some } else { return };
+ //~^ ERROR: this could be rewritten as `let...else`
+ //~| NOTE: `-D clippy::manual-let-else` implied by `-D warnings`
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
return;
};
let v = if let Some(v) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
// Blocks around the identity should have no impact
{
{ v }
@@ -43,14 +47,18 @@ fn fire() {
// continue and break diverge
loop {
let v = if let Some(v_some) = g() { v_some } else { continue };
+ //~^ ERROR: this could be rewritten as `let...else`
let v = if let Some(v_some) = g() { v_some } else { break };
+ //~^ ERROR: this could be rewritten as `let...else`
}
// panic also diverges
let v = if let Some(v_some) = g() { v_some } else { panic!() };
+ //~^ ERROR: this could be rewritten as `let...else`
// abort also diverges
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
std::process::abort()
@@ -58,6 +66,7 @@ fn fire() {
// If whose two branches diverge also diverges
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
if true { return } else { panic!() }
@@ -65,6 +74,7 @@ fn fire() {
// Diverging after an if still makes the block diverge:
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
if true {}
@@ -75,6 +85,7 @@ fn fire() {
// Note: the corresponding let-else requires a ; at the end of the match
// as otherwise the type checker does not turn it into a ! type.
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
match () {
@@ -85,9 +96,11 @@ fn fire() {
// An if's expression can cause divergence:
let v = if let Some(v_some) = g() { v_some } else { if panic!() {} };
+ //~^ ERROR: this could be rewritten as `let...else`
// An expression of a match can cause divergence:
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
match panic!() {
@@ -97,6 +110,7 @@ fn fire() {
// Top level else if
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else if true {
return;
@@ -106,6 +120,7 @@ fn fire() {
// All match arms diverge
let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
match (g(), g()) {
@@ -123,6 +138,7 @@ fn fire() {
// Tuples supported for the declared variables
let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {
+ //~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
return;
@@ -130,6 +146,7 @@ fn fire() {
// Tuples supported with multiple bindings
let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) {
+ //~^ ERROR: this could be rewritten as `let...else`
(w_some, v_some)
} else {
return;
@@ -148,25 +165,31 @@ fn fire() {
}
let v = if let Variant::A(a, 0) = e() { a } else { return };
+ //~^ ERROR: this could be rewritten as `let...else`
// `mut v` is inserted into the pattern
let mut v = if let Variant::B(b) = e() { b } else { return };
+ //~^ ERROR: this could be rewritten as `let...else`
// Nesting works
let nested = Ok(Some(e()));
let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested {
+ //~^ ERROR: this could be rewritten as `let...else`
b
} else {
return;
};
// dot dot works
let v = if let Variant::A(.., a) = e() { a } else { return };
+ //~^ ERROR: this could be rewritten as `let...else`
// () is preserved: a bit of an edge case but make sure it stays around
let w = if let (Some(v), ()) = (g(), ()) { v } else { return };
+ //~^ ERROR: this could be rewritten as `let...else`
// Tuple structs work
let w = if let Some(S { v: x }) = Some(S { v: 0 }) {
+ //~^ ERROR: this could be rewritten as `let...else`
x
} else {
return;
@@ -174,6 +197,7 @@ fn fire() {
// Field init shorthand is suggested
let v = if let Some(S { v: x }) = Some(S { v: 0 }) {
+ //~^ ERROR: this could be rewritten as `let...else`
x
} else {
return;
@@ -181,6 +205,7 @@ fn fire() {
// Multi-field structs also work
let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> {
+ //~^ ERROR: this could be rewritten as `let...else`
(x, v, w)
} else {
return;
@@ -297,6 +322,7 @@ fn not_fire() {
let ff = Some(1);
let _ = match ff {
+ //~^ ERROR: this could be rewritten as `let...else`
Some(value) => value,
_ => macro_call!(),
};
diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr
index 912302b17..49dbd7615 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else.stderr
@@ -5,11 +5,13 @@ LL | let v = if let Some(v_some) = g() { v_some } else { return };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
|
= note: `-D clippy::manual-let-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:26:5
+ --> $DIR/manual_let_else.rs:28:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else {
LL | | return;
@@ -24,12 +26,12 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:32:5
+ --> $DIR/manual_let_else.rs:35:5
|
LL | / let v = if let Some(v) = g() {
+LL | |
LL | | // Blocks around the identity should have no impact
LL | | {
-LL | | { v }
... |
LL | | return;
LL | | };
@@ -45,27 +47,28 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:45:9
+ --> $DIR/manual_let_else.rs:49:9
|
LL | let v = if let Some(v_some) = g() { v_some } else { continue };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:46:9
+ --> $DIR/manual_let_else.rs:51:9
|
LL | let v = if let Some(v_some) = g() { v_some } else { break };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:50:5
+ --> $DIR/manual_let_else.rs:56:5
|
LL | let v = if let Some(v_some) = g() { v_some } else { panic!() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:53:5
+ --> $DIR/manual_let_else.rs:60:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else {
LL | | std::process::abort()
@@ -80,9 +83,10 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:60:5
+ --> $DIR/manual_let_else.rs:68:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else {
LL | | if true { return } else { panic!() }
@@ -97,9 +101,10 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:67:5
+ --> $DIR/manual_let_else.rs:76:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else {
LL | | if true {}
@@ -116,12 +121,12 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:77:5
+ --> $DIR/manual_let_else.rs:87:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else {
-LL | | match () {
... |
LL | | }
LL | | };
@@ -138,19 +143,19 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:87:5
+ --> $DIR/manual_let_else.rs:98:5
|
LL | let v = if let Some(v_some) = g() { v_some } else { if panic!() {} };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { if panic!() {} };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:90:5
+ --> $DIR/manual_let_else.rs:102:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else {
-LL | | match panic!() {
-LL | | _ => {},
+... |
LL | | }
LL | | };
| |______^
@@ -165,13 +170,13 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:99:5
+ --> $DIR/manual_let_else.rs:112:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else if true {
-LL | | return;
-LL | | } else {
+... |
LL | | panic!("diverge");
LL | | };
| |______^
@@ -186,12 +191,12 @@ LL + } };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:108:5
+ --> $DIR/manual_let_else.rs:122:5
|
LL | / let v = if let Some(v_some) = g() {
+LL | |
LL | | v_some
LL | | } else {
-LL | | match (g(), g()) {
... |
LL | | }
LL | | };
@@ -215,9 +220,10 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:125:5
+ --> $DIR/manual_let_else.rs:140:5
|
LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {
+LL | |
LL | | v_some
LL | | } else {
LL | | return;
@@ -232,9 +238,10 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:132:5
+ --> $DIR/manual_let_else.rs:148:5
|
LL | / let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) {
+LL | |
LL | | (w_some, v_some)
LL | | } else {
LL | | return;
@@ -249,7 +256,7 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:141:13
+ --> $DIR/manual_let_else.rs:158:13
|
LL | let $n = if let Some(v) = $e { v } else { return };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };`
@@ -260,21 +267,22 @@ LL | create_binding_if_some!(w, g());
= note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:150:5
+ --> $DIR/manual_let_else.rs:167:5
|
LL | let v = if let Variant::A(a, 0) = e() { a } else { return };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:153:5
+ --> $DIR/manual_let_else.rs:171:5
|
LL | let mut v = if let Variant::B(b) = e() { b } else { return };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:157:5
+ --> $DIR/manual_let_else.rs:176:5
|
LL | / let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested {
+LL | |
LL | | b
LL | | } else {
LL | | return;
@@ -289,21 +297,22 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:163:5
+ --> $DIR/manual_let_else.rs:183:5
|
LL | let v = if let Variant::A(.., a) = e() { a } else { return };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:166:5
+ --> $DIR/manual_let_else.rs:187:5
|
LL | let w = if let (Some(v), ()) = (g(), ()) { v } else { return };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:169:5
+ --> $DIR/manual_let_else.rs:191:5
|
LL | / let w = if let Some(S { v: x }) = Some(S { v: 0 }) {
+LL | |
LL | | x
LL | | } else {
LL | | return;
@@ -318,9 +327,10 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:176:5
+ --> $DIR/manual_let_else.rs:199:5
|
LL | / let v = if let Some(S { v: x }) = Some(S { v: 0 }) {
+LL | |
LL | | x
LL | | } else {
LL | | return;
@@ -335,9 +345,10 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:183:5
+ --> $DIR/manual_let_else.rs:207:5
|
LL | / let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> {
+LL | |
LL | | (x, v, w)
LL | | } else {
LL | | return;
@@ -352,9 +363,10 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else.rs:299:5
+ --> $DIR/manual_let_else.rs:324:5
|
LL | / let _ = match ff {
+LL | |
LL | | Some(value) => value,
LL | | _ => macro_call!(),
LL | | };
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.fixed b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
new file mode 100644
index 000000000..09b713f04
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
@@ -0,0 +1,135 @@
+#![allow(unused_braces, unused_variables, dead_code)]
+#![allow(
+ clippy::collapsible_else_if,
+ clippy::let_unit_value,
+ clippy::redundant_at_rest_pattern
+)]
+#![warn(clippy::manual_let_else)]
+// Ensure that we don't conflict with match -> if let lints
+#![warn(clippy::single_match_else, clippy::single_match)]
+
+fn f() -> Result<u32, u32> {
+ Ok(0)
+}
+
+fn g() -> Option<()> {
+ None
+}
+
+fn h() -> (Option<()>, Option<()>) {
+ (None, None)
+}
+
+enum Variant {
+ Foo,
+ Bar(u32),
+ Baz(u32),
+}
+
+fn build_enum() -> Variant {
+ Variant::Foo
+}
+
+fn main() {}
+
+fn fire() {
+ let Some(v) = g() else { return };
+
+ let Some(v) = g() else { return };
+
+ loop {
+ // More complex pattern for the identity arm and diverging arm
+ let ((Some(v), None) | (None, Some(v))) = h() else { continue };
+ // Custom enums are supported as long as the "else" arm is a simple _
+ let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };
+ }
+
+ // There is a _ in the diverging arm
+ // TODO also support unused bindings aka _v
+ let Ok(v) = f() else { return };
+
+ // Err(()) is an allowed pattern
+ let Ok(v) = f().map_err(|_| ()) else { return };
+
+ let f = Variant::Bar(1);
+
+ let (Variant::Bar(_value) | Variant::Baz(_value)) = f else { return };
+
+ let Some(Variant::Bar(_value) | Variant::Baz(_value)) = Some(build_enum()) else { return };
+
+ let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];
+ let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };
+}
+
+fn not_fire() {
+ // Multiple diverging arms
+ let v = match h() {
+ _ => panic!(),
+ (None, Some(_v)) => return,
+ (Some(v), None) => v,
+ };
+
+ // Multiple identity arms
+ let v = match h() {
+ _ => panic!(),
+ (None, Some(v)) => v,
+ (Some(v), None) => v,
+ };
+
+ // No diverging arm at all, only identity arms.
+ // This is no case for let else, but destructuring assignment.
+ let v = match f() {
+ Ok(v) => v,
+ Err(e) => e,
+ };
+
+ // The identity arm has a guard
+ let v = match g() {
+ Some(v) if g().is_none() => v,
+ _ => return,
+ };
+
+ // The diverging arm has a guard
+ let v = match f() {
+ Err(v) if v > 0 => panic!(),
+ Ok(v) | Err(v) => v,
+ };
+
+ // The diverging arm creates a binding
+ let v = match f() {
+ Ok(v) => v,
+ Err(e) => panic!("error: {e}"),
+ };
+
+ // Custom enum where the diverging arm
+ // explicitly mentions the variant
+ let v = match build_enum() {
+ Variant::Foo => return,
+ Variant::Bar(v) | Variant::Baz(v) => v,
+ };
+
+ // The custom enum is surrounded by an Err()
+ let v = match Err(build_enum()) {
+ Ok(v) | Err(Variant::Bar(v) | Variant::Baz(v)) => v,
+ Err(Variant::Foo) => return,
+ };
+
+ // Issue 10241
+ // The non-divergent arm arrives in second position and
+ // may cover values already matched in the first arm.
+ let v = match h() {
+ (Some(_), Some(_)) | (None, None) => return,
+ (Some(v), _) | (None, Some(v)) => v,
+ };
+
+ let v = match build_enum() {
+ _ => return,
+ Variant::Bar(v) | Variant::Baz(v) => v,
+ };
+
+ let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];
+ let data = match data.as_slice() {
+ [] | [0, 0] => return,
+ [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data,
+ };
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.rs b/src/tools/clippy/tests/ui/manual_let_else_match.rs
index 73ff69eec..e6af47384 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.rs
@@ -34,11 +34,14 @@ fn main() {}
fn fire() {
let v = match g() {
+ //~^ ERROR: this could be rewritten as `let...else`
+ //~| NOTE: `-D clippy::manual-let-else` implied by `-D warnings`
Some(v_some) => v_some,
None => return,
};
let v = match g() {
+ //~^ ERROR: this could be rewritten as `let...else`
Some(v_some) => v_some,
_ => return,
};
@@ -46,11 +49,13 @@ fn fire() {
loop {
// More complex pattern for the identity arm and diverging arm
let v = match h() {
+ //~^ ERROR: this could be rewritten as `let...else`
(Some(v), None) | (None, Some(v)) => v,
(Some(_), Some(_)) | (None, None) => continue,
};
// Custom enums are supported as long as the "else" arm is a simple _
let v = match build_enum() {
+ //~^ ERROR: this could be rewritten as `let...else`
Variant::Bar(v) | Variant::Baz(v) => v,
_ => continue,
};
@@ -59,12 +64,14 @@ fn fire() {
// There is a _ in the diverging arm
// TODO also support unused bindings aka _v
let v = match f() {
+ //~^ ERROR: this could be rewritten as `let...else`
Ok(v) => v,
Err(_) => return,
};
// Err(()) is an allowed pattern
let v = match f().map_err(|_| ()) {
+ //~^ ERROR: this could be rewritten as `let...else`
Ok(v) => v,
Err(()) => return,
};
@@ -72,17 +79,20 @@ fn fire() {
let f = Variant::Bar(1);
let _value = match f {
+ //~^ ERROR: this could be rewritten as `let...else`
Variant::Bar(v) | Variant::Baz(v) => v,
_ => return,
};
let _value = match Some(build_enum()) {
+ //~^ ERROR: this could be rewritten as `let...else`
Some(Variant::Bar(v) | Variant::Baz(v)) => v,
_ => return,
};
let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];
let data = match data.as_slice() {
+ //~^ ERROR: this could be rewritten as `let...else`
[data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data,
_ => return,
};
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.stderr b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
index 3fd9a6376..8ca2c8407 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
@@ -2,80 +2,91 @@ error: this could be rewritten as `let...else`
--> $DIR/manual_let_else_match.rs:36:5
|
LL | / let v = match g() {
+LL | |
+LL | |
LL | | Some(v_some) => v_some,
LL | | None => return,
LL | | };
| |______^ help: consider writing: `let Some(v) = g() else { return };`
|
= note: `-D clippy::manual-let-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:41:5
+ --> $DIR/manual_let_else_match.rs:43:5
|
LL | / let v = match g() {
+LL | |
LL | | Some(v_some) => v_some,
LL | | _ => return,
LL | | };
| |______^ help: consider writing: `let Some(v) = g() else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:48:9
+ --> $DIR/manual_let_else_match.rs:51:9
|
LL | / let v = match h() {
+LL | |
LL | | (Some(v), None) | (None, Some(v)) => v,
LL | | (Some(_), Some(_)) | (None, None) => continue,
LL | | };
| |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:53:9
+ --> $DIR/manual_let_else_match.rs:57:9
|
LL | / let v = match build_enum() {
+LL | |
LL | | Variant::Bar(v) | Variant::Baz(v) => v,
LL | | _ => continue,
LL | | };
| |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:61:5
+ --> $DIR/manual_let_else_match.rs:66:5
|
LL | / let v = match f() {
+LL | |
LL | | Ok(v) => v,
LL | | Err(_) => return,
LL | | };
| |______^ help: consider writing: `let Ok(v) = f() else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:67:5
+ --> $DIR/manual_let_else_match.rs:73:5
|
LL | / let v = match f().map_err(|_| ()) {
+LL | |
LL | | Ok(v) => v,
LL | | Err(()) => return,
LL | | };
| |______^ help: consider writing: `let Ok(v) = f().map_err(|_| ()) else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:74:5
+ --> $DIR/manual_let_else_match.rs:81:5
|
LL | / let _value = match f {
+LL | |
LL | | Variant::Bar(v) | Variant::Baz(v) => v,
LL | | _ => return,
LL | | };
| |______^ help: consider writing: `let (Variant::Bar(_value) | Variant::Baz(_value)) = f else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:79:5
+ --> $DIR/manual_let_else_match.rs:87:5
|
LL | / let _value = match Some(build_enum()) {
+LL | |
LL | | Some(Variant::Bar(v) | Variant::Baz(v)) => v,
LL | | _ => return,
LL | | };
| |______^ help: consider writing: `let Some(Variant::Bar(_value) | Variant::Baz(_value)) = Some(build_enum()) else { return };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_match.rs:85:5
+ --> $DIR/manual_let_else_match.rs:94:5
|
LL | / let data = match data.as_slice() {
+LL | |
LL | | [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data,
LL | | _ => return,
LL | | };
diff --git a/src/tools/clippy/tests/ui/manual_let_else_question_mark.fixed b/src/tools/clippy/tests/ui/manual_let_else_question_mark.fixed
index 02308bc7c..b555186cc 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_question_mark.fixed
+++ b/src/tools/clippy/tests/ui/manual_let_else_question_mark.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused_braces, unused_variables, dead_code)]
#![allow(
clippy::collapsible_else_if,
diff --git a/src/tools/clippy/tests/ui/manual_let_else_question_mark.rs b/src/tools/clippy/tests/ui/manual_let_else_question_mark.rs
index 9c7ad386d..5852c7094 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_question_mark.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else_question_mark.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused_braces, unused_variables, dead_code)]
#![allow(
clippy::collapsible_else_if,
diff --git a/src/tools/clippy/tests/ui/manual_let_else_question_mark.stderr b/src/tools/clippy/tests/ui/manual_let_else_question_mark.stderr
index d7d2e127e..bf0b1bbf0 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_question_mark.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else_question_mark.stderr
@@ -1,25 +1,26 @@
error: this `let...else` may be rewritten with the `?` operator
- --> $DIR/manual_let_else_question_mark.rs:30:5
+ --> $DIR/manual_let_else_question_mark.rs:29:5
|
LL | let Some(v) = g() else { return None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `let v = g()?;`
|
= note: `-D clippy::question-mark` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::question_mark)]`
error: this `let...else` may be rewritten with the `?` operator
- --> $DIR/manual_let_else_question_mark.rs:36:5
+ --> $DIR/manual_let_else_question_mark.rs:35:5
|
LL | let Some((v, w)) = g() else { return None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `let (v, w) = g()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/manual_let_else_question_mark.rs:39:13
+ --> $DIR/manual_let_else_question_mark.rs:38:13
|
LL | let v = if let Some(v_some) = g() { v_some } else { return None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `g()?`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_question_mark.rs:43:5
+ --> $DIR/manual_let_else_question_mark.rs:42:5
|
LL | / let v = if let Some(v_some) = g() {
LL | | v_some
@@ -29,6 +30,7 @@ LL | | };
| |______^
|
= note: `-D clippy::manual-let-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
help: consider writing
|
LL ~ let Some(v) = g() else {
@@ -37,7 +39,7 @@ LL + };
|
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_question_mark.rs:54:9
+ --> $DIR/manual_let_else_question_mark.rs:53:9
|
LL | / let v = match g() {
LL | | Some(v_some) => v_some,
@@ -46,7 +48,7 @@ LL | | };
| |__________^ help: consider writing: `let Some(v) = g() else { return None };`
error: this could be rewritten as `let...else`
- --> $DIR/manual_let_else_question_mark.rs:64:9
+ --> $DIR/manual_let_else_question_mark.rs:63:9
|
LL | let v = if let Some(v_some) = g() { v_some } else { return None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return None };`
diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.fixed b/src/tools/clippy/tests/ui/manual_main_separator_str.fixed
index 7e7da8f20..6441d6ede 100644
--- a/src/tools/clippy/tests/ui/manual_main_separator_str.fixed
+++ b/src/tools/clippy/tests/ui/manual_main_separator_str.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_main_separator_str)]
diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.rs b/src/tools/clippy/tests/ui/manual_main_separator_str.rs
index cf90e12ef..339dfd8bb 100644
--- a/src/tools/clippy/tests/ui/manual_main_separator_str.rs
+++ b/src/tools/clippy/tests/ui/manual_main_separator_str.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_main_separator_str)]
diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.stderr b/src/tools/clippy/tests/ui/manual_main_separator_str.stderr
index e6cefde66..3e92bd023 100644
--- a/src/tools/clippy/tests/ui/manual_main_separator_str.stderr
+++ b/src/tools/clippy/tests/ui/manual_main_separator_str.stderr
@@ -1,25 +1,26 @@
error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`
- --> $DIR/manual_main_separator_str.rs:23:19
+ --> $DIR/manual_main_separator_str.rs:21:19
|
LL | let _: &str = &MAIN_SEPARATOR.to_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`
|
= note: `-D clippy::manual-main-separator-str` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_main_separator_str)]`
error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`
- --> $DIR/manual_main_separator_str.rs:24:17
+ --> $DIR/manual_main_separator_str.rs:22:17
|
LL | let _ = len(&MAIN_SEPARATOR.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`
error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`
- --> $DIR/manual_main_separator_str.rs:25:23
+ --> $DIR/manual_main_separator_str.rs:23:23
|
LL | let _: Vec<u16> = MAIN_SEPARATOR.to_string().encode_utf16().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`
error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`
- --> $DIR/manual_main_separator_str.rs:29:12
+ --> $DIR/manual_main_separator_str.rs:27:12
|
LL | f: &MAIN_SEPARATOR.to_string(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`
diff --git a/src/tools/clippy/tests/ui/manual_map_option.fixed b/src/tools/clippy/tests/ui/manual_map_option.fixed
index e8ff65cad..16cee3fd3 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.fixed
+++ b/src/tools/clippy/tests/ui/manual_map_option.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_map)]
#![allow(
clippy::no_effect,
@@ -7,6 +5,7 @@
clippy::unit_arg,
clippy::match_ref_pats,
clippy::redundant_pattern_matching,
+ clippy::unnecessary_map_on_constructor,
for_loops_over_fallibles,
dead_code
)]
diff --git a/src/tools/clippy/tests/ui/manual_map_option.rs b/src/tools/clippy/tests/ui/manual_map_option.rs
index b06a96451..4655acf14 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.rs
+++ b/src/tools/clippy/tests/ui/manual_map_option.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_map)]
#![allow(
clippy::no_effect,
@@ -7,6 +5,7 @@
clippy::unit_arg,
clippy::match_ref_pats,
clippy::redundant_pattern_matching,
+ clippy::unnecessary_map_on_constructor,
for_loops_over_fallibles,
dead_code
)]
diff --git a/src/tools/clippy/tests/ui/manual_map_option.stderr b/src/tools/clippy/tests/ui/manual_map_option.stderr
index 3f9caad4e..3754a982c 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.stderr
+++ b/src/tools/clippy/tests/ui/manual_map_option.stderr
@@ -1,5 +1,5 @@
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:15:5
+ --> $DIR/manual_map_option.rs:14:5
|
LL | / match Some(0) {
LL | | Some(_) => Some(2),
@@ -8,9 +8,10 @@ LL | | };
| |_____^ help: try: `Some(0).map(|_| 2)`
|
= note: `-D clippy::manual-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_map)]`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:20:5
+ --> $DIR/manual_map_option.rs:19:5
|
LL | / match Some(0) {
LL | | Some(x) => Some(x + 1),
@@ -19,7 +20,7 @@ LL | | };
| |_____^ help: try: `Some(0).map(|x| x + 1)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:25:5
+ --> $DIR/manual_map_option.rs:24:5
|
LL | / match Some("") {
LL | | Some(x) => Some(x.is_empty()),
@@ -28,7 +29,7 @@ LL | | };
| |_____^ help: try: `Some("").map(|x| x.is_empty())`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:30:5
+ --> $DIR/manual_map_option.rs:29:5
|
LL | / if let Some(x) = Some(0) {
LL | | Some(!x)
@@ -38,7 +39,7 @@ LL | | };
| |_____^ help: try: `Some(0).map(|x| !x)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:37:5
+ --> $DIR/manual_map_option.rs:36:5
|
LL | / match Some(0) {
LL | | Some(x) => { Some(std::convert::identity(x)) }
@@ -47,7 +48,7 @@ LL | | };
| |_____^ help: try: `Some(0).map(std::convert::identity)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:42:5
+ --> $DIR/manual_map_option.rs:41:5
|
LL | / match Some(&String::new()) {
LL | | Some(x) => Some(str::len(x)),
@@ -56,7 +57,7 @@ LL | | };
| |_____^ help: try: `Some(&String::new()).map(|x| str::len(x))`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:52:5
+ --> $DIR/manual_map_option.rs:51:5
|
LL | / match &Some([0, 1]) {
LL | | Some(x) => Some(x[0]),
@@ -65,7 +66,7 @@ LL | | };
| |_____^ help: try: `Some([0, 1]).as_ref().map(|x| x[0])`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:57:5
+ --> $DIR/manual_map_option.rs:56:5
|
LL | / match &Some(0) {
LL | | &Some(x) => Some(x * 2),
@@ -74,7 +75,7 @@ LL | | };
| |_____^ help: try: `Some(0).map(|x| x * 2)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:62:5
+ --> $DIR/manual_map_option.rs:61:5
|
LL | / match Some(String::new()) {
LL | | Some(ref x) => Some(x.is_empty()),
@@ -83,7 +84,7 @@ LL | | };
| |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:67:5
+ --> $DIR/manual_map_option.rs:66:5
|
LL | / match &&Some(String::new()) {
LL | | Some(x) => Some(x.len()),
@@ -92,7 +93,7 @@ LL | | };
| |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:72:5
+ --> $DIR/manual_map_option.rs:71:5
|
LL | / match &&Some(0) {
LL | | &&Some(x) => Some(x + x),
@@ -101,7 +102,7 @@ LL | | };
| |_____^ help: try: `Some(0).map(|x| x + x)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:85:9
+ --> $DIR/manual_map_option.rs:84:9
|
LL | / match &mut Some(String::new()) {
LL | | Some(x) => Some(x.push_str("")),
@@ -110,7 +111,7 @@ LL | | };
| |_________^ help: try: `Some(String::new()).as_mut().map(|x| x.push_str(""))`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:91:5
+ --> $DIR/manual_map_option.rs:90:5
|
LL | / match &mut Some(String::new()) {
LL | | Some(ref x) => Some(x.len()),
@@ -119,7 +120,7 @@ LL | | };
| |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:96:5
+ --> $DIR/manual_map_option.rs:95:5
|
LL | / match &mut &Some(String::new()) {
LL | | Some(x) => Some(x.is_empty()),
@@ -128,7 +129,7 @@ LL | | };
| |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:101:5
+ --> $DIR/manual_map_option.rs:100:5
|
LL | / match Some((0, 1, 2)) {
LL | | Some((x, y, z)) => Some(x + y + z),
@@ -137,7 +138,7 @@ LL | | };
| |_____^ help: try: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:106:5
+ --> $DIR/manual_map_option.rs:105:5
|
LL | / match Some([1, 2, 3]) {
LL | | Some([first, ..]) => Some(first),
@@ -146,7 +147,7 @@ LL | | };
| |_____^ help: try: `Some([1, 2, 3]).map(|[first, ..]| first)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:111:5
+ --> $DIR/manual_map_option.rs:110:5
|
LL | / match &Some((String::new(), "test")) {
LL | | Some((x, y)) => Some((y, x)),
@@ -155,7 +156,7 @@ LL | | };
| |_____^ help: try: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:169:5
+ --> $DIR/manual_map_option.rs:168:5
|
LL | / match Some(0) {
LL | | Some(x) => Some(vec![x]),
@@ -164,7 +165,7 @@ LL | | };
| |_____^ help: try: `Some(0).map(|x| vec![x])`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:174:5
+ --> $DIR/manual_map_option.rs:173:5
|
LL | / match option_env!("") {
LL | | Some(x) => Some(String::from(x)),
@@ -173,7 +174,7 @@ LL | | };
| |_____^ help: try: `option_env!("").map(String::from)`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:194:12
+ --> $DIR/manual_map_option.rs:193:12
|
LL | } else if let Some(x) = Some(0) {
| ____________^
@@ -184,7 +185,7 @@ LL | | };
| |_____^ help: try: `{ Some(0).map(|x| x + 1) }`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option.rs:202:12
+ --> $DIR/manual_map_option.rs:201:12
|
LL | } else if let Some(x) = Some(0) {
| ____________^
diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.fixed b/src/tools/clippy/tests/ui/manual_map_option_2.fixed
index dc7228782..513f6e323 100644
--- a/src/tools/clippy/tests/ui/manual_map_option_2.fixed
+++ b/src/tools/clippy/tests/ui/manual_map_option_2.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_map)]
#![allow(clippy::toplevel_ref_arg)]
diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.rs b/src/tools/clippy/tests/ui/manual_map_option_2.rs
index c495ab0fa..fd186743f 100644
--- a/src/tools/clippy/tests/ui/manual_map_option_2.rs
+++ b/src/tools/clippy/tests/ui/manual_map_option_2.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_map)]
#![allow(clippy::toplevel_ref_arg)]
diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.stderr b/src/tools/clippy/tests/ui/manual_map_option_2.stderr
index 8c78fcffc..bf242c041 100644
--- a/src/tools/clippy/tests/ui/manual_map_option_2.stderr
+++ b/src/tools/clippy/tests/ui/manual_map_option_2.stderr
@@ -1,5 +1,5 @@
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option_2.rs:8:13
+ --> $DIR/manual_map_option_2.rs:6:13
|
LL | let _ = match Some(0) {
| _____________^
@@ -12,6 +12,7 @@ LL | | };
| |_____^
|
= note: `-D clippy::manual-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_map)]`
help: try
|
LL ~ let _ = Some(0).map(|x| {
@@ -21,7 +22,7 @@ LL ~ });
|
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option_2.rs:50:13
+ --> $DIR/manual_map_option_2.rs:48:13
|
LL | let _ = match &s {
| _____________^
@@ -40,7 +41,7 @@ LL ~ });
|
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option_2.rs:62:17
+ --> $DIR/manual_map_option_2.rs:60:17
|
LL | let _ = match Some(0) {
| _________________^
@@ -50,7 +51,7 @@ LL | | };
| |_________^ help: try: `Some(0).map(|x| f(x))`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option_2.rs:67:13
+ --> $DIR/manual_map_option_2.rs:65:13
|
LL | let _ = match Some(0) {
| _____________^
@@ -60,7 +61,7 @@ LL | | };
| |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })`
error: manual implementation of `Option::map`
- --> $DIR/manual_map_option_2.rs:71:13
+ --> $DIR/manual_map_option_2.rs:69:13
|
LL | let _ = match Some(0) {
| _____________^
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs b/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs
index c826b082a..786d7e6e2 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs
+++ b/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs
@@ -1,50 +1,59 @@
#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]
-
+//@no-rustfix
pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
let mut count = 0;
for i in 3..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
+ //~| NOTE: `-D clippy::manual-memcpy` implied by `-D warnings`
dst[i] = src[count];
count += 1;
}
let mut count = 0;
for i in 3..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[count] = src[i];
count += 1;
}
let mut count = 3;
for i in 0..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[count] = src[i];
count += 1;
}
let mut count = 3;
for i in 0..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[count];
count += 1;
}
let mut count = 0;
for i in 3..(3 + src.len()) {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[count];
count += 1;
}
let mut count = 3;
for i in 5..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[count - 2];
count += 1;
}
let mut count = 2;
for i in 0..dst.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[count];
count += 1;
}
let mut count = 5;
for i in 3..10 {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[count];
count += 1;
}
@@ -52,6 +61,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32])
let mut count = 3;
let mut count2 = 30;
for i in 0..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[count] = src[i];
dst2[count2] = src[i];
count += 1;
@@ -62,6 +72,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32])
// arithmetic ones
let mut count = 0 << 1;
for i in 0..1 << 1 {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[count] = src[i + 2];
count += 1;
}
@@ -69,6 +80,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32])
// make sure incrementing expressions without semicolons at the end of loops are handled correctly.
let mut count = 0;
for i in 3..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[count];
count += 1
}
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.stderr b/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.stderr
index 79d40c0bc..3f000fbab 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.stderr
+++ b/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.stderr
@@ -2,80 +2,91 @@ error: it looks like you're manually copying between slices
--> $DIR/with_loop_counters.rs:5:5
|
LL | / for i in 3..src.len() {
+LL | |
+LL | |
LL | | dst[i] = src[count];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);`
|
= note: `-D clippy::manual-memcpy` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:11:5
+ --> $DIR/with_loop_counters.rs:13:5
|
LL | / for i in 3..src.len() {
+LL | |
LL | | dst[count] = src[i];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[..(src.len() - 3)].copy_from_slice(&src[3..]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:17:5
+ --> $DIR/with_loop_counters.rs:20:5
|
LL | / for i in 0..src.len() {
+LL | |
LL | | dst[count] = src[i];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[3..(src.len() + 3)].copy_from_slice(&src[..]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:23:5
+ --> $DIR/with_loop_counters.rs:27:5
|
LL | / for i in 0..src.len() {
+LL | |
LL | | dst[i] = src[count];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[3..(src.len() + 3)]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:29:5
+ --> $DIR/with_loop_counters.rs:34:5
|
LL | / for i in 3..(3 + src.len()) {
+LL | |
LL | | dst[i] = src[count];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[3..(3 + src.len())].copy_from_slice(&src[..(3 + src.len() - 3)]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:35:5
+ --> $DIR/with_loop_counters.rs:41:5
|
LL | / for i in 5..src.len() {
+LL | |
LL | | dst[i] = src[count - 2];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[5..src.len()].copy_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:41:5
+ --> $DIR/with_loop_counters.rs:48:5
|
LL | / for i in 0..dst.len() {
+LL | |
LL | | dst[i] = src[count];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[2..(dst.len() + 2)]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:47:5
+ --> $DIR/with_loop_counters.rs:55:5
|
LL | / for i in 3..10 {
+LL | |
LL | | dst[i] = src[count];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[3..10].copy_from_slice(&src[5..(10 + 5 - 3)]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:54:5
+ --> $DIR/with_loop_counters.rs:63:5
|
LL | / for i in 0..src.len() {
+LL | |
LL | | dst[count] = src[i];
LL | | dst2[count2] = src[i];
LL | | count += 1;
@@ -90,18 +101,20 @@ LL + dst2[30..(src.len() + 30)].copy_from_slice(&src[..]);
|
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:64:5
+ --> $DIR/with_loop_counters.rs:74:5
|
LL | / for i in 0..1 << 1 {
+LL | |
LL | | dst[count] = src[i + 2];
LL | | count += 1;
LL | | }
| |_____^ help: try replacing the loop by: `dst[(0 << 1)..((1 << 1) + (0 << 1))].copy_from_slice(&src[2..((1 << 1) + 2)]);`
error: it looks like you're manually copying between slices
- --> $DIR/with_loop_counters.rs:71:5
+ --> $DIR/with_loop_counters.rs:82:5
|
LL | / for i in 3..src.len() {
+LL | |
LL | | dst[i] = src[count];
LL | | count += 1
LL | | }
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
index 4d5c70f19..a224001a3 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
@@ -1,31 +1,37 @@
#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]
#![allow(clippy::useless_vec)]
-
+//@no-rustfix
const LOOP_OFFSET: usize = 5000;
pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
// plain manual memcpy
for i in 0..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
+ //~| NOTE: `-D clippy::manual-memcpy` implied by `-D warnings`
dst[i] = src[i];
}
// dst offset memcpy
for i in 0..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i + 10] = src[i];
}
// src offset memcpy
for i in 0..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i + 10];
}
// src offset memcpy
for i in 11..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - 10];
}
// overwrite entire dst
for i in 0..dst.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i];
}
@@ -39,6 +45,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
// multiple copies - suggest two memcpy statements
for i in 10..256 {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - 5];
dst2[i + 500] = src[i]
}
@@ -51,6 +58,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
let some_var = 5;
// Offset in variable
for i in 10..LOOP_OFFSET {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i + LOOP_OFFSET] = src[i - some_var];
}
@@ -64,6 +72,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
// make sure vectors are supported
for i in 0..src_vec.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst_vec[i] = src_vec[i];
}
@@ -93,20 +102,24 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
let from = 1;
for i in from..from + src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - from];
}
for i in from..from + 3 {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - from];
}
#[allow(clippy::identity_op)]
for i in 0..5 {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i - 0] = src[i];
}
#[allow(clippy::reversed_empty_ranges)]
for i in 0..0 {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i];
}
@@ -130,6 +143,7 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
#[warn(clippy::needless_range_loop, clippy::manual_memcpy)]
pub fn manual_clone(src: &[String], dst: &mut [String]) {
for i in 0..src.len() {
+ //~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i].clone();
}
}
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
index 1c6a7d5c0..b9dbda6ed 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
@@ -2,48 +2,56 @@ error: it looks like you're manually copying between slices
--> $DIR/without_loop_counters.rs:8:5
|
LL | / for i in 0..src.len() {
+LL | |
+LL | |
LL | | dst[i] = src[i];
LL | | }
| |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[..]);`
|
= note: `-D clippy::manual-memcpy` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:13:5
+ --> $DIR/without_loop_counters.rs:15:5
|
LL | / for i in 0..src.len() {
+LL | |
LL | | dst[i + 10] = src[i];
LL | | }
| |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:18:5
+ --> $DIR/without_loop_counters.rs:21:5
|
LL | / for i in 0..src.len() {
+LL | |
LL | | dst[i] = src[i + 10];
LL | | }
| |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:23:5
+ --> $DIR/without_loop_counters.rs:27:5
|
LL | / for i in 11..src.len() {
+LL | |
LL | | dst[i] = src[i - 10];
LL | | }
| |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:28:5
+ --> $DIR/without_loop_counters.rs:33:5
|
LL | / for i in 0..dst.len() {
+LL | |
LL | | dst[i] = src[i];
LL | | }
| |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:41:5
+ --> $DIR/without_loop_counters.rs:47:5
|
LL | / for i in 10..256 {
+LL | |
LL | | dst[i] = src[i - 5];
LL | | dst2[i + 500] = src[i]
LL | | }
@@ -56,57 +64,64 @@ LL + dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]);
|
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:53:5
+ --> $DIR/without_loop_counters.rs:60:5
|
LL | / for i in 10..LOOP_OFFSET {
+LL | |
LL | | dst[i + LOOP_OFFSET] = src[i - some_var];
LL | | }
| |_____^ 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)]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:66:5
+ --> $DIR/without_loop_counters.rs:74:5
|
LL | / for i in 0..src_vec.len() {
+LL | |
LL | | dst_vec[i] = src_vec[i];
LL | | }
| |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:95:5
+ --> $DIR/without_loop_counters.rs:104:5
|
LL | / for i in from..from + src.len() {
+LL | |
LL | | dst[i] = src[i - from];
LL | | }
| |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:99:5
+ --> $DIR/without_loop_counters.rs:109:5
|
LL | / for i in from..from + 3 {
+LL | |
LL | | dst[i] = src[i - from];
LL | | }
| |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:104:5
+ --> $DIR/without_loop_counters.rs:115:5
|
LL | / for i in 0..5 {
+LL | |
LL | | dst[i - 0] = src[i];
LL | | }
| |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src[..5]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:109:5
+ --> $DIR/without_loop_counters.rs:121:5
|
LL | / for i in 0..0 {
+LL | |
LL | | dst[i] = src[i];
LL | | }
| |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);`
error: it looks like you're manually copying between slices
- --> $DIR/without_loop_counters.rs:132:5
+ --> $DIR/without_loop_counters.rs:145:5
|
LL | / for i in 0..src.len() {
+LL | |
LL | | dst[i] = src[i].clone();
LL | | }
| |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..]);`
diff --git a/src/tools/clippy/tests/ui/manual_next_back.fixed b/src/tools/clippy/tests/ui/manual_next_back.fixed
index e8a47063a..75828f355 100644
--- a/src/tools/clippy/tests/ui/manual_next_back.fixed
+++ b/src/tools/clippy/tests/ui/manual_next_back.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_next_back)]
diff --git a/src/tools/clippy/tests/ui/manual_next_back.rs b/src/tools/clippy/tests/ui/manual_next_back.rs
index 9ec892422..b980e90e1 100644
--- a/src/tools/clippy/tests/ui/manual_next_back.rs
+++ b/src/tools/clippy/tests/ui/manual_next_back.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_next_back)]
diff --git a/src/tools/clippy/tests/ui/manual_next_back.stderr b/src/tools/clippy/tests/ui/manual_next_back.stderr
index 94ccaa9e4..a63d266dd 100644
--- a/src/tools/clippy/tests/ui/manual_next_back.stderr
+++ b/src/tools/clippy/tests/ui/manual_next_back.stderr
@@ -1,13 +1,14 @@
error: manual backwards iteration
- --> $DIR/manual_next_back.rs:34:20
+ --> $DIR/manual_next_back.rs:32:20
|
LL | let _ = (0..10).rev().next().unwrap();
| ^^^^^^^^^^^^^ help: use: `.next_back()`
|
= note: `-D clippy::manual-next-back` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_next_back)]`
error: manual backwards iteration
- --> $DIR/manual_next_back.rs:35:32
+ --> $DIR/manual_next_back.rs:33:32
|
LL | let _ = "something".bytes().rev().next();
| ^^^^^^^^^^^^^ help: use: `.next_back()`
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
index 03b2433f6..0e439dabf 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
@@ -1,8 +1,9 @@
#![feature(lint_reasons)]
#![warn(clippy::manual_non_exhaustive)]
#![allow(unused)]
-
+//@no-rustfix
enum E {
+ //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
A,
B,
#[doc(hidden)]
@@ -12,6 +13,7 @@ enum E {
// user forgot to remove the marker
#[non_exhaustive]
enum Ep {
+ //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
A,
B,
#[doc(hidden)]
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
index 087f766be..ce7e21c94 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
@@ -6,6 +6,7 @@ LL | enum E {
| |
| _help: add the attribute: `#[non_exhaustive] enum E`
| |
+LL | |
LL | | A,
LL | | B,
LL | | #[doc(hidden)]
@@ -14,16 +15,18 @@ LL | | }
| |_^
|
help: remove this variant
- --> $DIR/manual_non_exhaustive_enum.rs:9:5
+ --> $DIR/manual_non_exhaustive_enum.rs:10:5
|
LL | _C,
| ^^
= note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`
error: this seems like a manual implementation of the non-exhaustive pattern
- --> $DIR/manual_non_exhaustive_enum.rs:14:1
+ --> $DIR/manual_non_exhaustive_enum.rs:15:1
|
LL | / enum Ep {
+LL | |
LL | | A,
LL | | B,
LL | | #[doc(hidden)]
@@ -32,7 +35,7 @@ LL | | }
| |_^
|
help: remove this variant
- --> $DIR/manual_non_exhaustive_enum.rs:18:5
+ --> $DIR/manual_non_exhaustive_enum.rs:20:5
|
LL | _C,
| ^^
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
index 498eee444..4b2803ccc 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
@@ -1,8 +1,9 @@
#![warn(clippy::manual_non_exhaustive)]
#![allow(unused)]
-
+//@no-rustfix
mod structs {
struct S {
+ //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
pub a: i32,
pub b: i32,
_c: (),
@@ -11,6 +12,7 @@ mod structs {
// user forgot to remove the private field
#[non_exhaustive]
struct Sp {
+ //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
pub a: i32,
pub b: i32,
_c: (),
@@ -52,10 +54,12 @@ mod structs {
mod tuple_structs {
struct T(pub i32, pub i32, ());
+ //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
// user forgot to remove the private field
#[non_exhaustive]
struct Tp(pub i32, pub i32, ());
+ //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
// some other fields are private, should be ignored
struct PrivateFields(pub i32, i32, ());
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
index d0bed8e11..028b8ff76 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
@@ -6,6 +6,7 @@ LL | struct S {
| |
| _____help: add the attribute: `#[non_exhaustive] struct S`
| |
+LL | |
LL | | pub a: i32,
LL | | pub b: i32,
LL | | _c: (),
@@ -13,16 +14,18 @@ LL | | }
| |_____^
|
help: remove this field
- --> $DIR/manual_non_exhaustive_struct.rs:8:9
+ --> $DIR/manual_non_exhaustive_struct.rs:9:9
|
LL | _c: (),
| ^^^^^^
= note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`
error: this seems like a manual implementation of the non-exhaustive pattern
- --> $DIR/manual_non_exhaustive_struct.rs:13:5
+ --> $DIR/manual_non_exhaustive_struct.rs:14:5
|
LL | / struct Sp {
+LL | |
LL | | pub a: i32,
LL | | pub b: i32,
LL | | _c: (),
@@ -30,13 +33,13 @@ LL | | }
| |_____^
|
help: remove this field
- --> $DIR/manual_non_exhaustive_struct.rs:16:9
+ --> $DIR/manual_non_exhaustive_struct.rs:18:9
|
LL | _c: (),
| ^^^^^^
error: this seems like a manual implementation of the non-exhaustive pattern
- --> $DIR/manual_non_exhaustive_struct.rs:54:5
+ --> $DIR/manual_non_exhaustive_struct.rs:56:5
|
LL | struct T(pub i32, pub i32, ());
| --------^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,19 +47,19 @@ LL | struct T(pub i32, pub i32, ());
| help: add the attribute: `#[non_exhaustive] struct T`
|
help: remove this field
- --> $DIR/manual_non_exhaustive_struct.rs:54:32
+ --> $DIR/manual_non_exhaustive_struct.rs:56:32
|
LL | struct T(pub i32, pub i32, ());
| ^^
error: this seems like a manual implementation of the non-exhaustive pattern
- --> $DIR/manual_non_exhaustive_struct.rs:58:5
+ --> $DIR/manual_non_exhaustive_struct.rs:61:5
|
LL | struct Tp(pub i32, pub i32, ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove this field
- --> $DIR/manual_non_exhaustive_struct.rs:58:33
+ --> $DIR/manual_non_exhaustive_struct.rs:61:33
|
LL | struct Tp(pub i32, pub i32, ());
| ^^
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.fixed b/src/tools/clippy/tests/ui/manual_ok_or.fixed
index d8901dc3b..cc53cb416 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.fixed
+++ b/src/tools/clippy/tests/ui/manual_ok_or.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_ok_or)]
#![allow(clippy::or_fun_call)]
#![allow(clippy::disallowed_names)]
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.rs b/src/tools/clippy/tests/ui/manual_ok_or.rs
index 7188a5213..39c61a1e4 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.rs
+++ b/src/tools/clippy/tests/ui/manual_ok_or.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_ok_or)]
#![allow(clippy::or_fun_call)]
#![allow(clippy::disallowed_names)]
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.stderr b/src/tools/clippy/tests/ui/manual_ok_or.stderr
index b4a17f143..ddb2cf261 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.stderr
+++ b/src/tools/clippy/tests/ui/manual_ok_or.stderr
@@ -1,25 +1,26 @@
error: this pattern reimplements `Option::ok_or`
- --> $DIR/manual_ok_or.rs:12:5
+ --> $DIR/manual_ok_or.rs:11:5
|
LL | foo.map_or(Err("error"), |v| Ok(v));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")`
|
= note: `-D clippy::manual-ok-or` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_ok_or)]`
error: this pattern reimplements `Option::ok_or`
- --> $DIR/manual_ok_or.rs:15:5
+ --> $DIR/manual_ok_or.rs:14:5
|
LL | foo.map_or(Err("error"), Ok);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")`
error: this pattern reimplements `Option::ok_or`
- --> $DIR/manual_ok_or.rs:18:5
+ --> $DIR/manual_ok_or.rs:17:5
|
LL | None::<i32>.map_or(Err("error"), |v| Ok(v));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `None::<i32>.ok_or("error")`
error: this pattern reimplements `Option::ok_or`
- --> $DIR/manual_ok_or.rs:22:5
+ --> $DIR/manual_ok_or.rs:21:5
|
LL | / foo.map_or(Err::<i32, &str>(
LL | | &format!(
diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.fixed b/src/tools/clippy/tests/ui/manual_range_patterns.fixed
index 6bfcf263a..b348d7071 100644
--- a/src/tools/clippy/tests/ui/manual_range_patterns.fixed
+++ b/src/tools/clippy/tests/ui/manual_range_patterns.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_range_patterns)]
#![feature(exclusive_range_pattern)]
@@ -15,8 +13,8 @@ fn main() {
let _ = matches!(f, 1 | 2147483647);
let _ = matches!(f, 0 | 2147483647);
let _ = matches!(f, -2147483647 | 2147483647);
- let _ = matches!(f, 1 | (2..=4));
- let _ = matches!(f, 1 | (2..4));
+ let _ = matches!(f, 1..=4);
+ let _ = matches!(f, 1..4);
let _ = matches!(f, 1..=48324729);
let _ = matches!(f, 0..=48324730);
let _ = matches!(f, 0..=3);
@@ -27,9 +25,20 @@ fn main() {
};
let _ = matches!(f, -5..=3);
let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing
- let _ = matches!(f, -1000001..=1000001);
+ let _ = matches!(f, -1_000_001..=1_000_001);
let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002);
+ matches!(f, 0x00..=0x03);
+ matches!(f, 0x00..=0x07);
+ matches!(f, -0x09..=0x00);
+
+ matches!(f, 0..=5);
+ matches!(f, 0..5);
+
+ matches!(f, 0..10);
+ matches!(f, 0..=10);
+ matches!(f, 0..=10);
+
macro_rules! mac {
($e:expr) => {
matches!($e, 1..=10)
diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.rs b/src/tools/clippy/tests/ui/manual_range_patterns.rs
index 4a429bb2a..a0750f54b 100644
--- a/src/tools/clippy/tests/ui/manual_range_patterns.rs
+++ b/src/tools/clippy/tests/ui/manual_range_patterns.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_range_patterns)]
#![feature(exclusive_range_pattern)]
@@ -30,6 +28,17 @@ fn main() {
let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001);
let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002);
+ matches!(f, 0x00 | 0x01 | 0x02 | 0x03);
+ matches!(f, 0x00..=0x05 | 0x06 | 0x07);
+ matches!(f, -0x09 | -0x08 | -0x07..=0x00);
+
+ matches!(f, 0..5 | 5);
+ matches!(f, 0 | 1..5);
+
+ matches!(f, 0..=5 | 6..10);
+ matches!(f, 0..5 | 5..=10);
+ matches!(f, 5..=10 | 0..5);
+
macro_rules! mac {
($e:expr) => {
matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10)
diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.stderr b/src/tools/clippy/tests/ui/manual_range_patterns.stderr
index b1b55d483..fbeb94557 100644
--- a/src/tools/clippy/tests/ui/manual_range_patterns.stderr
+++ b/src/tools/clippy/tests/ui/manual_range_patterns.stderr
@@ -1,55 +1,116 @@
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:10:25
+ --> $DIR/manual_range_patterns.rs:8:25
|
LL | let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
|
= note: `-D clippy::manual-range-patterns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_range_patterns)]`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:11:25
+ --> $DIR/manual_range_patterns.rs:9:25
|
LL | let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:20:25
+ --> $DIR/manual_range_patterns.rs:16:25
+ |
+LL | let _ = matches!(f, 1 | (2..=4));
+ | ^^^^^^^^^^^ help: try: `1..=4`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:17:25
+ |
+LL | let _ = matches!(f, 1 | (2..4));
+ | ^^^^^^^^^^ help: try: `1..4`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:18:25
|
LL | let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=48324729`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:21:25
+ --> $DIR/manual_range_patterns.rs:19:25
|
LL | let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=48324730`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:22:25
+ --> $DIR/manual_range_patterns.rs:20:25
|
LL | let _ = matches!(f, 0..=1 | 0..=2 | 0..=3);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=3`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:25:9
+ --> $DIR/manual_range_patterns.rs:23:9
|
LL | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:28:25
+ --> $DIR/manual_range_patterns.rs:26:25
|
LL | let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-5..=3`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:30:25
+ --> $DIR/manual_range_patterns.rs:28:25
|
LL | let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-1000001..=1000001`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-1_000_001..=1_000_001`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:31:17
+ |
+LL | matches!(f, 0x00 | 0x01 | 0x02 | 0x03);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x03`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:32:17
+ |
+LL | matches!(f, 0x00..=0x05 | 0x06 | 0x07);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x07`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:33:17
+ |
+LL | matches!(f, -0x09 | -0x08 | -0x07..=0x00);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-0x09..=0x00`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:35:17
+ |
+LL | matches!(f, 0..5 | 5);
+ | ^^^^^^^^ help: try: `0..=5`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:36:17
+ |
+LL | matches!(f, 0 | 1..5);
+ | ^^^^^^^^ help: try: `0..5`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:38:17
+ |
+LL | matches!(f, 0..=5 | 6..10);
+ | ^^^^^^^^^^^^^ help: try: `0..10`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:39:17
+ |
+LL | matches!(f, 0..5 | 5..=10);
+ | ^^^^^^^^^^^^^ help: try: `0..=10`
+
+error: this OR pattern can be rewritten using a range
+ --> $DIR/manual_range_patterns.rs:40:17
+ |
+LL | matches!(f, 5..=10 | 0..5);
+ | ^^^^^^^^^^^^^ help: try: `0..=10`
error: this OR pattern can be rewritten using a range
- --> $DIR/manual_range_patterns.rs:35:26
+ --> $DIR/manual_range_patterns.rs:44:26
|
LL | matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
@@ -59,5 +120,5 @@ LL | mac!(f);
|
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 9 previous errors
+error: aborting due to 19 previous errors
diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed
index 594a76897..2d5086558 100644
--- a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed
+++ b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::manual_rem_euclid)]
#![allow(clippy::let_with_type_underscore)]
diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.rs b/src/tools/clippy/tests/ui/manual_rem_euclid.rs
index d5f98e715..e405a2db4 100644
--- a/src/tools/clippy/tests/ui/manual_rem_euclid.rs
+++ b/src/tools/clippy/tests/ui/manual_rem_euclid.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::manual_rem_euclid)]
#![allow(clippy::let_with_type_underscore)]
diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.stderr b/src/tools/clippy/tests/ui/manual_rem_euclid.stderr
index a43707f89..f296f2646 100644
--- a/src/tools/clippy/tests/ui/manual_rem_euclid.stderr
+++ b/src/tools/clippy/tests/ui/manual_rem_euclid.stderr
@@ -1,37 +1,38 @@
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:14:18
+ --> $DIR/manual_rem_euclid.rs:13:18
|
LL | let _: i32 = ((value % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
|
= note: `-D clippy::manual-rem-euclid` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_rem_euclid)]`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:15:18
+ --> $DIR/manual_rem_euclid.rs:14:18
|
LL | let _: i32 = (4 + (value % 4)) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:16:18
+ --> $DIR/manual_rem_euclid.rs:15:18
|
LL | let _: i32 = (value % 4 + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:17:18
+ --> $DIR/manual_rem_euclid.rs:16:18
|
LL | let _: i32 = (4 + value % 4) % 4;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:18:22
+ --> $DIR/manual_rem_euclid.rs:17:22
|
LL | let _: i32 = 1 + (4 + value % 4) % 4;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:38:22
+ --> $DIR/manual_rem_euclid.rs:37:22
|
LL | let _: i32 = ((value % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
@@ -39,25 +40,25 @@ LL | let _: i32 = ((value % 4) + 4) % 4;
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:50:5
+ --> $DIR/manual_rem_euclid.rs:49:5
|
LL | ((num % 4) + 4) % 4
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:55:5
+ --> $DIR/manual_rem_euclid.rs:54:5
|
LL | ((num % 4) + 4) % 4
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:67:18
+ --> $DIR/manual_rem_euclid.rs:66:18
|
LL | let _: i32 = ((x % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:80:18
+ --> $DIR/manual_rem_euclid.rs:79:18
|
LL | let _: i32 = ((x % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)`
diff --git a/src/tools/clippy/tests/ui/manual_retain.fixed b/src/tools/clippy/tests/ui/manual_retain.fixed
index c95d40fec..4dea3e8bf 100644
--- a/src/tools/clippy/tests/ui/manual_retain.fixed
+++ b/src/tools/clippy/tests/ui/manual_retain.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_retain)]
#![allow(unused, clippy::redundant_clone)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
@@ -18,22 +17,31 @@ fn main() {
}
fn binary_heap_retain() {
- // NOTE: Do not lint now, because binary_heap_retain is nightly API.
- // And we need to add a test case for msrv if we update this implementation.
- // https://github.com/rust-lang/rust/issues/71503
- let mut heap = BinaryHeap::from([1, 2, 3]);
- heap = heap.into_iter().filter(|x| x % 2 == 0).collect();
- heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
- heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
+ let mut binary_heap = BinaryHeap::from([1, 2, 3]);
+ // Do lint.
+ binary_heap.retain(|x| x % 2 == 0);
+ binary_heap.retain(|x| x % 2 == 0);
+ binary_heap.retain(|x| x % 2 == 0);
// Do not lint, because type conversion is performed
- heap = heap.into_iter().filter(|x| x % 2 == 0).collect::<BinaryHeap<i8>>();
- heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect::<BinaryHeap<i8>>();
- heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect::<BinaryHeap<i8>>();
+ binary_heap = binary_heap
+ .into_iter()
+ .filter(|x| x % 2 == 0)
+ .collect::<BinaryHeap<i8>>();
+ binary_heap = binary_heap
+ .iter()
+ .filter(|&x| x % 2 == 0)
+ .copied()
+ .collect::<BinaryHeap<i8>>();
+ binary_heap = binary_heap
+ .iter()
+ .filter(|&x| x % 2 == 0)
+ .cloned()
+ .collect::<BinaryHeap<i8>>();
// Do not lint, because this expression is not assign.
- let mut bar: BinaryHeap<i8> = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
- let mut foobar: BinaryHeap<i8> = heap.into_iter().filter(|x| x % 2 == 0).collect();
+ let mut bar: BinaryHeap<i8> = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
+ let mut foobar: BinaryHeap<i8> = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
// Do not lint, because it is an assignment to a different variable.
bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
@@ -210,6 +218,12 @@ fn vec_deque_retain() {
bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
}
+#[clippy::msrv = "1.69"]
+fn _msrv_169() {
+ let mut binary_heap = BinaryHeap::from([1, 2, 3]);
+ binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
+}
+
#[clippy::msrv = "1.52"]
fn _msrv_153() {
let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
diff --git a/src/tools/clippy/tests/ui/manual_retain.rs b/src/tools/clippy/tests/ui/manual_retain.rs
index 9a3434f48..d839550f3 100644
--- a/src/tools/clippy/tests/ui/manual_retain.rs
+++ b/src/tools/clippy/tests/ui/manual_retain.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::manual_retain)]
#![allow(unused, clippy::redundant_clone)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
@@ -18,22 +17,31 @@ fn main() {
}
fn binary_heap_retain() {
- // NOTE: Do not lint now, because binary_heap_retain is nightly API.
- // And we need to add a test case for msrv if we update this implementation.
- // https://github.com/rust-lang/rust/issues/71503
- let mut heap = BinaryHeap::from([1, 2, 3]);
- heap = heap.into_iter().filter(|x| x % 2 == 0).collect();
- heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
- heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
+ let mut binary_heap = BinaryHeap::from([1, 2, 3]);
+ // Do lint.
+ binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
+ binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
+ binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
// Do not lint, because type conversion is performed
- heap = heap.into_iter().filter(|x| x % 2 == 0).collect::<BinaryHeap<i8>>();
- heap = heap.iter().filter(|&x| x % 2 == 0).copied().collect::<BinaryHeap<i8>>();
- heap = heap.iter().filter(|&x| x % 2 == 0).cloned().collect::<BinaryHeap<i8>>();
+ binary_heap = binary_heap
+ .into_iter()
+ .filter(|x| x % 2 == 0)
+ .collect::<BinaryHeap<i8>>();
+ binary_heap = binary_heap
+ .iter()
+ .filter(|&x| x % 2 == 0)
+ .copied()
+ .collect::<BinaryHeap<i8>>();
+ binary_heap = binary_heap
+ .iter()
+ .filter(|&x| x % 2 == 0)
+ .cloned()
+ .collect::<BinaryHeap<i8>>();
// Do not lint, because this expression is not assign.
- let mut bar: BinaryHeap<i8> = heap.iter().filter(|&x| x % 2 == 0).copied().collect();
- let mut foobar: BinaryHeap<i8> = heap.into_iter().filter(|x| x % 2 == 0).collect();
+ let mut bar: BinaryHeap<i8> = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
+ let mut foobar: BinaryHeap<i8> = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
// Do not lint, because it is an assignment to a different variable.
bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();
@@ -216,6 +224,12 @@ fn vec_deque_retain() {
bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
}
+#[clippy::msrv = "1.69"]
+fn _msrv_169() {
+ let mut binary_heap = BinaryHeap::from([1, 2, 3]);
+ binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
+}
+
#[clippy::msrv = "1.52"]
fn _msrv_153() {
let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
diff --git a/src/tools/clippy/tests/ui/manual_retain.stderr b/src/tools/clippy/tests/ui/manual_retain.stderr
index 0936a2384..0c5b1383b 100644
--- a/src/tools/clippy/tests/ui/manual_retain.stderr
+++ b/src/tools/clippy/tests/ui/manual_retain.stderr
@@ -1,19 +1,38 @@
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:46:5
+ --> $DIR/manual_retain.rs:22:5
|
-LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`
+LL | binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
|
= note: `-D clippy::manual-retain` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_retain)]`
+
+error: this expression can be written more simply using `.retain()`
+ --> $DIR/manual_retain.rs:23:5
+ |
+LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
+
+error: this expression can be written more simply using `.retain()`
+ --> $DIR/manual_retain.rs:24:5
+ |
+LL | binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
+
+error: this expression can be written more simply using `.retain()`
+ --> $DIR/manual_retain.rs:54:5
+ |
+LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:47:5
+ --> $DIR/manual_retain.rs:55:5
|
LL | btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:48:5
+ --> $DIR/manual_retain.rs:56:5
|
LL | / btree_map = btree_map
LL | | .into_iter()
@@ -22,37 +41,37 @@ LL | | .collect();
| |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:70:5
+ --> $DIR/manual_retain.rs:78:5
|
LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:71:5
+ --> $DIR/manual_retain.rs:79:5
|
LL | btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:72:5
+ --> $DIR/manual_retain.rs:80:5
|
LL | btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:102:5
+ --> $DIR/manual_retain.rs:110:5
|
LL | hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:103:5
+ --> $DIR/manual_retain.rs:111:5
|
LL | hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:104:5
+ --> $DIR/manual_retain.rs:112:5
|
LL | / hash_map = hash_map
LL | | .into_iter()
@@ -61,64 +80,64 @@ LL | | .collect();
| |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:125:5
+ --> $DIR/manual_retain.rs:133:5
|
LL | hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:126:5
+ --> $DIR/manual_retain.rs:134:5
|
LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:127:5
+ --> $DIR/manual_retain.rs:135:5
|
LL | hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:156:5
+ --> $DIR/manual_retain.rs:164:5
|
LL | s = s.chars().filter(|&c| c != 'o').to_owned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:168:5
+ --> $DIR/manual_retain.rs:176:5
|
LL | vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:169:5
+ --> $DIR/manual_retain.rs:177:5
|
LL | vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:170:5
+ --> $DIR/manual_retain.rs:178:5
|
LL | vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:192:5
+ --> $DIR/manual_retain.rs:200:5
|
LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:193:5
+ --> $DIR/manual_retain.rs:201:5
|
LL | vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:194:5
+ --> $DIR/manual_retain.rs:202:5
|
LL | vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
-error: aborting due to 19 previous errors
+error: aborting due to 22 previous errors
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
index 7dd4521fa..8218f1088 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_imports)]
use std::{i128, i32, u128, u32};
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
index 463ee0692..60022b54b 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_imports)]
use std::{i128, i32, u128, u32};
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr
index d985f2e75..dc36a5ee7 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr
@@ -1,25 +1,26 @@
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:8:13
+ --> $DIR/manual_saturating_arithmetic.rs:6:13
|
LL | let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u32.saturating_add(1)`
|
= note: `-D clippy::manual-saturating-arithmetic` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_saturating_arithmetic)]`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:9:13
+ --> $DIR/manual_saturating_arithmetic.rs:7:13
|
LL | let _ = 1u32.checked_add(1).unwrap_or(u32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u32.saturating_add(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:10:13
+ --> $DIR/manual_saturating_arithmetic.rs:8:13
|
LL | let _ = 1u8.checked_add(1).unwrap_or(255);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u8.saturating_add(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:11:13
+ --> $DIR/manual_saturating_arithmetic.rs:9:13
|
LL | let _ = 1u128
| _____________^
@@ -28,49 +29,49 @@ LL | | .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455);
| |_______________________________________________________________________^ help: try using `saturating_add`: `1u128.saturating_add(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:16:13
+ --> $DIR/manual_saturating_arithmetic.rs:14:13
|
LL | let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_mul`: `1u32.saturating_mul(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:18:13
+ --> $DIR/manual_saturating_arithmetic.rs:16:13
|
LL | let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u32.saturating_sub(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:19:13
+ --> $DIR/manual_saturating_arithmetic.rs:17:13
|
LL | let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u32.saturating_sub(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:20:13
+ --> $DIR/manual_saturating_arithmetic.rs:18:13
|
LL | let _ = 1u8.checked_sub(1).unwrap_or(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u8.saturating_sub(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:24:13
+ --> $DIR/manual_saturating_arithmetic.rs:22:13
|
LL | let _ = 1i32.checked_add(1).unwrap_or(i32::max_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:25:13
+ --> $DIR/manual_saturating_arithmetic.rs:23:13
|
LL | let _ = 1i32.checked_add(1).unwrap_or(i32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:26:13
+ --> $DIR/manual_saturating_arithmetic.rs:24:13
|
LL | let _ = 1i8.checked_add(1).unwrap_or(127);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i8.saturating_add(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:27:13
+ --> $DIR/manual_saturating_arithmetic.rs:25:13
|
LL | let _ = 1i128
| _____________^
@@ -79,25 +80,25 @@ LL | | .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);
| |_______________________________________________________________________^ help: try using `saturating_add`: `1i128.saturating_add(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:30:13
+ --> $DIR/manual_saturating_arithmetic.rs:28:13
|
LL | let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(-1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:31:13
+ --> $DIR/manual_saturating_arithmetic.rs:29:13
|
LL | let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(-1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:32:13
+ --> $DIR/manual_saturating_arithmetic.rs:30:13
|
LL | let _ = 1i8.checked_add(-1).unwrap_or(-128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i8.saturating_add(-1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:33:13
+ --> $DIR/manual_saturating_arithmetic.rs:31:13
|
LL | let _ = 1i128
| _____________^
@@ -106,25 +107,25 @@ LL | | .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
| |________________________________________________________________________^ help: try using `saturating_add`: `1i128.saturating_add(-1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:40:13
+ --> $DIR/manual_saturating_arithmetic.rs:38:13
|
LL | let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:41:13
+ --> $DIR/manual_saturating_arithmetic.rs:39:13
|
LL | let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:42:13
+ --> $DIR/manual_saturating_arithmetic.rs:40:13
|
LL | let _ = 1i8.checked_sub(1).unwrap_or(-128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i8.saturating_sub(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:43:13
+ --> $DIR/manual_saturating_arithmetic.rs:41:13
|
LL | let _ = 1i128
| _____________^
@@ -133,25 +134,25 @@ LL | | .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
| |________________________________________________________________________^ help: try using `saturating_sub`: `1i128.saturating_sub(1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:46:13
+ --> $DIR/manual_saturating_arithmetic.rs:44:13
|
LL | let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(-1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:47:13
+ --> $DIR/manual_saturating_arithmetic.rs:45:13
|
LL | let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(-1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:48:13
+ --> $DIR/manual_saturating_arithmetic.rs:46:13
|
LL | let _ = 1i8.checked_sub(-1).unwrap_or(127);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i8.saturating_sub(-1)`
error: manual saturating arithmetic
- --> $DIR/manual_saturating_arithmetic.rs:49:13
+ --> $DIR/manual_saturating_arithmetic.rs:47:13
|
LL | let _ = 1i128
| _____________^
diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed b/src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed
index 5b9629f4b..62b372f4b 100644
--- a/src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed
+++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused)]
#![warn(clippy::manual_slice_size_calculation)]
diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs b/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs
index 297887a9c..d59f5fd8b 100644
--- a/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs
+++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused)]
#![warn(clippy::manual_slice_size_calculation)]
diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr b/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr
index e09d8057a..ebdb74813 100644
--- a/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr
+++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr
@@ -1,43 +1,44 @@
error: manual slice size calculation
- --> $DIR/manual_slice_size_calculation.rs:16:13
+ --> $DIR/manual_slice_size_calculation.rs:15:13
|
LL | let _ = s_i32.len() * size_of::<i32>(); // WARNING
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`
|
= note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_slice_size_calculation)]`
error: manual slice size calculation
- --> $DIR/manual_slice_size_calculation.rs:17:13
+ --> $DIR/manual_slice_size_calculation.rs:16:13
|
LL | let _ = size_of::<i32>() * s_i32.len(); // WARNING
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`
error: manual slice size calculation
- --> $DIR/manual_slice_size_calculation.rs:18:13
+ --> $DIR/manual_slice_size_calculation.rs:17:13
|
LL | let _ = size_of::<i32>() * s_i32.len() * 5; // WARNING
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`
error: manual slice size calculation
- --> $DIR/manual_slice_size_calculation.rs:22:13
+ --> $DIR/manual_slice_size_calculation.rs:21:13
|
LL | let _ = len * size_of::<i32>(); // WARNING
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`
error: manual slice size calculation
- --> $DIR/manual_slice_size_calculation.rs:23:13
+ --> $DIR/manual_slice_size_calculation.rs:22:13
|
LL | let _ = s_i32.len() * size; // WARNING
| ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`
error: manual slice size calculation
- --> $DIR/manual_slice_size_calculation.rs:24:13
+ --> $DIR/manual_slice_size_calculation.rs:23:13
|
LL | let _ = len * size; // WARNING
| ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`
error: manual slice size calculation
- --> $DIR/manual_slice_size_calculation.rs:26:13
+ --> $DIR/manual_slice_size_calculation.rs:25:13
|
LL | let _ = external!(&[1u64][..]).len() * size_of::<u64>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))`
diff --git a/src/tools/clippy/tests/ui/manual_split_once.fixed b/src/tools/clippy/tests/ui/manual_split_once.fixed
index e317c5971..aaac6a048 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.fixed
+++ b/src/tools/clippy/tests/ui/manual_split_once.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_split_once)]
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
diff --git a/src/tools/clippy/tests/ui/manual_split_once.rs b/src/tools/clippy/tests/ui/manual_split_once.rs
index 7e2dc22bc..113e1737c 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.rs
+++ b/src/tools/clippy/tests/ui/manual_split_once.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_split_once)]
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
diff --git a/src/tools/clippy/tests/ui/manual_split_once.stderr b/src/tools/clippy/tests/ui/manual_split_once.stderr
index f454f95b4..494a035ed 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.stderr
+++ b/src/tools/clippy/tests/ui/manual_split_once.stderr
@@ -1,85 +1,86 @@
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:13:13
+ --> $DIR/manual_split_once.rs:11:13
|
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
|
= note: `-D clippy::manual-split-once` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_split_once)]`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:14:13
+ --> $DIR/manual_split_once.rs:12:13
|
LL | let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:15:18
+ --> $DIR/manual_split_once.rs:13:18
|
LL | let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=')`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:18:13
+ --> $DIR/manual_split_once.rs:16:13
|
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:21:13
+ --> $DIR/manual_split_once.rs:19:13
|
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:24:13
+ --> $DIR/manual_split_once.rs:22:13
|
LL | let _ = s.splitn(2, '=').skip(1).next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:27:17
+ --> $DIR/manual_split_once.rs:25:17
|
LL | let _ = s.splitn(2, '=').nth(1)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:28:17
+ --> $DIR/manual_split_once.rs:26:17
|
LL | let _ = s.splitn(2, '=').skip(1).next()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:29:17
+ --> $DIR/manual_split_once.rs:27:17
|
LL | let _ = s.rsplitn(2, '=').nth(1)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:30:17
+ --> $DIR/manual_split_once.rs:28:17
|
LL | let _ = s.rsplitn(2, '=').skip(1).next()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:38:13
+ --> $DIR/manual_split_once.rs:36:13
|
LL | let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').unwrap().0`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:39:18
+ --> $DIR/manual_split_once.rs:37:18
|
LL | let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:40:13
+ --> $DIR/manual_split_once.rs:38:13
|
LL | let _ = s.rsplitn(2, '=').nth(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:44:5
+ --> $DIR/manual_split_once.rs:42:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +105,7 @@ LL +
|
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:48:5
+ --> $DIR/manual_split_once.rs:46:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,7 +130,7 @@ LL +
|
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:52:5
+ --> $DIR/manual_split_once.rs:50:5
|
LL | let mut iter = "a.b.c".rsplitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,7 +155,7 @@ LL +
|
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:56:5
+ --> $DIR/manual_split_once.rs:54:5
|
LL | let mut iter = "a.b.c".rsplitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -179,13 +180,13 @@ LL +
|
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:141:13
+ --> $DIR/manual_split_once.rs:139:13
|
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:143:5
+ --> $DIR/manual_split_once.rs:141:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.fixed b/src/tools/clippy/tests/ui/manual_str_repeat.fixed
index 9468c3df9..888a46627 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.fixed
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_str_repeat)]
use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.rs b/src/tools/clippy/tests/ui/manual_str_repeat.rs
index baa0a1026..a366351ff 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.rs
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_str_repeat)]
use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.stderr b/src/tools/clippy/tests/ui/manual_str_repeat.stderr
index 331bb6ea5..9a13aa972 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.stderr
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.stderr
@@ -1,61 +1,62 @@
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:9:21
+ --> $DIR/manual_str_repeat.rs:7:21
|
LL | let _: String = std::iter::repeat("test").take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"test".repeat(10)`
|
= note: `-D clippy::manual-str-repeat` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_str_repeat)]`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:10:21
+ --> $DIR/manual_str_repeat.rs:8:21
|
LL | let _: String = std::iter::repeat('x').take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"x".repeat(10)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:11:21
+ --> $DIR/manual_str_repeat.rs:9:21
|
-LL | let _: String = std::iter::repeat('/'').take(10).collect();
+LL | let _: String = std::iter::repeat('\'').take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"'".repeat(10)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:12:21
+ --> $DIR/manual_str_repeat.rs:10:21
|
LL | let _: String = std::iter::repeat('"').take(10).collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"/"".repeat(10)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"\"".repeat(10)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:16:13
+ --> $DIR/manual_str_repeat.rs:14:13
|
LL | let _ = repeat(x).take(count + 2).collect::<String>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count + 2)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:25:21
+ --> $DIR/manual_str_repeat.rs:23:21
|
LL | let _: String = repeat(*x).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*x).repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:34:21
+ --> $DIR/manual_str_repeat.rs:32:21
|
LL | let _: String = repeat(x).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:46:21
+ --> $DIR/manual_str_repeat.rs:44:21
|
LL | let _: String = repeat(Cow::Borrowed("test")).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Cow::Borrowed("test").repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:49:21
+ --> $DIR/manual_str_repeat.rs:47:21
|
LL | let _: String = repeat(x).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:64:21
+ --> $DIR/manual_str_repeat.rs:62:21
|
LL | let _: String = std::iter::repeat("test").take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"test".repeat(10)`
diff --git a/src/tools/clippy/tests/ui/manual_string_new.fixed b/src/tools/clippy/tests/ui/manual_string_new.fixed
index 0d1bab233..273be4e0f 100644
--- a/src/tools/clippy/tests/ui/manual_string_new.fixed
+++ b/src/tools/clippy/tests/ui/manual_string_new.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_string_new)]
macro_rules! create_strings_from_macro {
diff --git a/src/tools/clippy/tests/ui/manual_string_new.rs b/src/tools/clippy/tests/ui/manual_string_new.rs
index 2392ebfc3..0d5514fc8 100644
--- a/src/tools/clippy/tests/ui/manual_string_new.rs
+++ b/src/tools/clippy/tests/ui/manual_string_new.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_string_new)]
macro_rules! create_strings_from_macro {
diff --git a/src/tools/clippy/tests/ui/manual_string_new.stderr b/src/tools/clippy/tests/ui/manual_string_new.stderr
index e5ecfc619..399652d3f 100644
--- a/src/tools/clippy/tests/ui/manual_string_new.stderr
+++ b/src/tools/clippy/tests/ui/manual_string_new.stderr
@@ -1,55 +1,56 @@
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:15:13
+ --> $DIR/manual_string_new.rs:13:13
|
LL | let _ = "".to_string();
| ^^^^^^^^^^^^^^ help: consider using: `String::new()`
|
= note: `-D clippy::manual-string-new` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_string_new)]`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:18:13
+ --> $DIR/manual_string_new.rs:16:13
|
LL | let _ = "".to_owned();
| ^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:21:21
+ --> $DIR/manual_string_new.rs:19:21
|
LL | let _: String = "".into();
| ^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:28:13
+ --> $DIR/manual_string_new.rs:26:13
|
LL | let _ = String::from("");
| ^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:29:13
+ --> $DIR/manual_string_new.rs:27:13
|
LL | let _ = <String>::from("");
| ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:34:13
+ --> $DIR/manual_string_new.rs:32:13
|
LL | let _ = String::try_from("").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:40:21
+ --> $DIR/manual_string_new.rs:38:21
|
LL | let _: String = From::from("");
| ^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:45:21
+ --> $DIR/manual_string_new.rs:43:21
|
LL | let _: String = TryFrom::try_from("").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
error: empty String is being created manually
- --> $DIR/manual_string_new.rs:48:21
+ --> $DIR/manual_string_new.rs:46:21
|
LL | let _: String = TryFrom::try_from("").expect("this should warn");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`
diff --git a/src/tools/clippy/tests/ui/manual_strip.rs b/src/tools/clippy/tests/ui/manual_strip.rs
index b0b1c262a..8bd0300e6 100644
--- a/src/tools/clippy/tests/ui/manual_strip.rs
+++ b/src/tools/clippy/tests/ui/manual_strip.rs
@@ -1,10 +1,11 @@
#![warn(clippy::manual_strip)]
-
+//@no-rustfix
fn main() {
let s = "abc";
if s.starts_with("ab") {
str::to_string(&s["ab".len()..]);
+ //~^ ERROR: stripping a prefix manually
s["ab".len()..].to_string();
str::to_string(&s[2..]);
@@ -13,6 +14,7 @@ fn main() {
if s.ends_with("bc") {
str::to_string(&s[..s.len() - "bc".len()]);
+ //~^ ERROR: stripping a suffix manually
s[..s.len() - "bc".len()].to_string();
str::to_string(&s[..s.len() - 2]);
@@ -22,6 +24,7 @@ fn main() {
// Character patterns
if s.starts_with('a') {
str::to_string(&s[1..]);
+ //~^ ERROR: stripping a prefix manually
s[1..].to_string();
}
@@ -29,12 +32,14 @@ fn main() {
let prefix = "ab";
if s.starts_with(prefix) {
str::to_string(&s[prefix.len()..]);
+ //~^ ERROR: stripping a prefix manually
}
// Constant prefix
const PREFIX: &str = "ab";
if s.starts_with(PREFIX) {
str::to_string(&s[PREFIX.len()..]);
+ //~^ ERROR: stripping a prefix manually
str::to_string(&s[2..]);
}
@@ -42,12 +47,14 @@ fn main() {
const TARGET: &str = "abc";
if TARGET.starts_with(prefix) {
str::to_string(&TARGET[prefix.len()..]);
+ //~^ ERROR: stripping a prefix manually
}
// String target - not mutated.
let s1: String = "abc".into();
if s1.starts_with("ab") {
s1[2..].to_uppercase();
+ //~^ ERROR: stripping a prefix manually
}
// String target - mutated. (Don't lint.)
@@ -78,5 +85,6 @@ fn msrv_1_45() {
let s = "abc";
if s.starts_with('a') {
s[1..].to_string();
+ //~^ ERROR: stripping a prefix manually
}
}
diff --git a/src/tools/clippy/tests/ui/manual_strip.stderr b/src/tools/clippy/tests/ui/manual_strip.stderr
index f592e898f..0bf6975b1 100644
--- a/src/tools/clippy/tests/ui/manual_strip.stderr
+++ b/src/tools/clippy/tests/ui/manual_strip.stderr
@@ -10,10 +10,12 @@ note: the prefix was tested here
LL | if s.starts_with("ab") {
| ^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::manual-strip` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_strip)]`
help: try using the `strip_prefix` method
|
LL ~ if let Some(<stripped>) = s.strip_prefix("ab") {
LL ~ str::to_string(<stripped>);
+LL |
LL ~ <stripped>.to_string();
LL |
LL ~ str::to_string(<stripped>);
@@ -21,13 +23,13 @@ LL ~ <stripped>.to_string();
|
error: stripping a suffix manually
- --> $DIR/manual_strip.rs:15:24
+ --> $DIR/manual_strip.rs:16:24
|
LL | str::to_string(&s[..s.len() - "bc".len()]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the suffix was tested here
- --> $DIR/manual_strip.rs:14:5
+ --> $DIR/manual_strip.rs:15:5
|
LL | if s.ends_with("bc") {
| ^^^^^^^^^^^^^^^^^^^^^
@@ -35,6 +37,7 @@ help: try using the `strip_suffix` method
|
LL ~ if let Some(<stripped>) = s.strip_suffix("bc") {
LL ~ str::to_string(<stripped>);
+LL |
LL ~ <stripped>.to_string();
LL |
LL ~ str::to_string(<stripped>);
@@ -42,13 +45,13 @@ LL ~ <stripped>.to_string();
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:24:24
+ --> $DIR/manual_strip.rs:26:24
|
LL | str::to_string(&s[1..]);
| ^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:23:5
+ --> $DIR/manual_strip.rs:25:5
|
LL | if s.starts_with('a') {
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -56,17 +59,18 @@ help: try using the `strip_prefix` method
|
LL ~ if let Some(<stripped>) = s.strip_prefix('a') {
LL ~ str::to_string(<stripped>);
+LL |
LL ~ <stripped>.to_string();
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:31:24
+ --> $DIR/manual_strip.rs:34:24
|
LL | str::to_string(&s[prefix.len()..]);
| ^^^^^^^^^^^^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:30:5
+ --> $DIR/manual_strip.rs:33:5
|
LL | if s.starts_with(prefix) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -77,13 +81,13 @@ LL ~ str::to_string(<stripped>);
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:37:24
+ --> $DIR/manual_strip.rs:41:24
|
LL | str::to_string(&s[PREFIX.len()..]);
| ^^^^^^^^^^^^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:36:5
+ --> $DIR/manual_strip.rs:40:5
|
LL | if s.starts_with(PREFIX) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -91,17 +95,18 @@ help: try using the `strip_prefix` method
|
LL ~ if let Some(<stripped>) = s.strip_prefix(PREFIX) {
LL ~ str::to_string(<stripped>);
+LL |
LL ~ str::to_string(<stripped>);
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:44:24
+ --> $DIR/manual_strip.rs:49:24
|
LL | str::to_string(&TARGET[prefix.len()..]);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:43:5
+ --> $DIR/manual_strip.rs:48:5
|
LL | if TARGET.starts_with(prefix) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,13 +117,13 @@ LL ~ str::to_string(<stripped>);
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:50:9
+ --> $DIR/manual_strip.rs:56:9
|
LL | s1[2..].to_uppercase();
| ^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:49:5
+ --> $DIR/manual_strip.rs:55:5
|
LL | if s1.starts_with("ab") {
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,13 +134,13 @@ LL ~ <stripped>.to_uppercase();
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:80:9
+ --> $DIR/manual_strip.rs:87:9
|
LL | s[1..].to_string();
| ^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:79:5
+ --> $DIR/manual_strip.rs:86:5
|
LL | if s.starts_with('a') {
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/manual_try_fold.rs b/src/tools/clippy/tests/ui/manual_try_fold.rs
index 05c658579..bddf03ac3 100644
--- a/src/tools/clippy/tests/ui/manual_try_fold.rs
+++ b/src/tools/clippy/tests/ui/manual_try_fold.rs
@@ -1,8 +1,8 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::unnecessary_fold, unused)]
#![warn(clippy::manual_try_fold)]
#![feature(try_trait_v2)]
-
+//@no-rustfix
use std::ops::{ControlFlow, FromResidual, Try};
#[macro_use]
diff --git a/src/tools/clippy/tests/ui/manual_try_fold.stderr b/src/tools/clippy/tests/ui/manual_try_fold.stderr
index f1bb97c6d..4eb3e302b 100644
--- a/src/tools/clippy/tests/ui/manual_try_fold.stderr
+++ b/src/tools/clippy/tests/ui/manual_try_fold.stderr
@@ -5,6 +5,7 @@ LL | .fold(Some(0i32), |sum, i| sum?.checked_add(*i))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)`
|
= note: `-D clippy::manual-try-fold` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_try_fold)]`
error: usage of `Iterator::fold` on a type that implements `Try`
--> $DIR/manual_try_fold.rs:63:10
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
index 20560b87c..737d4c90d 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![allow(unused_variables, clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.rs b/src/tools/clippy/tests/ui/manual_unwrap_or.rs
index 5dbc57565..f59fb8752 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.rs
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![allow(unused_variables, clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.stderr b/src/tools/clippy/tests/ui/manual_unwrap_or.stderr
index 0e4cb798d..3a0759dcc 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.stderr
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.stderr
@@ -1,5 +1,5 @@
error: this pattern reimplements `Option::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:7:5
+ --> $DIR/manual_unwrap_or.rs:6:5
|
LL | / match Some(1) {
LL | | Some(i) => i,
@@ -8,9 +8,10 @@ LL | | };
| |_____^ help: replace with: `Some(1).unwrap_or(42)`
|
= note: `-D clippy::manual-unwrap-or` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or)]`
error: this pattern reimplements `Option::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:13:5
+ --> $DIR/manual_unwrap_or.rs:12:5
|
LL | / match Some(1) {
LL | | None => 42,
@@ -19,7 +20,7 @@ LL | | };
| |_____^ help: replace with: `Some(1).unwrap_or(42)`
error: this pattern reimplements `Option::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:19:5
+ --> $DIR/manual_unwrap_or.rs:18:5
|
LL | / match Some(1) {
LL | | Some(i) => i,
@@ -28,7 +29,7 @@ LL | | };
| |_____^ help: replace with: `Some(1).unwrap_or(1 + 42)`
error: this pattern reimplements `Option::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:26:5
+ --> $DIR/manual_unwrap_or.rs:25:5
|
LL | / match Some(1) {
LL | | Some(i) => i,
@@ -49,7 +50,7 @@ LL ~ });
|
error: this pattern reimplements `Option::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:36:5
+ --> $DIR/manual_unwrap_or.rs:35:5
|
LL | / match Some("Bob") {
LL | | Some(i) => i,
@@ -58,7 +59,7 @@ LL | | };
| |_____^ help: replace with: `Some("Bob").unwrap_or("Alice")`
error: this pattern reimplements `Result::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:86:5
+ --> $DIR/manual_unwrap_or.rs:85:5
|
LL | / match Ok::<i32, &str>(1) {
LL | | Ok(i) => i,
@@ -67,7 +68,7 @@ LL | | };
| |_____^ help: replace with: `Ok::<i32, &str>(1).unwrap_or(42)`
error: this pattern reimplements `Result::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:93:5
+ --> $DIR/manual_unwrap_or.rs:92:5
|
LL | / match a {
LL | | Ok(i) => i,
@@ -76,7 +77,7 @@ LL | | };
| |_____^ help: replace with: `a.unwrap_or(42)`
error: this pattern reimplements `Result::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:99:5
+ --> $DIR/manual_unwrap_or.rs:98:5
|
LL | / match Ok(1) as Result<i32, &str> {
LL | | Ok(i) => i,
@@ -85,7 +86,7 @@ LL | | };
| |_____^ help: replace with: `(Ok(1) as Result<i32, &str>).unwrap_or(42)`
error: this pattern reimplements `Option::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:112:5
+ --> $DIR/manual_unwrap_or.rs:111:5
|
LL | / match s.method() {
LL | | Some(i) => i,
@@ -94,7 +95,7 @@ LL | | };
| |_____^ help: replace with: `s.method().unwrap_or(42)`
error: this pattern reimplements `Result::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:118:5
+ --> $DIR/manual_unwrap_or.rs:117:5
|
LL | / match Ok::<i32, &str>(1) {
LL | | Err(_) => 42,
@@ -103,7 +104,7 @@ LL | | };
| |_____^ help: replace with: `Ok::<i32, &str>(1).unwrap_or(42)`
error: this pattern reimplements `Result::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:124:5
+ --> $DIR/manual_unwrap_or.rs:123:5
|
LL | / match Ok::<i32, &str>(1) {
LL | | Ok(i) => i,
@@ -112,7 +113,7 @@ LL | | };
| |_____^ help: replace with: `Ok::<i32, &str>(1).unwrap_or(1 + 42)`
error: this pattern reimplements `Result::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:131:5
+ --> $DIR/manual_unwrap_or.rs:130:5
|
LL | / match Ok::<i32, &str>(1) {
LL | | Ok(i) => i,
@@ -133,7 +134,7 @@ LL ~ });
|
error: this pattern reimplements `Result::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:141:5
+ --> $DIR/manual_unwrap_or.rs:140:5
|
LL | / match Ok::<&str, &str>("Bob") {
LL | | Ok(i) => i,
@@ -142,7 +143,7 @@ LL | | };
| |_____^ help: replace with: `Ok::<&str, &str>("Bob").unwrap_or("Alice")`
error: this pattern reimplements `Option::unwrap_or`
- --> $DIR/manual_unwrap_or.rs:201:17
+ --> $DIR/manual_unwrap_or.rs:200:17
|
LL | let _ = match some_macro!() {
| _________________^
diff --git a/src/tools/clippy/tests/ui/manual_while_let_some.fixed b/src/tools/clippy/tests/ui/manual_while_let_some.fixed
index 8b6109195..c70d258df 100644
--- a/src/tools/clippy/tests/ui/manual_while_let_some.fixed
+++ b/src/tools/clippy/tests/ui/manual_while_let_some.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_while_let_some)]
diff --git a/src/tools/clippy/tests/ui/manual_while_let_some.rs b/src/tools/clippy/tests/ui/manual_while_let_some.rs
index 85a0a084a..415bb5798 100644
--- a/src/tools/clippy/tests/ui/manual_while_let_some.rs
+++ b/src/tools/clippy/tests/ui/manual_while_let_some.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::manual_while_let_some)]
diff --git a/src/tools/clippy/tests/ui/manual_while_let_some.stderr b/src/tools/clippy/tests/ui/manual_while_let_some.stderr
index 633fe05c4..37387c8c3 100644
--- a/src/tools/clippy/tests/ui/manual_while_let_some.stderr
+++ b/src/tools/clippy/tests/ui/manual_while_let_some.stderr
@@ -1,10 +1,11 @@
error: you seem to be trying to pop elements from a `Vec` in a loop
- --> $DIR/manual_while_let_some.rs:23:9
+ --> $DIR/manual_while_let_some.rs:21:9
|
LL | let number = numbers.pop().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::manual-while-let-some` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_while_let_some)]`
help: consider using a `while..let` loop
|
LL ~ while let Some(number) = numbers.pop() {
@@ -12,7 +13,7 @@ LL ~
|
error: you seem to be trying to pop elements from a `Vec` in a loop
- --> $DIR/manual_while_let_some.rs:31:9
+ --> $DIR/manual_while_let_some.rs:29:9
|
LL | let number = val.numbers.pop().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL ~
|
error: you seem to be trying to pop elements from a `Vec` in a loop
- --> $DIR/manual_while_let_some.rs:35:20
+ --> $DIR/manual_while_let_some.rs:33:20
|
LL | accept_i32(numbers.pop().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL ~ accept_i32(element);
|
error: you seem to be trying to pop elements from a `Vec` in a loop
- --> $DIR/manual_while_let_some.rs:39:20
+ --> $DIR/manual_while_let_some.rs:37:20
|
LL | accept_i32(numbers.pop().expect(""));
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL ~ accept_i32(element);
|
error: you seem to be trying to pop elements from a `Vec` in a loop
- --> $DIR/manual_while_let_some.rs:82:9
+ --> $DIR/manual_while_let_some.rs:80:9
|
LL | let (a, b) = numbers.pop().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL ~
|
error: you seem to be trying to pop elements from a `Vec` in a loop
- --> $DIR/manual_while_let_some.rs:86:26
+ --> $DIR/manual_while_let_some.rs:84:26
|
LL | accept_i32_tuple(numbers.pop().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL ~ accept_i32_tuple(element);
|
error: you seem to be trying to pop elements from a `Vec` in a loop
- --> $DIR/manual_while_let_some.rs:91:9
+ --> $DIR/manual_while_let_some.rs:89:9
|
LL | let Foo { a, b } = results.pop().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/many_single_char_names.rs b/src/tools/clippy/tests/ui/many_single_char_names.rs
index 88fcce668..68578340d 100644
--- a/src/tools/clippy/tests/ui/many_single_char_names.rs
+++ b/src/tools/clippy/tests/ui/many_single_char_names.rs
@@ -3,6 +3,10 @@
fn bla() {
let a: i32;
+ //~^ ERROR: 5 bindings with single-character names in scope
+ //~| NOTE: `-D clippy::many-single-char-names` implied by `-D warnings`
+ //~| ERROR: 6 bindings with single-character names in scope
+ //~| ERROR: 5 bindings with single-character names in scope
let (b, c, d): (i32, i64, i16);
{
{
@@ -28,9 +32,11 @@ fn bla() {
}
fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
+//~^ ERROR: 8 bindings with single-character names in scope
fn bindings2() {
let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();
+ //~^ ERROR: 8 bindings with single-character names in scope
}
fn shadowing() {
diff --git a/src/tools/clippy/tests/ui/many_single_char_names.stderr b/src/tools/clippy/tests/ui/many_single_char_names.stderr
index ade0f84bc..688158cff 100644
--- a/src/tools/clippy/tests/ui/many_single_char_names.stderr
+++ b/src/tools/clippy/tests/ui/many_single_char_names.stderr
@@ -3,6 +3,7 @@ error: 5 bindings with single-character names in scope
|
LL | let a: i32;
| ^
+...
LL | let (b, c, d): (i32, i64, i16);
| ^ ^ ^
...
@@ -10,12 +11,14 @@ LL | let e: i32;
| ^
|
= note: `-D clippy::many-single-char-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::many_single_char_names)]`
error: 6 bindings with single-character names in scope
--> $DIR/many_single_char_names.rs:5:9
|
LL | let a: i32;
| ^
+...
LL | let (b, c, d): (i32, i64, i16);
| ^ ^ ^
...
@@ -29,6 +32,7 @@ error: 5 bindings with single-character names in scope
|
LL | let a: i32;
| ^
+...
LL | let (b, c, d): (i32, i64, i16);
| ^ ^ ^
...
@@ -36,13 +40,13 @@ LL | e => panic!(),
| ^
error: 8 bindings with single-character names in scope
- --> $DIR/many_single_char_names.rs:30:13
+ --> $DIR/many_single_char_names.rs:34:13
|
LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
| ^ ^ ^ ^ ^ ^ ^ ^
error: 8 bindings with single-character names in scope
- --> $DIR/many_single_char_names.rs:33:10
+ --> $DIR/many_single_char_names.rs:38:10
|
LL | let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();
| ^ ^ ^ ^ ^ ^ ^ ^
diff --git a/src/tools/clippy/tests/ui/map_clone.fixed b/src/tools/clippy/tests/ui/map_clone.fixed
index 50c0eb1a8..dd979013d 100644
--- a/src/tools/clippy/tests/ui/map_clone.fixed
+++ b/src/tools/clippy/tests/ui/map_clone.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::map_clone)]
#![allow(
clippy::clone_on_copy,
diff --git a/src/tools/clippy/tests/ui/map_clone.rs b/src/tools/clippy/tests/ui/map_clone.rs
index 91a084f28..96cba7196 100644
--- a/src/tools/clippy/tests/ui/map_clone.rs
+++ b/src/tools/clippy/tests/ui/map_clone.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::map_clone)]
#![allow(
clippy::clone_on_copy,
diff --git a/src/tools/clippy/tests/ui/map_clone.stderr b/src/tools/clippy/tests/ui/map_clone.stderr
index d768af1f4..eb11f0848 100644
--- a/src/tools/clippy/tests/ui/map_clone.stderr
+++ b/src/tools/clippy/tests/ui/map_clone.stderr
@@ -1,37 +1,38 @@
error: you are using an explicit closure for copying elements
- --> $DIR/map_clone.rs:12:22
+ --> $DIR/map_clone.rs:11:22
|
LL | let _: Vec<i8> = vec![5_i8; 6].iter().map(|x| *x).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![5_i8; 6].iter().copied()`
|
= note: `-D clippy::map-clone` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_clone)]`
error: you are using an explicit closure for cloning elements
- --> $DIR/map_clone.rs:13:26
+ --> $DIR/map_clone.rs:12:26
|
LL | let _: Vec<String> = vec![String::new()].iter().map(|x| x.clone()).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `vec![String::new()].iter().cloned()`
error: you are using an explicit closure for copying elements
- --> $DIR/map_clone.rs:14:23
+ --> $DIR/map_clone.rs:13:23
|
LL | let _: Vec<u32> = vec![42, 43].iter().map(|&x| x).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![42, 43].iter().copied()`
error: you are using an explicit closure for copying elements
- --> $DIR/map_clone.rs:16:26
+ --> $DIR/map_clone.rs:15:26
|
LL | let _: Option<u64> = Some(&16).map(|b| *b);
| ^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&16).copied()`
error: you are using an explicit closure for copying elements
- --> $DIR/map_clone.rs:17:25
+ --> $DIR/map_clone.rs:16:25
|
LL | let _: Option<u8> = Some(&1).map(|x| x.clone());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&1).copied()`
error: you are needlessly cloning iterator elements
- --> $DIR/map_clone.rs:28:29
+ --> $DIR/map_clone.rs:27:29
|
LL | let _ = std::env::args().map(|v| v.clone());
| ^^^^^^^^^^^^^^^^^^^ help: remove the `map` call
diff --git a/src/tools/clippy/tests/ui/map_collect_result_unit.fixed b/src/tools/clippy/tests/ui/map_collect_result_unit.fixed
index b00c2cf28..374af105f 100644
--- a/src/tools/clippy/tests/ui/map_collect_result_unit.fixed
+++ b/src/tools/clippy/tests/ui/map_collect_result_unit.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::map_collect_result_unit)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/map_collect_result_unit.rs b/src/tools/clippy/tests/ui/map_collect_result_unit.rs
index ad2198ec1..5c6fb23e2 100644
--- a/src/tools/clippy/tests/ui/map_collect_result_unit.rs
+++ b/src/tools/clippy/tests/ui/map_collect_result_unit.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::map_collect_result_unit)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/map_collect_result_unit.stderr b/src/tools/clippy/tests/ui/map_collect_result_unit.stderr
index 596e51e57..1a505d4ce 100644
--- a/src/tools/clippy/tests/ui/map_collect_result_unit.stderr
+++ b/src/tools/clippy/tests/ui/map_collect_result_unit.stderr
@@ -1,13 +1,14 @@
error: `.map().collect()` can be replaced with `.try_for_each()`
- --> $DIR/map_collect_result_unit.rs:6:17
+ --> $DIR/map_collect_result_unit.rs:5:17
|
LL | let _ = (0..3).map(|t| Err(t + 1)).collect::<Result<(), _>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0..3).try_for_each(|t| Err(t + 1))`
|
= note: `-D clippy::map-collect-result-unit` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_collect_result_unit)]`
error: `.map().collect()` can be replaced with `.try_for_each()`
- --> $DIR/map_collect_result_unit.rs:7:32
+ --> $DIR/map_collect_result_unit.rs:6:32
|
LL | let _: Result<(), _> = (0..3).map(|t| Err(t + 1)).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0..3).try_for_each(|t| Err(t + 1))`
diff --git a/src/tools/clippy/tests/ui/map_err.rs b/src/tools/clippy/tests/ui/map_err.rs
index bb35ab1a1..07c517844 100644
--- a/src/tools/clippy/tests/ui/map_err.rs
+++ b/src/tools/clippy/tests/ui/map_err.rs
@@ -20,6 +20,7 @@ fn main() -> Result<(), Errors> {
let x = u32::try_from(-123_i32);
println!("{:?}", x.map_err(|_| Errors::Ignored));
+ //~^ ERROR: `map_err(|_|...` wildcard pattern discards the original error
// Should not warn you because you explicitly ignore the parameter
// using a named wildcard value
diff --git a/src/tools/clippy/tests/ui/map_err.stderr b/src/tools/clippy/tests/ui/map_err.stderr
index d44403a84..6a845c84a 100644
--- a/src/tools/clippy/tests/ui/map_err.stderr
+++ b/src/tools/clippy/tests/ui/map_err.stderr
@@ -6,6 +6,7 @@ LL | println!("{:?}", x.map_err(|_| Errors::Ignored));
|
= help: consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)
= note: `-D clippy::map-err-ignore` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_err_ignore)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/map_flatten.rs b/src/tools/clippy/tests/ui/map_flatten.rs
index 7d47ee09d..76916d465 100644
--- a/src/tools/clippy/tests/ui/map_flatten.rs
+++ b/src/tools/clippy/tests/ui/map_flatten.rs
@@ -1,11 +1,13 @@
#![warn(clippy::map_flatten)]
#![feature(result_flattening)]
-
+//@no-rustfix
// issue #8506, multi-line
#[rustfmt::skip]
fn long_span() {
let _: Option<i32> = Some(1)
.map(|x| {
+ //~^ ERROR: called `map(..).flatten()` on `Option`
+ //~| NOTE: `-D clippy::map-flatten` implied by `-D warnings`
if x <= 5 {
Some(x)
} else {
@@ -16,6 +18,7 @@ fn long_span() {
let _: Result<i32, i32> = Ok(1)
.map(|x| {
+ //~^ ERROR: called `map(..).flatten()` on `Result`
if x == 1 {
Ok(x)
} else {
@@ -28,6 +31,7 @@ fn long_span() {
fn do_something() { }
let _: Result<i32, i32> = result
.map(|res| {
+ //~^ ERROR: called `map(..).flatten()` on `Result`
if res > 0 {
do_something();
Ok(res)
@@ -40,6 +44,7 @@ fn long_span() {
let _: Vec<_> = vec![5_i8; 6]
.into_iter()
.map(|some_value| {
+ //~^ ERROR: called `map(..).flatten()` on `Iterator`
if some_value > 3 {
Some(some_value)
} else {
diff --git a/src/tools/clippy/tests/ui/map_flatten.stderr b/src/tools/clippy/tests/ui/map_flatten.stderr
index 4b2630d68..a65d8f75d 100644
--- a/src/tools/clippy/tests/ui/map_flatten.stderr
+++ b/src/tools/clippy/tests/ui/map_flatten.stderr
@@ -3,18 +3,21 @@ error: called `map(..).flatten()` on `Option`
|
LL | .map(|x| {
| __________^
+LL | |
+LL | |
LL | | if x <= 5 {
-LL | | Some(x)
-LL | | } else {
... |
LL | | })
LL | | .flatten();
| |__________________^
|
= note: `-D clippy::map-flatten` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_flatten)]`
help: try replacing `map` with `and_then` and remove the `.flatten()`
|
LL ~ .and_then(|x| {
+LL +
+LL +
LL + if x <= 5 {
LL + Some(x)
LL + } else {
@@ -24,13 +27,13 @@ LL ~ });
|
error: called `map(..).flatten()` on `Result`
- --> $DIR/map_flatten.rs:18:10
+ --> $DIR/map_flatten.rs:20:10
|
LL | .map(|x| {
| __________^
+LL | |
LL | | if x == 1 {
LL | | Ok(x)
-LL | | } else {
... |
LL | | })
LL | | .flatten();
@@ -39,6 +42,7 @@ LL | | .flatten();
help: try replacing `map` with `and_then` and remove the `.flatten()`
|
LL ~ .and_then(|x| {
+LL +
LL + if x == 1 {
LL + Ok(x)
LL + } else {
@@ -48,13 +52,13 @@ LL ~ });
|
error: called `map(..).flatten()` on `Result`
- --> $DIR/map_flatten.rs:30:10
+ --> $DIR/map_flatten.rs:33:10
|
LL | .map(|res| {
| __________^
+LL | |
LL | | if res > 0 {
LL | | do_something();
-LL | | Ok(res)
... |
LL | | })
LL | | .flatten();
@@ -63,6 +67,7 @@ LL | | .flatten();
help: try replacing `map` with `and_then` and remove the `.flatten()`
|
LL ~ .and_then(|res| {
+LL +
LL + if res > 0 {
LL + do_something();
LL + Ok(res)
@@ -73,13 +78,13 @@ LL ~ });
|
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten.rs:42:10
+ --> $DIR/map_flatten.rs:46:10
|
LL | .map(|some_value| {
| __________^
+LL | |
LL | | if some_value > 3 {
LL | | Some(some_value)
-LL | | } else {
... |
LL | | })
LL | | .flatten()
@@ -88,6 +93,7 @@ LL | | .flatten()
help: try replacing `map` with `filter_map` and remove the `.flatten()`
|
LL ~ .filter_map(|some_value| {
+LL +
LL + if some_value > 3 {
LL + Some(some_value)
LL + } else {
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
index 14816de1a..1932f412d 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::let_underscore_untyped)]
#![allow(clippy::missing_docs_in_private_items)]
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.rs b/src/tools/clippy/tests/ui/map_flatten_fixable.rs
index f38a00a59..093fd9b6c 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.rs
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::let_underscore_untyped)]
#![allow(clippy::missing_docs_in_private_items)]
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
index c91f0b9ae..e5387eead 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
@@ -1,49 +1,50 @@
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:18:47
+ --> $DIR/map_flatten_fixable.rs:16:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id)`
|
= note: `-D clippy::map-flatten` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_flatten)]`
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:19:47
+ --> $DIR/map_flatten_fixable.rs:17:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_ref)`
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:20:47
+ --> $DIR/map_flatten_fixable.rs:18:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_closure)`
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:21:47
+ --> $DIR/map_flatten_fixable.rs:19:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(|x| x.checked_add(1))`
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:24:47
+ --> $DIR/map_flatten_fixable.rs:22:47
|
LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| 0..x)`
error: called `map(..).flatten()` on `Option`
- --> $DIR/map_flatten_fixable.rs:27:40
+ --> $DIR/map_flatten_fixable.rs:25:40
|
LL | let _: Option<_> = (Some(Some(1))).map(|x| x).flatten();
| ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`
error: called `map(..).flatten()` on `Result`
- --> $DIR/map_flatten_fixable.rs:30:42
+ --> $DIR/map_flatten_fixable.rs:28:42
|
LL | let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten();
| ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:39:10
+ --> $DIR/map_flatten_fixable.rs:37:10
|
LL | .map(|n| match n {
| __________^
@@ -72,7 +73,7 @@ LL ~ });
|
error: called `map(..).flatten()` on `Option`
- --> $DIR/map_flatten_fixable.rs:59:10
+ --> $DIR/map_flatten_fixable.rs:57:10
|
LL | .map(|_| {
| __________^
diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed
index 7fb7d8c12..cc40b1620 100644
--- a/src/tools/clippy/tests/ui/map_identity.fixed
+++ b/src/tools/clippy/tests/ui/map_identity.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::map_identity)]
#![allow(clippy::needless_return)]
diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs
index 7891c2426..97a91aea6 100644
--- a/src/tools/clippy/tests/ui/map_identity.rs
+++ b/src/tools/clippy/tests/ui/map_identity.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::map_identity)]
#![allow(clippy::needless_return)]
diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr
index b6a77281f..8942fd7c0 100644
--- a/src/tools/clippy/tests/ui/map_identity.stderr
+++ b/src/tools/clippy/tests/ui/map_identity.stderr
@@ -1,31 +1,32 @@
error: unnecessary map of the identity function
- --> $DIR/map_identity.rs:8:47
+ --> $DIR/map_identity.rs:7:47
|
LL | let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect();
| ^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
= note: `-D clippy::map-identity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_identity)]`
error: unnecessary map of the identity function
- --> $DIR/map_identity.rs:9:57
+ --> $DIR/map_identity.rs:8:57
|
LL | let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect();
| ^^^^^^^^^^^ help: remove the call to `map`
error: unnecessary map of the identity function
- --> $DIR/map_identity.rs:9:29
+ --> $DIR/map_identity.rs:8:29
|
LL | let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
error: unnecessary map of the identity function
- --> $DIR/map_identity.rs:10:32
+ --> $DIR/map_identity.rs:9:32
|
LL | let _: Option<u8> = Some(3).map(|x| x);
| ^^^^^^^^^^^ help: remove the call to `map`
error: unnecessary map of the identity function
- --> $DIR/map_identity.rs:11:36
+ --> $DIR/map_identity.rs:10:36
|
LL | let _: Result<i8, f32> = Ok(-3).map(|x| {
| ____________________________________^
@@ -34,7 +35,7 @@ LL | | });
| |______^ help: remove the call to `map`
error: unnecessary map of the identity function
- --> $DIR/map_identity.rs:21:36
+ --> $DIR/map_identity.rs:20:36
|
LL | let _: Result<u32, u32> = Ok(1).map_err(|a| a);
| ^^^^^^^^^^^^^^^ help: remove the call to `map_err`
diff --git a/src/tools/clippy/tests/ui/map_unwrap_or.rs b/src/tools/clippy/tests/ui/map_unwrap_or.rs
index bb36cb2c5..dfaa8f24f 100644
--- a/src/tools/clippy/tests/ui/map_unwrap_or.rs
+++ b/src/tools/clippy/tests/ui/map_unwrap_or.rs
@@ -1,5 +1,5 @@
//@aux-build:option_helpers.rs
-
+//@no-rustfix
#![warn(clippy::map_unwrap_or)]
#![allow(clippy::uninlined_format_args, clippy::unnecessary_lazy_evaluations)]
diff --git a/src/tools/clippy/tests/ui/map_unwrap_or.stderr b/src/tools/clippy/tests/ui/map_unwrap_or.stderr
index 5b3c61acf..7b7eeb322 100644
--- a/src/tools/clippy/tests/ui/map_unwrap_or.stderr
+++ b/src/tools/clippy/tests/ui/map_unwrap_or.stderr
@@ -8,6 +8,7 @@ LL | | .unwrap_or(0);
| |_____________________^
|
= note: `-D clippy::map-unwrap-or` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]`
help: use `map_or(<a>, <f>)` instead
|
LL - let _ = opt.map(|x| x + 1)
diff --git a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed
index ea5b6a669..90f3cf8ba 100644
--- a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed
+++ b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:option_helpers.rs
#![warn(clippy::map_unwrap_or)]
diff --git a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs
index f8bb9d8ca..d3d0ae015 100644
--- a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs
+++ b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:option_helpers.rs
#![warn(clippy::map_unwrap_or)]
diff --git a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr
index 71dc009f2..ca611ac9d 100644
--- a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr
+++ b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.stderr
@@ -1,5 +1,5 @@
error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value. This can be done more directly by calling `map_or_else(<g>, <f>)` instead
- --> $DIR/map_unwrap_or_fixable.rs:17:13
+ --> $DIR/map_unwrap_or_fixable.rs:16:13
|
LL | let _ = opt.map(|x| x + 1)
| _____________^
@@ -8,9 +8,10 @@ LL | | .unwrap_or_else(|| 0);
| |_____________________________^ help: try: `opt.map_or_else(|| 0, |x| x + 1)`
|
= note: `-D clippy::map-unwrap-or` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]`
error: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value. This can be done more directly by calling `.map_or_else(<g>, <f>)` instead
- --> $DIR/map_unwrap_or_fixable.rs:47:13
+ --> $DIR/map_unwrap_or_fixable.rs:46:13
|
LL | let _ = res.map(|x| x + 1)
| _____________^
diff --git a/src/tools/clippy/tests/ui/match_as_ref.fixed b/src/tools/clippy/tests/ui/match_as_ref.fixed
index 61d414bdf..8c07076af 100644
--- a/src/tools/clippy/tests/ui/match_as_ref.fixed
+++ b/src/tools/clippy/tests/ui/match_as_ref.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::match_as_ref)]
diff --git a/src/tools/clippy/tests/ui/match_as_ref.rs b/src/tools/clippy/tests/ui/match_as_ref.rs
index cd39514c5..655e16623 100644
--- a/src/tools/clippy/tests/ui/match_as_ref.rs
+++ b/src/tools/clippy/tests/ui/match_as_ref.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::match_as_ref)]
diff --git a/src/tools/clippy/tests/ui/match_as_ref.stderr b/src/tools/clippy/tests/ui/match_as_ref.stderr
index 2e6955eb8..cb0191370 100644
--- a/src/tools/clippy/tests/ui/match_as_ref.stderr
+++ b/src/tools/clippy/tests/ui/match_as_ref.stderr
@@ -1,5 +1,5 @@
error: use `as_ref()` instead
- --> $DIR/match_as_ref.rs:8:33
+ --> $DIR/match_as_ref.rs:6:33
|
LL | let borrowed: Option<&()> = match owned {
| _________________________________^
@@ -9,9 +9,10 @@ LL | | };
| |_____^ help: try: `owned.as_ref()`
|
= note: `-D clippy::match-as-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_as_ref)]`
error: use `as_mut()` instead
- --> $DIR/match_as_ref.rs:14:39
+ --> $DIR/match_as_ref.rs:12:39
|
LL | let borrow_mut: Option<&mut ()> = match mut_owned {
| _______________________________________^
@@ -21,7 +22,7 @@ LL | | };
| |_____^ help: try: `mut_owned.as_mut()`
error: use `as_ref()` instead
- --> $DIR/match_as_ref.rs:32:13
+ --> $DIR/match_as_ref.rs:30:13
|
LL | / match self.source {
LL | | Some(ref s) => Some(s),
diff --git a/src/tools/clippy/tests/ui/match_bool.rs b/src/tools/clippy/tests/ui/match_bool.rs
index bcc999a49..f84af393e 100644
--- a/src/tools/clippy/tests/ui/match_bool.rs
+++ b/src/tools/clippy/tests/ui/match_bool.rs
@@ -1,20 +1,24 @@
+//@no-rustfix: overlapping suggestions
#![deny(clippy::match_bool)]
fn match_bool() {
let test: bool = true;
match test {
+ //~^ ERROR: you seem to be trying to match on a boolean expression
true => 0,
false => 42,
};
let option = 1;
match option == 1 {
+ //~^ ERROR: you seem to be trying to match on a boolean expression
true => 1,
false => 0,
};
match test {
+ //~^ ERROR: you seem to be trying to match on a boolean expression
true => (),
false => {
println!("Noooo!");
@@ -22,6 +26,7 @@ fn match_bool() {
};
match test {
+ //~^ ERROR: you seem to be trying to match on a boolean expression
false => {
println!("Noooo!");
},
@@ -29,6 +34,11 @@ fn match_bool() {
};
match test && test {
+ //~^ ERROR: this boolean expression can be simplified
+ //~| NOTE: `-D clippy::nonminimal-bool` implied by `-D warnings`
+ //~| ERROR: you seem to be trying to match on a boolean expression
+ //~| ERROR: equal expressions as operands to `&&`
+ //~| NOTE: `#[deny(clippy::eq_op)]` on by default
false => {
println!("Noooo!");
},
@@ -36,6 +46,7 @@ fn match_bool() {
};
match test {
+ //~^ ERROR: you seem to be trying to match on a boolean expression
false => {
println!("Noooo!");
},
diff --git a/src/tools/clippy/tests/ui/match_bool.stderr b/src/tools/clippy/tests/ui/match_bool.stderr
index 3fd0468e5..369f4e1c6 100644
--- a/src/tools/clippy/tests/ui/match_bool.stderr
+++ b/src/tools/clippy/tests/ui/match_bool.stderr
@@ -1,39 +1,43 @@
error: this boolean expression can be simplified
- --> $DIR/match_bool.rs:31:11
+ --> $DIR/match_bool.rs:36:11
|
LL | match test && test {
| ^^^^^^^^^^^^ help: try: `test`
|
= note: `-D clippy::nonminimal-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
error: you seem to be trying to match on a boolean expression
- --> $DIR/match_bool.rs:6:5
+ --> $DIR/match_bool.rs:7:5
|
LL | / match test {
+LL | |
LL | | true => 0,
LL | | false => 42,
LL | | };
| |_____^ help: consider using an `if`/`else` expression: `if test { 0 } else { 42 }`
|
note: the lint level is defined here
- --> $DIR/match_bool.rs:1:9
+ --> $DIR/match_bool.rs:2:9
|
LL | #![deny(clippy::match_bool)]
| ^^^^^^^^^^^^^^^^^^
error: you seem to be trying to match on a boolean expression
- --> $DIR/match_bool.rs:12:5
+ --> $DIR/match_bool.rs:14:5
|
LL | / match option == 1 {
+LL | |
LL | | true => 1,
LL | | false => 0,
LL | | };
| |_____^ help: consider using an `if`/`else` expression: `if option == 1 { 1 } else { 0 }`
error: you seem to be trying to match on a boolean expression
- --> $DIR/match_bool.rs:17:5
+ --> $DIR/match_bool.rs:20:5
|
LL | / match test {
+LL | |
LL | | true => (),
LL | | false => {
LL | | println!("Noooo!");
@@ -49,9 +53,10 @@ LL ~ };
|
error: you seem to be trying to match on a boolean expression
- --> $DIR/match_bool.rs:24:5
+ --> $DIR/match_bool.rs:28:5
|
LL | / match test {
+LL | |
LL | | false => {
LL | | println!("Noooo!");
LL | | },
@@ -67,12 +72,13 @@ LL ~ };
|
error: you seem to be trying to match on a boolean expression
- --> $DIR/match_bool.rs:31:5
+ --> $DIR/match_bool.rs:36:5
|
LL | / match test && test {
-LL | | false => {
-LL | | println!("Noooo!");
-LL | | },
+LL | |
+LL | |
+LL | |
+... |
LL | | _ => (),
LL | | };
| |_____^
@@ -85,7 +91,7 @@ LL ~ };
|
error: equal expressions as operands to `&&`
- --> $DIR/match_bool.rs:31:11
+ --> $DIR/match_bool.rs:36:11
|
LL | match test && test {
| ^^^^^^^^^^^^
@@ -93,12 +99,12 @@ LL | match test && test {
= note: `#[deny(clippy::eq_op)]` on by default
error: you seem to be trying to match on a boolean expression
- --> $DIR/match_bool.rs:38:5
+ --> $DIR/match_bool.rs:48:5
|
LL | / match test {
+LL | |
LL | | false => {
LL | | println!("Noooo!");
-LL | | },
... |
LL | | },
LL | | };
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
index f19149cf9..05edc024b 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::match_like_matches_macro)]
#![allow(
unreachable_patterns,
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
index 8f4e58981..d6a0313cd 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::match_like_matches_macro)]
#![allow(
unreachable_patterns,
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr
index b57b26284..c70252378 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr
@@ -1,5 +1,5 @@
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:16:14
+ --> $DIR/match_expr_like_matches_macro.rs:14:14
|
LL | let _y = match x {
| ______________^
@@ -9,9 +9,10 @@ LL | | };
| |_____^ help: try: `matches!(x, Some(0))`
|
= note: `-D clippy::match-like-matches-macro` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_like_matches_macro)]`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/match_expr_like_matches_macro.rs:22:14
+ --> $DIR/match_expr_like_matches_macro.rs:20:14
|
LL | let _w = match x {
| ______________^
@@ -21,9 +22,10 @@ LL | | };
| |_____^ help: try: `x.is_some()`
|
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/match_expr_like_matches_macro.rs:28:14
+ --> $DIR/match_expr_like_matches_macro.rs:26:14
|
LL | let _z = match x {
| ______________^
@@ -33,7 +35,7 @@ LL | | };
| |_____^ help: try: `x.is_none()`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:34:15
+ --> $DIR/match_expr_like_matches_macro.rs:32:15
|
LL | let _zz = match x {
| _______________^
@@ -43,13 +45,13 @@ LL | | };
| |_____^ help: try: `!matches!(x, Some(r) if r == 0)`
error: if let .. else expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:40:16
+ --> $DIR/match_expr_like_matches_macro.rs:38:16
|
LL | let _zzz = if let Some(5) = x { true } else { false };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(x, Some(5))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:64:20
+ --> $DIR/match_expr_like_matches_macro.rs:62:20
|
LL | let _ans = match x {
| ____________________^
@@ -60,7 +62,7 @@ LL | | };
| |_________^ help: try: `matches!(x, E::A(_) | E::B(_))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:74:20
+ --> $DIR/match_expr_like_matches_macro.rs:72:20
|
LL | let _ans = match x {
| ____________________^
@@ -73,7 +75,7 @@ LL | | };
| |_________^ help: try: `matches!(x, E::A(_) | E::B(_))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:84:20
+ --> $DIR/match_expr_like_matches_macro.rs:82:20
|
LL | let _ans = match x {
| ____________________^
@@ -84,7 +86,7 @@ LL | | };
| |_________^ help: try: `!matches!(x, E::B(_) | E::C)`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:144:18
+ --> $DIR/match_expr_like_matches_macro.rs:142:18
|
LL | let _z = match &z {
| __________________^
@@ -94,7 +96,7 @@ LL | | };
| |_________^ help: try: `matches!(z, Some(3))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:153:18
+ --> $DIR/match_expr_like_matches_macro.rs:151:18
|
LL | let _z = match &z {
| __________________^
@@ -104,7 +106,7 @@ LL | | };
| |_________^ help: try: `matches!(&z, Some(3))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:170:21
+ --> $DIR/match_expr_like_matches_macro.rs:168:21
|
LL | let _ = match &z {
| _____________________^
@@ -114,7 +116,7 @@ LL | | };
| |_____________^ help: try: `matches!(&z, AnEnum::X)`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:184:20
+ --> $DIR/match_expr_like_matches_macro.rs:182:20
|
LL | let _res = match &val {
| ____________________^
@@ -124,7 +126,7 @@ LL | | };
| |_________^ help: try: `matches!(&val, &Some(ref _a))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:196:20
+ --> $DIR/match_expr_like_matches_macro.rs:194:20
|
LL | let _res = match &val {
| ____________________^
@@ -134,7 +136,7 @@ LL | | };
| |_________^ help: try: `matches!(&val, &Some(ref _a))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:254:14
+ --> $DIR/match_expr_like_matches_macro.rs:252:14
|
LL | let _y = match Some(5) {
| ______________^
diff --git a/src/tools/clippy/tests/ui/match_on_vec_items.rs b/src/tools/clippy/tests/ui/match_on_vec_items.rs
index cf9c279cd..f7b8500fa 100644
--- a/src/tools/clippy/tests/ui/match_on_vec_items.rs
+++ b/src/tools/clippy/tests/ui/match_on_vec_items.rs
@@ -1,6 +1,6 @@
#![warn(clippy::match_on_vec_items)]
#![allow(clippy::redundant_at_rest_pattern, clippy::useless_vec)]
-
+//@no-rustfix
fn match_with_wildcard() {
let arr = vec![0, 1, 2, 3];
let range = 1..3;
@@ -8,6 +8,8 @@ fn match_with_wildcard() {
// Lint, may panic
match arr[idx] {
+ //~^ ERROR: indexing into a vector may panic
+ //~| NOTE: `-D clippy::match-on-vec-items` implied by `-D warnings`
0 => println!("0"),
1 => println!("1"),
_ => {},
@@ -15,6 +17,7 @@ fn match_with_wildcard() {
// Lint, may panic
match arr[range] {
+ //~^ ERROR: indexing into a vector may panic
[0, 1] => println!("0 1"),
[1, 2] => println!("1 2"),
_ => {},
@@ -28,6 +31,7 @@ fn match_without_wildcard() {
// Lint, may panic
match arr[idx] {
+ //~^ ERROR: indexing into a vector may panic
0 => println!("0"),
1 => println!("1"),
num => {},
@@ -35,6 +39,7 @@ fn match_without_wildcard() {
// Lint, may panic
match arr[range] {
+ //~^ ERROR: indexing into a vector may panic
[0, 1] => println!("0 1"),
[1, 2] => println!("1 2"),
[ref sub @ ..] => {},
@@ -48,6 +53,7 @@ fn match_wildcard_and_action() {
// Lint, may panic
match arr[idx] {
+ //~^ ERROR: indexing into a vector may panic
0 => println!("0"),
1 => println!("1"),
_ => println!("Hello, World!"),
@@ -55,6 +61,7 @@ fn match_wildcard_and_action() {
// Lint, may panic
match arr[range] {
+ //~^ ERROR: indexing into a vector may panic
[0, 1] => println!("0 1"),
[1, 2] => println!("1 2"),
_ => println!("Hello, World!"),
@@ -68,6 +75,7 @@ fn match_vec_ref() {
// Lint, may panic
match arr[idx] {
+ //~^ ERROR: indexing into a vector may panic
0 => println!("0"),
1 => println!("1"),
_ => {},
@@ -75,6 +83,7 @@ fn match_vec_ref() {
// Lint, may panic
match arr[range] {
+ //~^ ERROR: indexing into a vector may panic
[0, 1] => println!("0 1"),
[1, 2] => println!("1 2"),
_ => {},
diff --git a/src/tools/clippy/tests/ui/match_on_vec_items.stderr b/src/tools/clippy/tests/ui/match_on_vec_items.stderr
index fc4a3ce19..140a458cb 100644
--- a/src/tools/clippy/tests/ui/match_on_vec_items.stderr
+++ b/src/tools/clippy/tests/ui/match_on_vec_items.stderr
@@ -5,45 +5,46 @@ LL | match arr[idx] {
| ^^^^^^^^ help: try: `arr.get(idx)`
|
= note: `-D clippy::match-on-vec-items` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_on_vec_items)]`
error: indexing into a vector may panic
- --> $DIR/match_on_vec_items.rs:17:11
+ --> $DIR/match_on_vec_items.rs:19:11
|
LL | match arr[range] {
| ^^^^^^^^^^ help: try: `arr.get(range)`
error: indexing into a vector may panic
- --> $DIR/match_on_vec_items.rs:30:11
+ --> $DIR/match_on_vec_items.rs:33:11
|
LL | match arr[idx] {
| ^^^^^^^^ help: try: `arr.get(idx)`
error: indexing into a vector may panic
- --> $DIR/match_on_vec_items.rs:37:11
+ --> $DIR/match_on_vec_items.rs:41:11
|
LL | match arr[range] {
| ^^^^^^^^^^ help: try: `arr.get(range)`
error: indexing into a vector may panic
- --> $DIR/match_on_vec_items.rs:50:11
+ --> $DIR/match_on_vec_items.rs:55:11
|
LL | match arr[idx] {
| ^^^^^^^^ help: try: `arr.get(idx)`
error: indexing into a vector may panic
- --> $DIR/match_on_vec_items.rs:57:11
+ --> $DIR/match_on_vec_items.rs:63:11
|
LL | match arr[range] {
| ^^^^^^^^^^ help: try: `arr.get(range)`
error: indexing into a vector may panic
- --> $DIR/match_on_vec_items.rs:70:11
+ --> $DIR/match_on_vec_items.rs:77:11
|
LL | match arr[idx] {
| ^^^^^^^^ help: try: `arr.get(idx)`
error: indexing into a vector may panic
- --> $DIR/match_on_vec_items.rs:77:11
+ --> $DIR/match_on_vec_items.rs:85:11
|
LL | match arr[range] {
| ^^^^^^^^^^ help: try: `arr.get(range)`
diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.rs b/src/tools/clippy/tests/ui/match_overlapping_arm.rs
index b78c1fd06..c2c2f2839 100644
--- a/src/tools/clippy/tests/ui/match_overlapping_arm.rs
+++ b/src/tools/clippy/tests/ui/match_overlapping_arm.rs
@@ -10,12 +10,14 @@ fn overlapping() {
match 42 {
0..=10 => println!("0..=10"),
+ //~^ ERROR: some ranges overlap
0..=11 => println!("0..=11"),
_ => (),
}
match 42 {
0..=5 => println!("0..=5"),
+ //~^ ERROR: some ranges overlap
6..=7 => println!("6..=7"),
FOO..=11 => println!("FOO..=11"),
_ => (),
@@ -53,6 +55,7 @@ fn overlapping() {
match 42 {
0..11 => println!("0..11"),
+ //~^ ERROR: some ranges overlap
0..=11 => println!("0..=11"),
_ => (),
}
@@ -78,11 +81,13 @@ fn overlapping() {
match 42 {
5..14 => println!("5..14"),
0..=10 => println!("0..=10"),
+ //~^ ERROR: some ranges overlap
_ => (),
}
match 42 {
0..7 => println!("0..7"),
+ //~^ ERROR: some ranges overlap
0..=10 => println!("0..=10"),
_ => (),
}
@@ -95,6 +100,7 @@ fn overlapping() {
match 42 {
..=23 => println!("..=23"),
+ //~^ ERROR: some ranges overlap
..26 => println!("..26"),
_ => (),
}
@@ -104,6 +110,7 @@ fn overlapping() {
5..=10 => (),
0..=20 => (),
21..=30 => (),
+ //~^ ERROR: some ranges overlap
21..=40 => (),
_ => (),
}
@@ -118,6 +125,7 @@ fn overlapping() {
// Only warn about the first if there are multiple overlaps
match 42u128 {
0..=0x0000_0000_0000_00ff => (),
+ //~^ ERROR: some ranges overlap
0..=0x0000_0000_0000_ffff => (),
0..=0x0000_0000_ffff_ffff => (),
0..=0xffff_ffff_ffff_ffff => (),
diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
index b98d4799e..322c704f2 100644
--- a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
+++ b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
@@ -5,92 +5,93 @@ LL | 0..=10 => println!("0..=10"),
| ^^^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:13:9
+ --> $DIR/match_overlapping_arm.rs:14:9
|
LL | 0..=11 => println!("0..=11"),
| ^^^^^^
= note: `-D clippy::match-overlapping-arm` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_overlapping_arm)]`
error: some ranges overlap
- --> $DIR/match_overlapping_arm.rs:18:9
+ --> $DIR/match_overlapping_arm.rs:19:9
|
LL | 0..=5 => println!("0..=5"),
| ^^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:20:9
+ --> $DIR/match_overlapping_arm.rs:22:9
|
LL | FOO..=11 => println!("FOO..=11"),
| ^^^^^^^^
error: some ranges overlap
- --> $DIR/match_overlapping_arm.rs:55:9
+ --> $DIR/match_overlapping_arm.rs:57:9
|
LL | 0..11 => println!("0..11"),
| ^^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:56:9
+ --> $DIR/match_overlapping_arm.rs:59:9
|
LL | 0..=11 => println!("0..=11"),
| ^^^^^^
error: some ranges overlap
- --> $DIR/match_overlapping_arm.rs:80:9
+ --> $DIR/match_overlapping_arm.rs:83:9
|
LL | 0..=10 => println!("0..=10"),
| ^^^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:79:9
+ --> $DIR/match_overlapping_arm.rs:82:9
|
LL | 5..14 => println!("5..14"),
| ^^^^^
error: some ranges overlap
- --> $DIR/match_overlapping_arm.rs:85:9
+ --> $DIR/match_overlapping_arm.rs:89:9
|
LL | 0..7 => println!("0..7"),
| ^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:86:9
+ --> $DIR/match_overlapping_arm.rs:91:9
|
LL | 0..=10 => println!("0..=10"),
| ^^^^^^
error: some ranges overlap
- --> $DIR/match_overlapping_arm.rs:97:9
+ --> $DIR/match_overlapping_arm.rs:102:9
|
LL | ..=23 => println!("..=23"),
| ^^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:98:9
+ --> $DIR/match_overlapping_arm.rs:104:9
|
LL | ..26 => println!("..26"),
| ^^^^
error: some ranges overlap
- --> $DIR/match_overlapping_arm.rs:106:9
+ --> $DIR/match_overlapping_arm.rs:112:9
|
LL | 21..=30 => (),
| ^^^^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:107:9
+ --> $DIR/match_overlapping_arm.rs:114:9
|
LL | 21..=40 => (),
| ^^^^^^^
error: some ranges overlap
- --> $DIR/match_overlapping_arm.rs:120:9
+ --> $DIR/match_overlapping_arm.rs:127:9
|
LL | 0..=0x0000_0000_0000_00ff => (),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: overlaps with this
- --> $DIR/match_overlapping_arm.rs:121:9
+ --> $DIR/match_overlapping_arm.rs:129:9
|
LL | 0..=0x0000_0000_0000_ffff => (),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/match_ref_pats.fixed b/src/tools/clippy/tests/ui/match_ref_pats.fixed
index 50c3dcc1e..f8d47b0fd 100644
--- a/src/tools/clippy/tests/ui/match_ref_pats.fixed
+++ b/src/tools/clippy/tests/ui/match_ref_pats.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_ref_pats)]
#![allow(dead_code, unused_variables)]
#![allow(clippy::enum_variant_names, clippy::equatable_if_let, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/match_ref_pats.rs b/src/tools/clippy/tests/ui/match_ref_pats.rs
index d29ddacc0..bcd7bf7ab 100644
--- a/src/tools/clippy/tests/ui/match_ref_pats.rs
+++ b/src/tools/clippy/tests/ui/match_ref_pats.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_ref_pats)]
#![allow(dead_code, unused_variables)]
#![allow(clippy::enum_variant_names, clippy::equatable_if_let, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/match_ref_pats.stderr b/src/tools/clippy/tests/ui/match_ref_pats.stderr
index 1294e0fe5..e3bb2824a 100644
--- a/src/tools/clippy/tests/ui/match_ref_pats.stderr
+++ b/src/tools/clippy/tests/ui/match_ref_pats.stderr
@@ -1,5 +1,5 @@
error: you don't need to add `&` to all patterns
- --> $DIR/match_ref_pats.rs:9:9
+ --> $DIR/match_ref_pats.rs:8:9
|
LL | / match v {
LL | | &Some(v) => println!("{:?}", v),
@@ -8,6 +8,7 @@ LL | | }
| |_________^
|
= note: `-D clippy::match-ref-pats` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_ref_pats)]`
help: instead of prefixing all patterns with `&`, you can dereference the expression
|
LL ~ match *v {
@@ -16,7 +17,7 @@ LL ~ None => println!("none"),
|
error: you don't need to add `&` to both the expression and the patterns
- --> $DIR/match_ref_pats.rs:26:5
+ --> $DIR/match_ref_pats.rs:25:5
|
LL | / match &w {
LL | | &Some(v) => println!("{:?}", v),
@@ -32,21 +33,22 @@ LL ~ None => println!("none"),
|
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/match_ref_pats.rs:38:12
+ --> $DIR/match_ref_pats.rs:37:12
|
LL | if let &None = a {
| -------^^^^^---- help: try: `if a.is_none()`
|
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/match_ref_pats.rs:43:12
+ --> $DIR/match_ref_pats.rs:42:12
|
LL | if let &None = &b {
| -------^^^^^----- help: try: `if b.is_none()`
error: you don't need to add `&` to all patterns
- --> $DIR/match_ref_pats.rs:103:9
+ --> $DIR/match_ref_pats.rs:102:9
|
LL | / match foobar_variant!(0) {
LL | | &FooBar::Foo => println!("Foo"),
diff --git a/src/tools/clippy/tests/ui/match_result_ok.fixed b/src/tools/clippy/tests/ui/match_result_ok.fixed
index fe67b225f..8d7cddc0a 100644
--- a/src/tools/clippy/tests/ui/match_result_ok.fixed
+++ b/src/tools/clippy/tests/ui/match_result_ok.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_result_ok)]
#![allow(dead_code)]
#![allow(clippy::boxed_local, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/match_result_ok.rs b/src/tools/clippy/tests/ui/match_result_ok.rs
index eac382e1f..9a18b813a 100644
--- a/src/tools/clippy/tests/ui/match_result_ok.rs
+++ b/src/tools/clippy/tests/ui/match_result_ok.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_result_ok)]
#![allow(dead_code)]
#![allow(clippy::boxed_local, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/match_result_ok.stderr b/src/tools/clippy/tests/ui/match_result_ok.stderr
index cbdc56aa2..de0361bd6 100644
--- a/src/tools/clippy/tests/ui/match_result_ok.stderr
+++ b/src/tools/clippy/tests/ui/match_result_ok.stderr
@@ -1,17 +1,18 @@
error: matching on `Some` with `ok()` is redundant
- --> $DIR/match_result_ok.rs:9:5
+ --> $DIR/match_result_ok.rs:8:5
|
LL | if let Some(y) = x.parse().ok() { y } else { 0 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::match-result-ok` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_result_ok)]`
help: consider matching on `Ok(y)` and removing the call to `ok` instead
|
LL | if let Ok(y) = x.parse() { y } else { 0 }
| ~~~~~~~~~~~~~~~~~~~~~~~~
error: matching on `Some` with `ok()` is redundant
- --> $DIR/match_result_ok.rs:19:9
+ --> $DIR/match_result_ok.rs:18:9
|
LL | if let Some(y) = x . parse() . ok () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | if let Ok(y) = x . parse() {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: matching on `Some` with `ok()` is redundant
- --> $DIR/match_result_ok.rs:45:5
+ --> $DIR/match_result_ok.rs:44:5
|
LL | while let Some(a) = wat.next().ok() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/match_same_arms.rs b/src/tools/clippy/tests/ui/match_same_arms.rs
index fad6a7db9..2f4652dcf 100644
--- a/src/tools/clippy/tests/ui/match_same_arms.rs
+++ b/src/tools/clippy/tests/ui/match_same_arms.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::match_same_arms)]
pub enum Abc {
diff --git a/src/tools/clippy/tests/ui/match_same_arms.stderr b/src/tools/clippy/tests/ui/match_same_arms.stderr
index 88b9a20a3..824dcfdce 100644
--- a/src/tools/clippy/tests/ui/match_same_arms.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms.stderr
@@ -1,19 +1,20 @@
error: this match arm has an identical body to the `_` wildcard arm
- --> $DIR/match_same_arms.rs:11:9
+ --> $DIR/match_same_arms.rs:12:9
|
LL | Abc::A => 0,
| ^^^^^^^^^^^ help: try removing the arm
|
= help: or try changing either arm body
note: `_` wildcard arm here
- --> $DIR/match_same_arms.rs:13:9
+ --> $DIR/match_same_arms.rs:14:9
|
LL | _ => 0,
| ^^^^^^
= note: `-D clippy::match-same-arms` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
error: this match arm has an identical body to another arm
- --> $DIR/match_same_arms.rs:17:9
+ --> $DIR/match_same_arms.rs:18:9
|
LL | (1, .., 3) => 42,
| ----------^^^^^^
@@ -22,13 +23,13 @@ LL | (1, .., 3) => 42,
|
= help: or try changing either arm body
note: other arm here
- --> $DIR/match_same_arms.rs:18:9
+ --> $DIR/match_same_arms.rs:19:9
|
LL | (.., 3) => 42,
| ^^^^^^^^^^^^^
error: this match arm has an identical body to another arm
- --> $DIR/match_same_arms.rs:24:9
+ --> $DIR/match_same_arms.rs:25:9
|
LL | 51 => 1,
| --^^^^^
@@ -37,13 +38,13 @@ LL | 51 => 1,
|
= help: or try changing either arm body
note: other arm here
- --> $DIR/match_same_arms.rs:23:9
+ --> $DIR/match_same_arms.rs:24:9
|
LL | 42 => 1,
| ^^^^^^^
error: this match arm has an identical body to another arm
- --> $DIR/match_same_arms.rs:25:9
+ --> $DIR/match_same_arms.rs:26:9
|
LL | 41 => 2,
| --^^^^^
@@ -52,13 +53,13 @@ LL | 41 => 2,
|
= help: or try changing either arm body
note: other arm here
- --> $DIR/match_same_arms.rs:26:9
+ --> $DIR/match_same_arms.rs:27:9
|
LL | 52 => 2,
| ^^^^^^^
error: this match arm has an identical body to another arm
- --> $DIR/match_same_arms.rs:32:9
+ --> $DIR/match_same_arms.rs:33:9
|
LL | 2 => 2,
| -^^^^^
@@ -67,13 +68,13 @@ LL | 2 => 2,
|
= help: or try changing either arm body
note: other arm here
- --> $DIR/match_same_arms.rs:31:9
+ --> $DIR/match_same_arms.rs:32:9
|
LL | 1 => 2,
| ^^^^^^
error: this match arm has an identical body to another arm
- --> $DIR/match_same_arms.rs:34:9
+ --> $DIR/match_same_arms.rs:35:9
|
LL | 3 => 2,
| -^^^^^
@@ -82,13 +83,13 @@ LL | 3 => 2,
|
= help: or try changing either arm body
note: other arm here
- --> $DIR/match_same_arms.rs:31:9
+ --> $DIR/match_same_arms.rs:32:9
|
LL | 1 => 2,
| ^^^^^^
error: this match arm has an identical body to another arm
- --> $DIR/match_same_arms.rs:32:9
+ --> $DIR/match_same_arms.rs:33:9
|
LL | 2 => 2,
| -^^^^^
@@ -97,13 +98,13 @@ LL | 2 => 2,
|
= help: or try changing either arm body
note: other arm here
- --> $DIR/match_same_arms.rs:34:9
+ --> $DIR/match_same_arms.rs:35:9
|
LL | 3 => 2,
| ^^^^^^
error: this match arm has an identical body to another arm
- --> $DIR/match_same_arms.rs:51:17
+ --> $DIR/match_same_arms.rs:52:17
|
LL | CommandInfo::External { name, .. } => name.to_string(),
| ----------------------------------^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +113,7 @@ LL | CommandInfo::External { name, .. } => name.to_string(),
|
= help: or try changing either arm body
note: other arm here
- --> $DIR/match_same_arms.rs:50:17
+ --> $DIR/match_same_arms.rs:51:17
|
LL | CommandInfo::BuiltIn { name, .. } => name.to_string(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/match_same_arms2.rs b/src/tools/clippy/tests/ui/match_same_arms2.rs
index b1b9a6ae3..525a355f4 100644
--- a/src/tools/clippy/tests/ui/match_same_arms2.rs
+++ b/src/tools/clippy/tests/ui/match_same_arms2.rs
@@ -4,7 +4,7 @@
clippy::diverging_sub_expression,
clippy::uninlined_format_args
)]
-
+//@no-rustfix
fn bar<T>(_: T) {}
fn foo() -> bool {
unimplemented!()
diff --git a/src/tools/clippy/tests/ui/match_same_arms2.stderr b/src/tools/clippy/tests/ui/match_same_arms2.stderr
index a73481875..40b20c7e1 100644
--- a/src/tools/clippy/tests/ui/match_same_arms2.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms2.stderr
@@ -23,6 +23,7 @@ LL | | a
LL | | },
| |_________^
= note: `-D clippy::match-same-arms` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
error: this match arm has an identical body to another arm
--> $DIR/match_same_arms2.rs:38:9
@@ -147,6 +148,7 @@ LL | | };
| |_____^ help: try: `!matches!(x, E::A | E::B)`
|
= note: `-D clippy::match-like-matches-macro` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_like_matches_macro)]`
error: this match arm has an identical body to another arm
--> $DIR/match_same_arms2.rs:199:9
diff --git a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs
index 07421173a..1ee048bf7 100644
--- a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs
+++ b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.rs
@@ -1,7 +1,7 @@
#![feature(non_exhaustive_omitted_patterns_lint)]
#![warn(clippy::match_same_arms)]
#![no_main]
-
+//@no-rustfix
use std::sync::atomic::Ordering; // #[non_exhaustive] enum
pub fn f(x: Ordering) {
@@ -39,6 +39,7 @@ pub fn g(x: Ordering) {
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => panic!(),
+ //~^ ERROR: this match arm has an identical body to the `_` wildcard arm
_ => panic!(),
}
}
@@ -52,6 +53,7 @@ mod g {
Ordering::Release => println!("release"),
Ordering::Acquire => println!("acquire"),
Ordering::AcqRel | Ordering::SeqCst => panic!(),
+ //~^ ERROR: this match arm has an identical body to the `_` wildcard arm
_ => panic!(),
}
}
diff --git a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr
index 088f7d5c0..a03953633 100644
--- a/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms_non_exhaustive.stderr
@@ -6,21 +6,22 @@ LL | Ordering::AcqRel | Ordering::SeqCst => panic!(),
|
= help: or try changing either arm body
note: `_` wildcard arm here
- --> $DIR/match_same_arms_non_exhaustive.rs:42:9
+ --> $DIR/match_same_arms_non_exhaustive.rs:43:9
|
LL | _ => panic!(),
| ^^^^^^^^^^^^^
= note: `-D clippy::match-same-arms` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
error: this match arm has an identical body to the `_` wildcard arm
- --> $DIR/match_same_arms_non_exhaustive.rs:54:13
+ --> $DIR/match_same_arms_non_exhaustive.rs:55:13
|
LL | Ordering::AcqRel | Ordering::SeqCst => panic!(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try removing the arm
|
= help: or try changing either arm body
note: `_` wildcard arm here
- --> $DIR/match_same_arms_non_exhaustive.rs:55:13
+ --> $DIR/match_same_arms_non_exhaustive.rs:57:13
|
LL | _ => panic!(),
| ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/match_single_binding.fixed b/src/tools/clippy/tests/ui/match_single_binding.fixed
index f59ff456b..3a3eee4c9 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.fixed
+++ b/src/tools/clippy/tests/ui/match_single_binding.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_single_binding)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/match_single_binding.rs b/src/tools/clippy/tests/ui/match_single_binding.rs
index e293bc33c..ff2f842ac 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.rs
+++ b/src/tools/clippy/tests/ui/match_single_binding.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_single_binding)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/match_single_binding.stderr b/src/tools/clippy/tests/ui/match_single_binding.stderr
index 8998786de..81ec200df 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.stderr
+++ b/src/tools/clippy/tests/ui/match_single_binding.stderr
@@ -1,5 +1,5 @@
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:34:5
+ --> $DIR/match_single_binding.rs:33:5
|
LL | / match (a, b, c) {
LL | | (x, y, z) => {
@@ -9,6 +9,7 @@ LL | | }
| |_____^
|
= note: `-D clippy::match-single-binding` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_single_binding)]`
help: consider using a `let` statement
|
LL ~ let (x, y, z) = (a, b, c);
@@ -18,7 +19,7 @@ LL + }
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:40:5
+ --> $DIR/match_single_binding.rs:39:5
|
LL | / match (a, b, c) {
LL | | (x, y, z) => println!("{} {} {}", x, y, z),
@@ -32,7 +33,7 @@ LL + println!("{} {} {}", x, y, z);
|
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:57:5
+ --> $DIR/match_single_binding.rs:56:5
|
LL | / match a {
LL | | _ => println!("whatever"),
@@ -40,7 +41,7 @@ LL | | }
| |_____^ help: consider using the match body instead: `println!("whatever");`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:61:5
+ --> $DIR/match_single_binding.rs:60:5
|
LL | / match a {
LL | | _ => {
@@ -59,7 +60,7 @@ LL + }
|
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:68:5
+ --> $DIR/match_single_binding.rs:67:5
|
LL | / match a {
LL | | _ => {
@@ -81,7 +82,7 @@ LL + }
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:78:5
+ --> $DIR/match_single_binding.rs:77:5
|
LL | / match p {
LL | | Point { x, y } => println!("Coords: ({}, {})", x, y),
@@ -95,7 +96,7 @@ LL + println!("Coords: ({}, {})", x, y);
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:82:5
+ --> $DIR/match_single_binding.rs:81:5
|
LL | / match p {
LL | | Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1),
@@ -109,7 +110,7 @@ LL + println!("Coords: ({}, {})", x1, y1);
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:87:5
+ --> $DIR/match_single_binding.rs:86:5
|
LL | / match x {
LL | | ref r => println!("Got a reference to {}", r),
@@ -123,7 +124,7 @@ LL + println!("Got a reference to {}", r);
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:92:5
+ --> $DIR/match_single_binding.rs:91:5
|
LL | / match x {
LL | | ref mut mr => println!("Got a mutable reference to {}", mr),
@@ -137,7 +138,7 @@ LL + println!("Got a mutable reference to {}", mr);
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:96:5
+ --> $DIR/match_single_binding.rs:95:5
|
LL | / let product = match coords() {
LL | | Point { x, y } => x * y,
@@ -151,7 +152,7 @@ LL + let product = x * y;
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:104:18
+ --> $DIR/match_single_binding.rs:103:18
|
LL | .map(|i| match i.unwrap() {
| __________________^
@@ -168,7 +169,7 @@ LL ~ })
|
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:130:5
+ --> $DIR/match_single_binding.rs:129:5
|
LL | / match x {
LL | | // =>
@@ -177,7 +178,7 @@ LL | | }
| |_____^ help: consider using the match body instead: `println!("Not an array index start")`
error: this assignment could be simplified
- --> $DIR/match_single_binding.rs:139:5
+ --> $DIR/match_single_binding.rs:138:5
|
LL | / val = match val.split_at(idx) {
LL | | (pre, suf) => {
@@ -197,7 +198,7 @@ LL ~ };
|
error: this match could be replaced by its scrutinee and body
- --> $DIR/match_single_binding.rs:152:16
+ --> $DIR/match_single_binding.rs:151:16
|
LL | let _ = || match side_effects() {
| ________________^
@@ -214,7 +215,7 @@ LL ~ };
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding.rs:158:5
+ --> $DIR/match_single_binding.rs:157:5
|
LL | / match r {
LL | | x => match x {
@@ -239,7 +240,7 @@ LL ~ };
|
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:171:5
+ --> $DIR/match_single_binding.rs:170:5
|
LL | / match 1 {
LL | | _ => (),
@@ -247,7 +248,7 @@ LL | | }
| |_____^ help: consider using the match body instead: `();`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:175:13
+ --> $DIR/match_single_binding.rs:174:13
|
LL | let a = match 1 {
| _____________^
@@ -256,7 +257,7 @@ LL | | };
| |_____^ help: consider using the match body instead: `()`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:179:5
+ --> $DIR/match_single_binding.rs:178:5
|
LL | / match 1 {
LL | | _ => side_effects(),
@@ -264,7 +265,7 @@ LL | | }
| |_____^ help: consider using the match body instead: `side_effects();`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:183:13
+ --> $DIR/match_single_binding.rs:182:13
|
LL | let b = match 1 {
| _____________^
@@ -273,7 +274,7 @@ LL | | };
| |_____^ help: consider using the match body instead: `side_effects()`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:187:5
+ --> $DIR/match_single_binding.rs:186:5
|
LL | / match 1 {
LL | | _ => println!("1"),
@@ -281,7 +282,7 @@ LL | | }
| |_____^ help: consider using the match body instead: `println!("1");`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:191:13
+ --> $DIR/match_single_binding.rs:190:13
|
LL | let c = match 1 {
| _____________^
@@ -290,7 +291,7 @@ LL | | };
| |_____^ help: consider using the match body instead: `println!("1")`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:196:9
+ --> $DIR/match_single_binding.rs:195:9
|
LL | / match 1 {
LL | | _ => (),
@@ -298,7 +299,7 @@ LL | | },
| |_________^ help: consider using the match body instead: `()`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:199:9
+ --> $DIR/match_single_binding.rs:198:9
|
LL | / match 1 {
LL | | _ => side_effects(),
@@ -306,7 +307,7 @@ LL | | },
| |_________^ help: consider using the match body instead: `side_effects()`
error: this match could be replaced by its body itself
- --> $DIR/match_single_binding.rs:202:9
+ --> $DIR/match_single_binding.rs:201:9
|
LL | / match 1 {
LL | | _ => println!("1"),
diff --git a/src/tools/clippy/tests/ui/match_single_binding2.fixed b/src/tools/clippy/tests/ui/match_single_binding2.fixed
index adfb4ba91..5673aa78c 100644
--- a/src/tools/clippy/tests/ui/match_single_binding2.fixed
+++ b/src/tools/clippy/tests/ui/match_single_binding2.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_single_binding)]
#![allow(unused_variables)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/match_single_binding2.rs b/src/tools/clippy/tests/ui/match_single_binding2.rs
index b5cfe3654..575e7f581 100644
--- a/src/tools/clippy/tests/ui/match_single_binding2.rs
+++ b/src/tools/clippy/tests/ui/match_single_binding2.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_single_binding)]
#![allow(unused_variables)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/match_single_binding2.stderr b/src/tools/clippy/tests/ui/match_single_binding2.stderr
index e180b93e7..e7b9ef8a1 100644
--- a/src/tools/clippy/tests/ui/match_single_binding2.stderr
+++ b/src/tools/clippy/tests/ui/match_single_binding2.stderr
@@ -1,5 +1,5 @@
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding2.rs:18:36
+ --> $DIR/match_single_binding2.rs:17:36
|
LL | Some((iter, _item)) => match iter.size_hint() {
| ____________________________________^
@@ -8,6 +8,7 @@ LL | | },
| |_____________^
|
= note: `-D clippy::match-single-binding` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_single_binding)]`
help: consider using a `let` statement
|
LL ~ Some((iter, _item)) => {
@@ -17,7 +18,7 @@ LL ~ },
|
error: this match could be written as a `let` statement
- --> $DIR/match_single_binding2.rs:31:13
+ --> $DIR/match_single_binding2.rs:30:13
|
LL | / match get_tup() {
LL | | (a, b) => println!("a {:?} and b {:?}", a, b),
@@ -31,7 +32,7 @@ LL + println!("a {:?} and b {:?}", a, b)
|
error: this match could be replaced by its scrutinee and body
- --> $DIR/match_single_binding2.rs:42:5
+ --> $DIR/match_single_binding2.rs:41:5
|
LL | / match side_effects() {
LL | | _ => println!("Side effects"),
@@ -45,7 +46,7 @@ LL + println!("Side effects");
|
error: this match could be replaced by its scrutinee and body
- --> $DIR/match_single_binding2.rs:49:5
+ --> $DIR/match_single_binding2.rs:48:5
|
LL | / match match x {
LL | | 0 => 1,
diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed b/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed
index cd53b1f06..a608ab0c0 100644
--- a/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed
+++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_str_case_mismatch)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.rs b/src/tools/clippy/tests/ui/match_str_case_mismatch.rs
index 688530566..1e4269d1d 100644
--- a/src/tools/clippy/tests/ui/match_str_case_mismatch.rs
+++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::match_str_case_mismatch)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
index 197520a3d..f799a4698 100644
--- a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
+++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
@@ -1,17 +1,18 @@
error: this `match` arm has a differing case than its expression
- --> $DIR/match_str_case_mismatch.rs:113:9
+ --> $DIR/match_str_case_mismatch.rs:112:9
|
LL | "Bar" => {},
| ^^^^^
|
= note: `-D clippy::match-str-case-mismatch` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_str_case_mismatch)]`
help: consider changing the case of this arm to respect `to_ascii_lowercase`
|
LL | "bar" => {},
| ~~~~~
error: this `match` arm has a differing case than its expression
- --> $DIR/match_str_case_mismatch.rs:123:9
+ --> $DIR/match_str_case_mismatch.rs:122:9
|
LL | "~!@#$%^&*()-_=+Foo" => {},
| ^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | "~!@#$%^&*()-_=+foo" => {},
| ~~~~~~~~~~~~~~~~~~~~
error: this `match` arm has a differing case than its expression
- --> $DIR/match_str_case_mismatch.rs:135:9
+ --> $DIR/match_str_case_mismatch.rs:134:9
|
LL | "Воды" => {},
| ^^^^^^
@@ -33,7 +34,7 @@ LL | "воды" => {},
| ~~~~~~
error: this `match` arm has a differing case than its expression
- --> $DIR/match_str_case_mismatch.rs:146:9
+ --> $DIR/match_str_case_mismatch.rs:145:9
|
LL | "barDz" => {},
| ^^^^^^
@@ -44,7 +45,7 @@ LL | "bardz" => {},
| ~~~~~~
error: this `match` arm has a differing case than its expression
- --> $DIR/match_str_case_mismatch.rs:156:9
+ --> $DIR/match_str_case_mismatch.rs:155:9
|
LL | "bARʁ" => {},
| ^^^^^^
@@ -55,7 +56,7 @@ LL | "BARʁ" => {},
| ~~~~~~
error: this `match` arm has a differing case than its expression
- --> $DIR/match_str_case_mismatch.rs:166:9
+ --> $DIR/match_str_case_mismatch.rs:165:9
|
LL | "Bar" => {},
| ^^^^^
@@ -66,7 +67,7 @@ LL | "bar" => {},
| ~~~~~
error: this `match` arm has a differing case than its expression
- --> $DIR/match_str_case_mismatch.rs:181:9
+ --> $DIR/match_str_case_mismatch.rs:180:9
|
LL | "bAR" => {},
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.rs b/src/tools/clippy/tests/ui/match_wild_err_arm.rs
index 5a552e4ae..7bdd75d7f 100644
--- a/src/tools/clippy/tests/ui/match_wild_err_arm.rs
+++ b/src/tools/clippy/tests/ui/match_wild_err_arm.rs
@@ -22,18 +22,24 @@ fn match_wild_err_arm() {
Ok(3) => println!("ok"),
Ok(_) => println!("ok"),
Err(_) => panic!("err"),
+ //~^ ERROR: `Err(_)` matches all errors
+ //~| NOTE: match each error separately or use the error output, or use `.expect(ms
}
match x {
Ok(3) => println!("ok"),
Ok(_) => println!("ok"),
Err(_) => panic!(),
+ //~^ ERROR: `Err(_)` matches all errors
+ //~| NOTE: match each error separately or use the error output, or use `.expect(ms
}
match x {
Ok(3) => println!("ok"),
Ok(_) => println!("ok"),
Err(_) => {
+ //~^ ERROR: `Err(_)` matches all errors
+ //~| NOTE: match each error separately or use the error output, or use `.expect(ms
panic!();
},
}
@@ -42,6 +48,8 @@ fn match_wild_err_arm() {
Ok(3) => println!("ok"),
Ok(_) => println!("ok"),
Err(_e) => panic!(),
+ //~^ ERROR: `Err(_e)` matches all errors
+ //~| NOTE: match each error separately or use the error output, or use `.expect(ms
}
// Allowed when used in `panic!`.
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.stderr
index a9f54feac..c120aec5b 100644
--- a/src/tools/clippy/tests/ui/match_wild_err_arm.stderr
+++ b/src/tools/clippy/tests/ui/match_wild_err_arm.stderr
@@ -6,9 +6,10 @@ LL | Err(_) => panic!("err"),
|
= note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
= note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_wild_err_arm)]`
error: `Err(_)` matches all errors
- --> $DIR/match_wild_err_arm.rs:30:9
+ --> $DIR/match_wild_err_arm.rs:32:9
|
LL | Err(_) => panic!(),
| ^^^^^^
@@ -16,7 +17,7 @@ LL | Err(_) => panic!(),
= note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_)` matches all errors
- --> $DIR/match_wild_err_arm.rs:36:9
+ --> $DIR/match_wild_err_arm.rs:40:9
|
LL | Err(_) => {
| ^^^^^^
@@ -24,7 +25,7 @@ LL | Err(_) => {
= note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
error: `Err(_e)` matches all errors
- --> $DIR/match_wild_err_arm.rs:44:9
+ --> $DIR/match_wild_err_arm.rs:50:9
|
LL | Err(_e) => panic!(),
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed
index d2e6fef07..e5ea2fdde 100644
--- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed
+++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::match_wildcard_for_single_variants)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs
index cff0c8960..dbd7fbe16 100644
--- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs
+++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::match_wildcard_for_single_variants)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr
index 40ff4fbd3..e07d3bdd3 100644
--- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr
+++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.stderr
@@ -1,61 +1,62 @@
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:24:13
+ --> $DIR/match_wildcard_for_single_variants.rs:22:13
|
LL | _ => (),
| ^ help: try: `Self::Rgb(..)`
|
= note: `-D clippy::match-wildcard-for-single-variants` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::match_wildcard_for_single_variants)]`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:34:9
+ --> $DIR/match_wildcard_for_single_variants.rs:32:9
|
LL | _ => {},
| ^ help: try: `Foo::C`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:44:9
+ --> $DIR/match_wildcard_for_single_variants.rs:42:9
|
LL | _ => {},
| ^ help: try: `Color::Blue`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:52:9
+ --> $DIR/match_wildcard_for_single_variants.rs:50:9
|
LL | _ => {},
| ^ help: try: `Color::Blue`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:58:9
+ --> $DIR/match_wildcard_for_single_variants.rs:56:9
|
LL | _ => {},
| ^ help: try: `Color::Blue`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:75:9
+ --> $DIR/match_wildcard_for_single_variants.rs:73:9
|
LL | &_ => (),
| ^^ help: try: `Color::Blue`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:84:9
+ --> $DIR/match_wildcard_for_single_variants.rs:82:9
|
LL | _ => (),
| ^ help: try: `C::Blue`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:91:9
+ --> $DIR/match_wildcard_for_single_variants.rs:89:9
|
LL | _ => (),
| ^ help: try: `Color::Blue`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:126:13
+ --> $DIR/match_wildcard_for_single_variants.rs:124:13
|
LL | _ => (),
| ^ help: try: `Enum::__Private`
error: wildcard matches only a single variant and will also match any future added variants
- --> $DIR/match_wildcard_for_single_variants.rs:153:13
+ --> $DIR/match_wildcard_for_single_variants.rs:151:13
|
LL | _ => 2,
| ^ help: try: `Foo::B`
diff --git a/src/tools/clippy/tests/ui/mem_forget.rs b/src/tools/clippy/tests/ui/mem_forget.rs
index b6c8d9e53..1f508b3bc 100644
--- a/src/tools/clippy/tests/ui/mem_forget.rs
+++ b/src/tools/clippy/tests/ui/mem_forget.rs
@@ -12,15 +12,23 @@ fn main() {
let six: Arc<i32> = Arc::new(6);
memstuff::forget(six);
+ //~^ ERROR: usage of `mem::forget` on `Drop` type
+ //~| NOTE: argument has type `std::sync::Arc<i32>`
let seven: Rc<i32> = Rc::new(7);
std::mem::forget(seven);
+ //~^ ERROR: usage of `mem::forget` on `Drop` type
+ //~| NOTE: argument has type `std::rc::Rc<i32>`
let eight: Vec<i32> = vec![8];
forgetSomething(eight);
+ //~^ ERROR: usage of `mem::forget` on `Drop` type
+ //~| NOTE: argument has type `std::vec::Vec<i32>`
let string = String::new();
std::mem::forget(string);
+ //~^ ERROR: usage of `mem::forget` on type with `Drop` fields
+ //~| NOTE: argument has type `std::string::String`
std::mem::forget(7);
}
diff --git a/src/tools/clippy/tests/ui/mem_forget.stderr b/src/tools/clippy/tests/ui/mem_forget.stderr
index 8004b2aa8..a5ab15031 100644
--- a/src/tools/clippy/tests/ui/mem_forget.stderr
+++ b/src/tools/clippy/tests/ui/mem_forget.stderr
@@ -6,9 +6,10 @@ LL | memstuff::forget(six);
|
= note: argument has type `std::sync::Arc<i32>`
= note: `-D clippy::mem-forget` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mem_forget)]`
error: usage of `mem::forget` on `Drop` type
- --> $DIR/mem_forget.rs:17:5
+ --> $DIR/mem_forget.rs:19:5
|
LL | std::mem::forget(seven);
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | std::mem::forget(seven);
= note: argument has type `std::rc::Rc<i32>`
error: usage of `mem::forget` on `Drop` type
- --> $DIR/mem_forget.rs:20:5
+ --> $DIR/mem_forget.rs:24:5
|
LL | forgetSomething(eight);
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | forgetSomething(eight);
= note: argument has type `std::vec::Vec<i32>`
error: usage of `mem::forget` on type with `Drop` fields
- --> $DIR/mem_forget.rs:23:5
+ --> $DIR/mem_forget.rs:29:5
|
LL | std::mem::forget(string);
| ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mem_replace.fixed b/src/tools/clippy/tests/ui/mem_replace.fixed
index d37e97b0a..453d0bcc5 100644
--- a/src/tools/clippy/tests/ui/mem_replace.fixed
+++ b/src/tools/clippy/tests/ui/mem_replace.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(
clippy::all,
diff --git a/src/tools/clippy/tests/ui/mem_replace.rs b/src/tools/clippy/tests/ui/mem_replace.rs
index 34e37f3db..0c4e0f603 100644
--- a/src/tools/clippy/tests/ui/mem_replace.rs
+++ b/src/tools/clippy/tests/ui/mem_replace.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(
clippy::all,
diff --git a/src/tools/clippy/tests/ui/mem_replace.stderr b/src/tools/clippy/tests/ui/mem_replace.stderr
index 58b57be75..ae5f4e534 100644
--- a/src/tools/clippy/tests/ui/mem_replace.stderr
+++ b/src/tools/clippy/tests/ui/mem_replace.stderr
@@ -1,147 +1,149 @@
error: replacing an `Option` with `None`
- --> $DIR/mem_replace.rs:16:13
+ --> $DIR/mem_replace.rs:14:13
|
LL | let _ = mem::replace(&mut an_option, None);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
|
= note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
error: replacing an `Option` with `None`
- --> $DIR/mem_replace.rs:18:13
+ --> $DIR/mem_replace.rs:16:13
|
LL | let _ = mem::replace(an_option, None);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:23:13
+ --> $DIR/mem_replace.rs:21:13
|
LL | let _ = std::mem::replace(&mut s, String::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
|
= note: `-D clippy::mem-replace-with-default` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:26:13
+ --> $DIR/mem_replace.rs:24:13
|
LL | let _ = std::mem::replace(s, String::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:27:13
+ --> $DIR/mem_replace.rs:25:13
|
LL | let _ = std::mem::replace(s, Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:30:13
+ --> $DIR/mem_replace.rs:28:13
|
LL | let _ = std::mem::replace(&mut v, Vec::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:31:13
+ --> $DIR/mem_replace.rs:29:13
|
LL | let _ = std::mem::replace(&mut v, Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:32:13
+ --> $DIR/mem_replace.rs:30:13
|
LL | let _ = std::mem::replace(&mut v, Vec::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:33:13
+ --> $DIR/mem_replace.rs:31:13
|
LL | let _ = std::mem::replace(&mut v, vec![]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:36:13
+ --> $DIR/mem_replace.rs:34:13
|
LL | let _ = std::mem::replace(&mut hash_map, HashMap::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_map)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:39:13
+ --> $DIR/mem_replace.rs:37:13
|
LL | let _ = std::mem::replace(&mut btree_map, BTreeMap::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_map)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:42:13
+ --> $DIR/mem_replace.rs:40:13
|
LL | let _ = std::mem::replace(&mut vd, VecDeque::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut vd)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:45:13
+ --> $DIR/mem_replace.rs:43:13
|
LL | let _ = std::mem::replace(&mut hash_set, HashSet::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_set)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:48:13
+ --> $DIR/mem_replace.rs:46:13
|
LL | let _ = std::mem::replace(&mut btree_set, BTreeSet::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_set)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:51:13
+ --> $DIR/mem_replace.rs:49:13
|
LL | let _ = std::mem::replace(&mut list, LinkedList::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut list)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:54:13
+ --> $DIR/mem_replace.rs:52:13
|
LL | let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut binary_heap)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:57:13
+ --> $DIR/mem_replace.rs:55:13
|
LL | let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut tuple)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:60:13
+ --> $DIR/mem_replace.rs:58:13
|
LL | let _ = std::mem::replace(&mut refstr, "");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut refstr)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:63:13
+ --> $DIR/mem_replace.rs:61:13
|
LL | let _ = std::mem::replace(&mut slice, &[]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut slice)`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:91:13
+ --> $DIR/mem_replace.rs:89:13
|
LL | let _ = std::mem::replace(&mut s, String::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
error: replacing an `Option` with `None`
- --> $DIR/mem_replace.rs:121:13
+ --> $DIR/mem_replace.rs:119:13
|
LL | let _ = std::mem::replace(&mut f.0, None);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
error: replacing an `Option` with `None`
- --> $DIR/mem_replace.rs:122:13
+ --> $DIR/mem_replace.rs:120:13
|
LL | let _ = std::mem::replace(&mut *f, None);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
error: replacing an `Option` with `None`
- --> $DIR/mem_replace.rs:123:13
+ --> $DIR/mem_replace.rs:121:13
|
LL | let _ = std::mem::replace(&mut b.opt, None);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
- --> $DIR/mem_replace.rs:125:13
+ --> $DIR/mem_replace.rs:123:13
|
LL | let _ = std::mem::replace(&mut b.val, String::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)`
diff --git a/src/tools/clippy/tests/ui/mem_replace_macro.rs b/src/tools/clippy/tests/ui/mem_replace_macro.rs
index e53342f2e..132873858 100644
--- a/src/tools/clippy/tests/ui/mem_replace_macro.rs
+++ b/src/tools/clippy/tests/ui/mem_replace_macro.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::mem_replace_with_default)]
extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/mem_replace_macro.stderr b/src/tools/clippy/tests/ui/mem_replace_macro.stderr
index 35dda93da..842ad3a85 100644
--- a/src/tools/clippy/tests/ui/mem_replace_macro.stderr
+++ b/src/tools/clippy/tests/ui/mem_replace_macro.stderr
@@ -5,6 +5,7 @@ LL | inline!(std::mem::replace($s, Default::default()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::mem-replace-with-default` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/methods.stderr b/src/tools/clippy/tests/ui/methods.stderr
index 6be38b24f..e32b3b336 100644
--- a/src/tools/clippy/tests/ui/methods.stderr
+++ b/src/tools/clippy/tests/ui/methods.stderr
@@ -7,6 +7,7 @@ LL | | }
| |_____^
|
= note: `-D clippy::new-ret-no-self` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]`
error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead
--> $DIR/methods.rs:124:13
@@ -19,6 +20,7 @@ LL | | ).next();
| |___________________________^
|
= note: `-D clippy::filter-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filter_next)]`
error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui/methods_fixable.fixed b/src/tools/clippy/tests/ui/methods_fixable.fixed
index ce5d19a8b..bb06b5a48 100644
--- a/src/tools/clippy/tests/ui/methods_fixable.fixed
+++ b/src/tools/clippy/tests/ui/methods_fixable.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::filter_next)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/methods_fixable.rs b/src/tools/clippy/tests/ui/methods_fixable.rs
index 0615817ec..11de92459 100644
--- a/src/tools/clippy/tests/ui/methods_fixable.rs
+++ b/src/tools/clippy/tests/ui/methods_fixable.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::filter_next)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/methods_fixable.stderr b/src/tools/clippy/tests/ui/methods_fixable.stderr
index 6f45d100d..1bfe56d91 100644
--- a/src/tools/clippy/tests/ui/methods_fixable.stderr
+++ b/src/tools/clippy/tests/ui/methods_fixable.stderr
@@ -1,10 +1,11 @@
error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead
- --> $DIR/methods_fixable.rs:11:13
+ --> $DIR/methods_fixable.rs:9:13
|
LL | let _ = v.iter().filter(|&x| *x < 0).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.iter().find(|&x| *x < 0)`
|
= note: `-D clippy::filter-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filter_next)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/methods_unfixable.rs b/src/tools/clippy/tests/ui/methods_unfixable.rs
index 3d88ce4b6..ee59983a7 100644
--- a/src/tools/clippy/tests/ui/methods_unfixable.rs
+++ b/src/tools/clippy/tests/ui/methods_unfixable.rs
@@ -1,5 +1,5 @@
#![warn(clippy::filter_next)]
-
+//@no-rustfix
fn main() {
issue10029();
}
@@ -7,4 +7,5 @@ fn main() {
pub fn issue10029() {
let iter = (0..10);
let _ = iter.filter(|_| true).next();
+ //~^ ERROR: called `filter(..).next()` on an `Iterator`. This is more succinctly expre
}
diff --git a/src/tools/clippy/tests/ui/methods_unfixable.stderr b/src/tools/clippy/tests/ui/methods_unfixable.stderr
index 6e101fe16..581a985e0 100644
--- a/src/tools/clippy/tests/ui/methods_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/methods_unfixable.stderr
@@ -10,6 +10,7 @@ help: you will also need to make `iter` mutable, because `find` takes `&mut self
LL | let iter = (0..10);
| ^^^^
= note: `-D clippy::filter-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::filter_next)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/min_ident_chars.rs b/src/tools/clippy/tests/ui/min_ident_chars.rs
index 03784442e..030863ca0 100644
--- a/src/tools/clippy/tests/ui/min_ident_chars.rs
+++ b/src/tools/clippy/tests/ui/min_ident_chars.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(irrefutable_let_patterns, nonstandard_style, unused)]
#![warn(clippy::min_ident_chars)]
diff --git a/src/tools/clippy/tests/ui/min_ident_chars.stderr b/src/tools/clippy/tests/ui/min_ident_chars.stderr
index 4dff6588b..253636cf9 100644
--- a/src/tools/clippy/tests/ui/min_ident_chars.stderr
+++ b/src/tools/clippy/tests/ui/min_ident_chars.stderr
@@ -5,6 +5,7 @@ LL | struct A {
| ^
|
= note: `-D clippy::min-ident-chars` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]`
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:9:5
diff --git a/src/tools/clippy/tests/ui/min_max.rs b/src/tools/clippy/tests/ui/min_max.rs
index 1215a0228..cf64f85f9 100644
--- a/src/tools/clippy/tests/ui/min_max.rs
+++ b/src/tools/clippy/tests/ui/min_max.rs
@@ -20,11 +20,17 @@ impl NotOrd {
fn main() {
let x = 2usize;
min(1, max(3, x));
+ //~^ ERROR: this `min`/`max` combination leads to constant result
+ //~| NOTE: `-D clippy::min-max` implied by `-D warnings`
min(max(3, x), 1);
+ //~^ ERROR: this `min`/`max` combination leads to constant result
max(min(x, 1), 3);
+ //~^ ERROR: this `min`/`max` combination leads to constant result
max(3, min(x, 1));
+ //~^ ERROR: this `min`/`max` combination leads to constant result
my_max(3, my_min(x, 1));
+ //~^ ERROR: this `min`/`max` combination leads to constant result
min(3, max(1, x)); // ok, could be 1, 2 or 3 depending on x
@@ -35,24 +41,32 @@ fn main() {
let s = "Hello";
min("Apple", max("Zoo", s));
+ //~^ ERROR: this `min`/`max` combination leads to constant result
max(min(s, "Apple"), "Zoo");
+ //~^ ERROR: this `min`/`max` combination leads to constant result
max("Apple", min(s, "Zoo")); // ok
let f = 3f32;
x.min(1).max(3);
+ //~^ ERROR: this `min`/`max` combination leads to constant result
x.max(3).min(1);
+ //~^ ERROR: this `min`/`max` combination leads to constant result
f.max(3f32).min(1f32);
+ //~^ ERROR: this `min`/`max` combination leads to constant result
x.max(1).min(3); // ok
x.min(3).max(1); // ok
f.min(3f32).max(1f32); // ok
max(x.min(1), 3);
+ //~^ ERROR: this `min`/`max` combination leads to constant result
min(x.max(1), 3); // ok
s.max("Zoo").min("Apple");
+ //~^ ERROR: this `min`/`max` combination leads to constant result
s.min("Apple").max("Zoo");
+ //~^ ERROR: this `min`/`max` combination leads to constant result
s.min("Zoo").max("Apple"); // ok
diff --git a/src/tools/clippy/tests/ui/min_max.stderr b/src/tools/clippy/tests/ui/min_max.stderr
index 402b094f4..e9c64e56b 100644
--- a/src/tools/clippy/tests/ui/min_max.stderr
+++ b/src/tools/clippy/tests/ui/min_max.stderr
@@ -5,75 +5,76 @@ LL | min(1, max(3, x));
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::min-max` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::min_max)]`
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:23:5
+ --> $DIR/min_max.rs:25:5
|
LL | min(max(3, x), 1);
| ^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:24:5
+ --> $DIR/min_max.rs:27:5
|
LL | max(min(x, 1), 3);
| ^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:25:5
+ --> $DIR/min_max.rs:29:5
|
LL | max(3, min(x, 1));
| ^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:27:5
+ --> $DIR/min_max.rs:32:5
|
LL | my_max(3, my_min(x, 1));
| ^^^^^^^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:37:5
+ --> $DIR/min_max.rs:43:5
|
LL | min("Apple", max("Zoo", s));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:38:5
+ --> $DIR/min_max.rs:45:5
|
LL | max(min(s, "Apple"), "Zoo");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:43:5
+ --> $DIR/min_max.rs:51:5
|
LL | x.min(1).max(3);
| ^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:44:5
+ --> $DIR/min_max.rs:53:5
|
LL | x.max(3).min(1);
| ^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:45:5
+ --> $DIR/min_max.rs:55:5
|
LL | f.max(3f32).min(1f32);
| ^^^^^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:51:5
+ --> $DIR/min_max.rs:62:5
|
LL | max(x.min(1), 3);
| ^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:54:5
+ --> $DIR/min_max.rs:66:5
|
LL | s.max("Zoo").min("Apple");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `min`/`max` combination leads to constant result
- --> $DIR/min_max.rs:55:5
+ --> $DIR/min_max.rs:68:5
|
LL | s.min("Apple").max("Zoo");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
index 955e7eb72..5fe3306d6 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
@@ -11,11 +11,13 @@ fn just_under_msrv() {
#[clippy::msrv = "1.43.0"]
fn meets_msrv() {
let log2_10 = 3.321928094887362;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found
}
#[clippy::msrv = "1.44.0"]
fn just_above_msrv() {
let log2_10 = 3.321928094887362;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found
}
#[clippy::msrv = "1.42"]
@@ -26,6 +28,7 @@ fn no_patch_under() {
#[clippy::msrv = "1.43"]
fn no_patch_meets() {
let log2_10 = 3.321928094887362;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found
}
fn inner_attr_under() {
@@ -36,6 +39,7 @@ fn inner_attr_under() {
fn inner_attr_meets() {
#![clippy::msrv = "1.43"]
let log2_10 = 3.321928094887362;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found
}
// https://github.com/rust-lang/rust-clippy/issues/6920
@@ -46,6 +50,7 @@ fn scoping() {
// Should warn
let log2_10 = 3.321928094887362;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found
mod a {
#![clippy::msrv = "1.42.0"]
@@ -53,6 +58,7 @@ fn scoping() {
fn should_warn() {
#![clippy::msrv = "1.43.0"]
let log2_10 = 3.321928094887362;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::LOG2_10` found
}
fn should_not_warn() {
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
index 7e2135584..3c8555c62 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
@@ -8,7 +8,7 @@ LL | let log2_10 = 3.321928094887362;
= note: `#[deny(clippy::approx_constant)]` on by default
error: approximate value of `f{32, 64}::consts::LOG2_10` found
- --> $DIR/min_rust_version_attr.rs:18:19
+ --> $DIR/min_rust_version_attr.rs:19:19
|
LL | let log2_10 = 3.321928094887362;
| ^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL | let log2_10 = 3.321928094887362;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG2_10` found
- --> $DIR/min_rust_version_attr.rs:28:19
+ --> $DIR/min_rust_version_attr.rs:30:19
|
LL | let log2_10 = 3.321928094887362;
| ^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL | let log2_10 = 3.321928094887362;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG2_10` found
- --> $DIR/min_rust_version_attr.rs:38:19
+ --> $DIR/min_rust_version_attr.rs:41:19
|
LL | let log2_10 = 3.321928094887362;
| ^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL | let log2_10 = 3.321928094887362;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG2_10` found
- --> $DIR/min_rust_version_attr.rs:48:19
+ --> $DIR/min_rust_version_attr.rs:52:19
|
LL | let log2_10 = 3.321928094887362;
| ^^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL | let log2_10 = 3.321928094887362;
= help: consider using the constant directly
error: approximate value of `f{32, 64}::consts::LOG2_10` found
- --> $DIR/min_rust_version_attr.rs:55:27
+ --> $DIR/min_rust_version_attr.rs:60:27
|
LL | let log2_10 = 3.321928094887362;
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
index 02892f329..c8a0d6641 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
@@ -1,18 +1,23 @@
#![feature(custom_inner_attributes)]
#![clippy::msrv = "invalid.version"]
+//~^ ERROR: `invalid.version` is not a valid Rust version
fn main() {}
#[clippy::msrv = "invalid.version"]
+//~^ ERROR: `invalid.version` is not a valid Rust version
fn outer_attr() {}
mod multiple {
#![clippy::msrv = "1.40"]
#![clippy::msrv = "=1.35.0"]
+ //~^ ERROR: `msrv` is defined multiple times
#![clippy::msrv = "1.10.1"]
+ //~^ ERROR: `msrv` is defined multiple times
mod foo {
#![clippy::msrv = "1"]
#![clippy::msrv = "1.0.0"]
+ //~^ ERROR: `msrv` is defined multiple times
}
}
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
index 675b78031..8d4071e25 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
@@ -5,43 +5,43 @@ LL | #![clippy::msrv = "invalid.version"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `invalid.version` is not a valid Rust version
- --> $DIR/min_rust_version_invalid_attr.rs:6:1
+ --> $DIR/min_rust_version_invalid_attr.rs:7:1
|
LL | #[clippy::msrv = "invalid.version"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
- --> $DIR/min_rust_version_invalid_attr.rs:11:5
+ --> $DIR/min_rust_version_invalid_attr.rs:13:5
|
LL | #![clippy::msrv = "=1.35.0"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first definition found here
- --> $DIR/min_rust_version_invalid_attr.rs:10:5
+ --> $DIR/min_rust_version_invalid_attr.rs:12:5
|
LL | #![clippy::msrv = "1.40"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
- --> $DIR/min_rust_version_invalid_attr.rs:12:5
+ --> $DIR/min_rust_version_invalid_attr.rs:15:5
|
LL | #![clippy::msrv = "1.10.1"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first definition found here
- --> $DIR/min_rust_version_invalid_attr.rs:10:5
+ --> $DIR/min_rust_version_invalid_attr.rs:12:5
|
LL | #![clippy::msrv = "1.40"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `msrv` is defined multiple times
- --> $DIR/min_rust_version_invalid_attr.rs:16:9
+ --> $DIR/min_rust_version_invalid_attr.rs:20:9
|
LL | #![clippy::msrv = "1.0.0"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first definition found here
- --> $DIR/min_rust_version_invalid_attr.rs:15:9
+ --> $DIR/min_rust_version_invalid_attr.rs:19:9
|
LL | #![clippy::msrv = "1"]
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed
index f58e9a429..de02b2bee 100644
--- a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed
+++ b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs
index e00224f5c..a96051875 100644
--- a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs
+++ b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.stderr b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.stderr
index 5f1b09083..795d043e2 100644
--- a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.stderr
+++ b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.stderr
@@ -1,5 +1,5 @@
error: operating system used in target family position
- --> $DIR/mismatched_target_os_non_unix.rs:6:1
+ --> $DIR/mismatched_target_os_non_unix.rs:4:1
|
LL | #[cfg(hermit)]
| ^^^^^^------^^
@@ -7,9 +7,10 @@ LL | #[cfg(hermit)]
| help: try: `target_os = "hermit"`
|
= note: `-D clippy::mismatched-target-os` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mismatched_target_os)]`
error: operating system used in target family position
- --> $DIR/mismatched_target_os_non_unix.rs:9:1
+ --> $DIR/mismatched_target_os_non_unix.rs:7:1
|
LL | #[cfg(wasi)]
| ^^^^^^----^^
@@ -17,7 +18,7 @@ LL | #[cfg(wasi)]
| help: try: `target_os = "wasi"`
error: operating system used in target family position
- --> $DIR/mismatched_target_os_non_unix.rs:12:1
+ --> $DIR/mismatched_target_os_non_unix.rs:10:1
|
LL | #[cfg(none)]
| ^^^^^^----^^
@@ -25,7 +26,7 @@ LL | #[cfg(none)]
| help: try: `target_os = "none"`
error: operating system used in target family position
- --> $DIR/mismatched_target_os_non_unix.rs:16:1
+ --> $DIR/mismatched_target_os_non_unix.rs:14:1
|
LL | #[cfg(all(not(windows), wasi))]
| ^^^^^^^^^^^^^^^^^^^^^^^^----^^^
diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed b/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed
index 330587a3c..b945c4d96 100644
--- a/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed
+++ b/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs b/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs
index 5a90019a2..34307facd 100644
--- a/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs
+++ b/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr b/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr
index 9822c77c9..261c33754 100644
--- a/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr
+++ b/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr
@@ -1,5 +1,5 @@
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:6:1
+ --> $DIR/mismatched_target_os_unix.rs:4:1
|
LL | #[cfg(linux)]
| ^^^^^^-----^^
@@ -8,9 +8,10 @@ LL | #[cfg(linux)]
|
= help: did you mean `unix`?
= note: `-D clippy::mismatched-target-os` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mismatched_target_os)]`
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:9:1
+ --> $DIR/mismatched_target_os_unix.rs:7:1
|
LL | #[cfg(freebsd)]
| ^^^^^^-------^^
@@ -20,7 +21,7 @@ LL | #[cfg(freebsd)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:12:1
+ --> $DIR/mismatched_target_os_unix.rs:10:1
|
LL | #[cfg(dragonfly)]
| ^^^^^^---------^^
@@ -30,7 +31,7 @@ LL | #[cfg(dragonfly)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:15:1
+ --> $DIR/mismatched_target_os_unix.rs:13:1
|
LL | #[cfg(openbsd)]
| ^^^^^^-------^^
@@ -40,7 +41,7 @@ LL | #[cfg(openbsd)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:18:1
+ --> $DIR/mismatched_target_os_unix.rs:16:1
|
LL | #[cfg(netbsd)]
| ^^^^^^------^^
@@ -50,7 +51,7 @@ LL | #[cfg(netbsd)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:21:1
+ --> $DIR/mismatched_target_os_unix.rs:19:1
|
LL | #[cfg(macos)]
| ^^^^^^-----^^
@@ -60,7 +61,7 @@ LL | #[cfg(macos)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:24:1
+ --> $DIR/mismatched_target_os_unix.rs:22:1
|
LL | #[cfg(ios)]
| ^^^^^^---^^
@@ -70,7 +71,7 @@ LL | #[cfg(ios)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:27:1
+ --> $DIR/mismatched_target_os_unix.rs:25:1
|
LL | #[cfg(android)]
| ^^^^^^-------^^
@@ -80,7 +81,7 @@ LL | #[cfg(android)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:30:1
+ --> $DIR/mismatched_target_os_unix.rs:28:1
|
LL | #[cfg(emscripten)]
| ^^^^^^----------^^
@@ -90,7 +91,7 @@ LL | #[cfg(emscripten)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:33:1
+ --> $DIR/mismatched_target_os_unix.rs:31:1
|
LL | #[cfg(fuchsia)]
| ^^^^^^-------^^
@@ -100,7 +101,7 @@ LL | #[cfg(fuchsia)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:36:1
+ --> $DIR/mismatched_target_os_unix.rs:34:1
|
LL | #[cfg(haiku)]
| ^^^^^^-----^^
@@ -110,7 +111,7 @@ LL | #[cfg(haiku)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:39:1
+ --> $DIR/mismatched_target_os_unix.rs:37:1
|
LL | #[cfg(illumos)]
| ^^^^^^-------^^
@@ -120,7 +121,7 @@ LL | #[cfg(illumos)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:42:1
+ --> $DIR/mismatched_target_os_unix.rs:40:1
|
LL | #[cfg(l4re)]
| ^^^^^^----^^
@@ -130,7 +131,7 @@ LL | #[cfg(l4re)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:45:1
+ --> $DIR/mismatched_target_os_unix.rs:43:1
|
LL | #[cfg(redox)]
| ^^^^^^-----^^
@@ -140,7 +141,7 @@ LL | #[cfg(redox)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:48:1
+ --> $DIR/mismatched_target_os_unix.rs:46:1
|
LL | #[cfg(solaris)]
| ^^^^^^-------^^
@@ -150,7 +151,7 @@ LL | #[cfg(solaris)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:51:1
+ --> $DIR/mismatched_target_os_unix.rs:49:1
|
LL | #[cfg(vxworks)]
| ^^^^^^-------^^
@@ -160,7 +161,7 @@ LL | #[cfg(vxworks)]
= help: did you mean `unix`?
error: operating system used in target family position
- --> $DIR/mismatched_target_os_unix.rs:55:1
+ --> $DIR/mismatched_target_os_unix.rs:53:1
|
LL | #[cfg(all(not(any(solaris, linux)), freebsd))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
index 40c1fcae1..af2882e41 100644
--- a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
+++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
@@ -9,9 +9,12 @@ fn main() {
// lint on both params
impl<B, A> Foo<B, A> {}
+ //~^ ERROR: `Foo` has a similarly named generic type parameter `B` in its declaration,
+ //~| ERROR: `Foo` has a similarly named generic type parameter `A` in its declaration,
// lint on the 2nd param
impl<C, A> Foo<C, A> {}
+ //~^ ERROR: `Foo` has a similarly named generic type parameter `A` in its declaration,
// should not lint
impl<A, B> Foo<A, B> {}
@@ -23,6 +26,8 @@ fn main() {
// should not lint on lifetimes
impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}
+ //~^ ERROR: `FooLifetime` has a similarly named generic type parameter `B` in its decl
+ //~| ERROR: `FooLifetime` has a similarly named generic type parameter `A` in its decl
struct Bar {
x: i32,
@@ -39,6 +44,9 @@ fn main() {
}
impl<C, A, B> FooEnum<C, A, B> {}
+ //~^ ERROR: `FooEnum` has a similarly named generic type parameter `C` in its declarat
+ //~| ERROR: `FooEnum` has a similarly named generic type parameter `A` in its declarat
+ //~| ERROR: `FooEnum` has a similarly named generic type parameter `B` in its declarat
// also works for unions
union FooUnion<A: Copy, B>
@@ -50,6 +58,8 @@ fn main() {
}
impl<B: Copy, A> FooUnion<B, A> where A: Copy {}
+ //~^ ERROR: `FooUnion` has a similarly named generic type parameter `B` in its declara
+ //~| ERROR: `FooUnion` has a similarly named generic type parameter `A` in its declara
impl<A, B> FooUnion<A, B>
where
diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr b/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr
index 204d49905..8edbe3295 100644
--- a/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr
+++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr
@@ -6,6 +6,7 @@ LL | impl<B, A> Foo<B, A> {}
|
= help: try `A`, or a name that does not conflict with `Foo`'s generic params
= note: `-D clippy::mismatching-type-param-order` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mismatching_type_param_order)]`
error: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order
--> $DIR/mismatching_type_param_order.rs:11:23
@@ -16,7 +17,7 @@ LL | impl<B, A> Foo<B, A> {}
= help: try `B`, or a name that does not conflict with `Foo`'s generic params
error: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:14:23
+ --> $DIR/mismatching_type_param_order.rs:16:23
|
LL | impl<C, A> Foo<C, A> {}
| ^
@@ -24,7 +25,7 @@ LL | impl<C, A> Foo<C, A> {}
= help: try `B`, or a name that does not conflict with `Foo`'s generic params
error: `FooLifetime` has a similarly named generic type parameter `B` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:25:44
+ --> $DIR/mismatching_type_param_order.rs:28:44
|
LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}
| ^
@@ -32,7 +33,7 @@ LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}
= help: try `A`, or a name that does not conflict with `FooLifetime`'s generic params
error: `FooLifetime` has a similarly named generic type parameter `A` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:25:47
+ --> $DIR/mismatching_type_param_order.rs:28:47
|
LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}
| ^
@@ -40,7 +41,7 @@ LL | impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}
= help: try `B`, or a name that does not conflict with `FooLifetime`'s generic params
error: `FooEnum` has a similarly named generic type parameter `C` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:41:27
+ --> $DIR/mismatching_type_param_order.rs:46:27
|
LL | impl<C, A, B> FooEnum<C, A, B> {}
| ^
@@ -48,7 +49,7 @@ LL | impl<C, A, B> FooEnum<C, A, B> {}
= help: try `A`, or a name that does not conflict with `FooEnum`'s generic params
error: `FooEnum` has a similarly named generic type parameter `A` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:41:30
+ --> $DIR/mismatching_type_param_order.rs:46:30
|
LL | impl<C, A, B> FooEnum<C, A, B> {}
| ^
@@ -56,7 +57,7 @@ LL | impl<C, A, B> FooEnum<C, A, B> {}
= help: try `B`, or a name that does not conflict with `FooEnum`'s generic params
error: `FooEnum` has a similarly named generic type parameter `B` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:41:33
+ --> $DIR/mismatching_type_param_order.rs:46:33
|
LL | impl<C, A, B> FooEnum<C, A, B> {}
| ^
@@ -64,7 +65,7 @@ LL | impl<C, A, B> FooEnum<C, A, B> {}
= help: try `C`, or a name that does not conflict with `FooEnum`'s generic params
error: `FooUnion` has a similarly named generic type parameter `B` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:52:31
+ --> $DIR/mismatching_type_param_order.rs:60:31
|
LL | impl<B: Copy, A> FooUnion<B, A> where A: Copy {}
| ^
@@ -72,7 +73,7 @@ LL | impl<B: Copy, A> FooUnion<B, A> where A: Copy {}
= help: try `A`, or a name that does not conflict with `FooUnion`'s generic params
error: `FooUnion` has a similarly named generic type parameter `A` in its declaration, but in a different order
- --> $DIR/mismatching_type_param_order.rs:52:34
+ --> $DIR/mismatching_type_param_order.rs:60:34
|
LL | impl<B: Copy, A> FooUnion<B, A> where A: Copy {}
| ^
diff --git a/src/tools/clippy/tests/ui/misnamed_getters.fixed b/src/tools/clippy/tests/ui/misnamed_getters.fixed
new file mode 100644
index 000000000..2a7a2067e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/misnamed_getters.fixed
@@ -0,0 +1,143 @@
+#![allow(unused)]
+#![warn(clippy::misnamed_getters)]
+
+struct A {
+ a: u8,
+ b: u8,
+ c: u8,
+}
+
+impl A {
+ fn a(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ //~| NOTE: `-D clippy::misnamed-getters` implied by `-D warnings`
+ &self.a
+ }
+ fn a_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.a
+ }
+
+ fn b(self) -> u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ self.b
+ }
+
+ fn b_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.b
+ }
+
+ fn c(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &self.c
+ }
+
+ fn c_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.c
+ }
+}
+
+union B {
+ a: u8,
+ b: u8,
+}
+
+impl B {
+ unsafe fn a(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &self.a
+ }
+ unsafe fn a_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.a
+ }
+
+ unsafe fn b(self) -> u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ self.b
+ }
+
+ unsafe fn b_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.b
+ }
+
+ unsafe fn c(&self) -> &u8 {
+ &self.b
+ }
+
+ unsafe fn c_mut(&mut self) -> &mut u8 {
+ &mut self.a
+ }
+
+ unsafe fn a_unchecked(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &self.a
+ }
+ unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.a
+ }
+
+ unsafe fn b_unchecked(self) -> u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ self.b
+ }
+
+ unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.b
+ }
+
+ unsafe fn c_unchecked(&self) -> &u8 {
+ &self.b
+ }
+
+ unsafe fn c_unchecked_mut(&mut self) -> &mut u8 {
+ &mut self.a
+ }
+}
+
+struct D {
+ d: u8,
+ inner: A,
+}
+
+impl core::ops::Deref for D {
+ type Target = A;
+ fn deref(&self) -> &A {
+ &self.inner
+ }
+}
+
+impl core::ops::DerefMut for D {
+ fn deref_mut(&mut self) -> &mut A {
+ &mut self.inner
+ }
+}
+
+impl D {
+ fn a(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &self.a
+ }
+ fn a_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.a
+ }
+
+ fn d(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &self.d
+ }
+ fn d_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ &mut self.d
+ }
+}
+
+fn main() {
+ // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/misnamed_getters.rs b/src/tools/clippy/tests/ui/misnamed_getters.rs
index 03e7dac7d..56ddc46c4 100644
--- a/src/tools/clippy/tests/ui/misnamed_getters.rs
+++ b/src/tools/clippy/tests/ui/misnamed_getters.rs
@@ -9,25 +9,32 @@ struct A {
impl A {
fn a(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
+ //~| NOTE: `-D clippy::misnamed-getters` implied by `-D warnings`
&self.b
}
fn a_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.b
}
fn b(self) -> u8 {
+ //~^ ERROR: getter function appears to return the wrong field
self.a
}
fn b_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.a
}
fn c(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&self.b
}
fn c_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.a
}
}
@@ -39,17 +46,21 @@ union B {
impl B {
unsafe fn a(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&self.b
}
unsafe fn a_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.b
}
unsafe fn b(self) -> u8 {
+ //~^ ERROR: getter function appears to return the wrong field
self.a
}
unsafe fn b_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.a
}
@@ -62,17 +73,21 @@ impl B {
}
unsafe fn a_unchecked(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&self.b
}
unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.b
}
unsafe fn b_unchecked(self) -> u8 {
+ //~^ ERROR: getter function appears to return the wrong field
self.a
}
unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.a
}
@@ -105,16 +120,20 @@ impl core::ops::DerefMut for D {
impl D {
fn a(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&self.b
}
fn a_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.b
}
fn d(&self) -> &u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&self.b
}
fn d_mut(&mut self) -> &mut u8 {
+ //~^ ERROR: getter function appears to return the wrong field
&mut self.b
}
}
diff --git a/src/tools/clippy/tests/ui/misnamed_getters.stderr b/src/tools/clippy/tests/ui/misnamed_getters.stderr
index 1e38a83d0..aadec6549 100644
--- a/src/tools/clippy/tests/ui/misnamed_getters.stderr
+++ b/src/tools/clippy/tests/ui/misnamed_getters.stderr
@@ -2,161 +2,181 @@ error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:11:5
|
LL | / fn a(&self) -> &u8 {
+LL | |
+LL | |
LL | | &self.b
| | ------- help: consider using: `&self.a`
LL | | }
| |_____^
|
= note: `-D clippy::misnamed-getters` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::misnamed_getters)]`
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:14:5
+ --> $DIR/misnamed_getters.rs:16:5
|
LL | / fn a_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.b
| | ----------- help: consider using: `&mut self.a`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:18:5
+ --> $DIR/misnamed_getters.rs:21:5
|
LL | / fn b(self) -> u8 {
+LL | |
LL | | self.a
| | ------ help: consider using: `self.b`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:22:5
+ --> $DIR/misnamed_getters.rs:26:5
|
LL | / fn b_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.a
| | ----------- help: consider using: `&mut self.b`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:26:5
+ --> $DIR/misnamed_getters.rs:31:5
|
LL | / fn c(&self) -> &u8 {
+LL | |
LL | | &self.b
| | ------- help: consider using: `&self.c`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:30:5
+ --> $DIR/misnamed_getters.rs:36:5
|
LL | / fn c_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.a
| | ----------- help: consider using: `&mut self.c`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:41:5
+ --> $DIR/misnamed_getters.rs:48:5
|
LL | / unsafe fn a(&self) -> &u8 {
+LL | |
LL | | &self.b
| | ------- help: consider using: `&self.a`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:44:5
+ --> $DIR/misnamed_getters.rs:52:5
|
LL | / unsafe fn a_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.b
| | ----------- help: consider using: `&mut self.a`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:48:5
+ --> $DIR/misnamed_getters.rs:57:5
|
LL | / unsafe fn b(self) -> u8 {
+LL | |
LL | | self.a
| | ------ help: consider using: `self.b`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:52:5
+ --> $DIR/misnamed_getters.rs:62:5
|
LL | / unsafe fn b_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.a
| | ----------- help: consider using: `&mut self.b`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:64:5
+ --> $DIR/misnamed_getters.rs:75:5
|
LL | / unsafe fn a_unchecked(&self) -> &u8 {
+LL | |
LL | | &self.b
| | ------- help: consider using: `&self.a`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:67:5
+ --> $DIR/misnamed_getters.rs:79:5
|
LL | / unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.b
| | ----------- help: consider using: `&mut self.a`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:71:5
+ --> $DIR/misnamed_getters.rs:84:5
|
LL | / unsafe fn b_unchecked(self) -> u8 {
+LL | |
LL | | self.a
| | ------ help: consider using: `self.b`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:75:5
+ --> $DIR/misnamed_getters.rs:89:5
|
LL | / unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.a
| | ----------- help: consider using: `&mut self.b`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:107:5
+ --> $DIR/misnamed_getters.rs:122:5
|
LL | / fn a(&self) -> &u8 {
+LL | |
LL | | &self.b
| | ------- help: consider using: `&self.a`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:110:5
+ --> $DIR/misnamed_getters.rs:126:5
|
LL | / fn a_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.b
| | ----------- help: consider using: `&mut self.a`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:114:5
+ --> $DIR/misnamed_getters.rs:131:5
|
LL | / fn d(&self) -> &u8 {
+LL | |
LL | | &self.b
| | ------- help: consider using: `&self.d`
LL | | }
| |_____^
error: getter function appears to return the wrong field
- --> $DIR/misnamed_getters.rs:117:5
+ --> $DIR/misnamed_getters.rs:135:5
|
LL | / fn d_mut(&mut self) -> &mut u8 {
+LL | |
LL | | &mut self.b
| | ----------- help: consider using: `&mut self.d`
LL | | }
diff --git a/src/tools/clippy/tests/ui/missing_assert_message.rs b/src/tools/clippy/tests/ui/missing_assert_message.rs
index af1358f61..2ad8e0127 100644
--- a/src/tools/clippy/tests/ui/missing_assert_message.rs
+++ b/src/tools/clippy/tests/ui/missing_assert_message.rs
@@ -10,29 +10,45 @@ macro_rules! bar {
// Should trigger warning
fn asserts_without_message() {
assert!(foo());
+ //~^ ERROR: assert without any message
assert_eq!(foo(), foo());
+ //~^ ERROR: assert without any message
assert_ne!(foo(), foo());
+ //~^ ERROR: assert without any message
debug_assert!(foo());
+ //~^ ERROR: assert without any message
debug_assert_eq!(foo(), foo());
+ //~^ ERROR: assert without any message
debug_assert_ne!(foo(), foo());
+ //~^ ERROR: assert without any message
}
// Should trigger warning
fn asserts_without_message_but_with_macro_calls() {
assert!(bar!(true));
+ //~^ ERROR: assert without any message
assert!(bar!(true, false));
+ //~^ ERROR: assert without any message
assert_eq!(bar!(true), foo());
+ //~^ ERROR: assert without any message
assert_ne!(bar!(true, true), bar!(true));
+ //~^ ERROR: assert without any message
}
// Should trigger warning
fn asserts_with_trailing_commas() {
assert!(foo(),);
+ //~^ ERROR: assert without any message
assert_eq!(foo(), foo(),);
+ //~^ ERROR: assert without any message
assert_ne!(foo(), foo(),);
+ //~^ ERROR: assert without any message
debug_assert!(foo(),);
+ //~^ ERROR: assert without any message
debug_assert_eq!(foo(), foo(),);
+ //~^ ERROR: assert without any message
debug_assert_ne!(foo(), foo(),);
+ //~^ ERROR: assert without any message
}
// Should not trigger warning
diff --git a/src/tools/clippy/tests/ui/missing_assert_message.stderr b/src/tools/clippy/tests/ui/missing_assert_message.stderr
index 33a5c1f8e..e07f52e3f 100644
--- a/src/tools/clippy/tests/ui/missing_assert_message.stderr
+++ b/src/tools/clippy/tests/ui/missing_assert_message.stderr
@@ -6,9 +6,10 @@ LL | assert!(foo());
|
= help: consider describing why the failing assert is problematic
= note: `-D clippy::missing-assert-message` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_assert_message)]`
error: assert without any message
- --> $DIR/missing_assert_message.rs:13:5
+ --> $DIR/missing_assert_message.rs:14:5
|
LL | assert_eq!(foo(), foo());
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | assert_eq!(foo(), foo());
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:14:5
+ --> $DIR/missing_assert_message.rs:16:5
|
LL | assert_ne!(foo(), foo());
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | assert_ne!(foo(), foo());
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:15:5
+ --> $DIR/missing_assert_message.rs:18:5
|
LL | debug_assert!(foo());
| ^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | debug_assert!(foo());
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:16:5
+ --> $DIR/missing_assert_message.rs:20:5
|
LL | debug_assert_eq!(foo(), foo());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | debug_assert_eq!(foo(), foo());
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:17:5
+ --> $DIR/missing_assert_message.rs:22:5
|
LL | debug_assert_ne!(foo(), foo());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | debug_assert_ne!(foo(), foo());
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:22:5
+ --> $DIR/missing_assert_message.rs:28:5
|
LL | assert!(bar!(true));
| ^^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | assert!(bar!(true));
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:23:5
+ --> $DIR/missing_assert_message.rs:30:5
|
LL | assert!(bar!(true, false));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | assert!(bar!(true, false));
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:24:5
+ --> $DIR/missing_assert_message.rs:32:5
|
LL | assert_eq!(bar!(true), foo());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | assert_eq!(bar!(true), foo());
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:25:5
+ --> $DIR/missing_assert_message.rs:34:5
|
LL | assert_ne!(bar!(true, true), bar!(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +81,7 @@ LL | assert_ne!(bar!(true, true), bar!(true));
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:30:5
+ --> $DIR/missing_assert_message.rs:40:5
|
LL | assert!(foo(),);
| ^^^^^^^^^^^^^^^
@@ -88,7 +89,7 @@ LL | assert!(foo(),);
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:31:5
+ --> $DIR/missing_assert_message.rs:42:5
|
LL | assert_eq!(foo(), foo(),);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL | assert_eq!(foo(), foo(),);
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:32:5
+ --> $DIR/missing_assert_message.rs:44:5
|
LL | assert_ne!(foo(), foo(),);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +105,7 @@ LL | assert_ne!(foo(), foo(),);
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:33:5
+ --> $DIR/missing_assert_message.rs:46:5
|
LL | debug_assert!(foo(),);
| ^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +113,7 @@ LL | debug_assert!(foo(),);
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:34:5
+ --> $DIR/missing_assert_message.rs:48:5
|
LL | debug_assert_eq!(foo(), foo(),);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,7 +121,7 @@ LL | debug_assert_eq!(foo(), foo(),);
= help: consider describing why the failing assert is problematic
error: assert without any message
- --> $DIR/missing_assert_message.rs:35:5
+ --> $DIR/missing_assert_message.rs:50:5
|
LL | debug_assert_ne!(foo(), foo(),);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed
new file mode 100644
index 000000000..a96827259
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed
@@ -0,0 +1,121 @@
+#![allow(unused)]
+#![warn(clippy::missing_asserts_for_indexing)]
+
+// ok
+fn sum_with_assert(v: &[u8]) -> u8 {
+ assert!(v.len() > 4);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+// ok
+fn sum_with_assert_other_way(v: &[u8]) -> u8 {
+ assert!(5 <= v.len());
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+// ok
+fn sum_with_assert_ge(v: &[u8]) -> u8 {
+ assert!(v.len() >= 5);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+// ok
+fn sum_with_assert_ge_other_way(v: &[u8]) -> u8 {
+ assert!(4 < v.len());
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+fn sum_with_assert_lt(v: &[u8]) -> u8 {
+ assert!(v.len() > 4);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+fn sum_with_assert_le(v: &[u8]) -> u8 {
+ assert!(v.len() > 4);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+fn sum_with_incorrect_assert_len(v: &[u8]) -> u8 {
+ assert!(v.len() > 4);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+fn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 {
+ assert!(v.len() > 4);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+// ok, don't lint for single array access
+fn single_access(v: &[u8]) -> u8 {
+ v[0]
+}
+
+// ok
+fn subslice_ok(v: &[u8]) {
+ assert!(v.len() > 3);
+ let _ = v[0];
+ let _ = v[1..4];
+}
+
+fn subslice_bad(v: &[u8]) {
+ assert!(v.len() > 3);
+ let _ = v[0];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v[1..4];
+}
+
+// ok
+fn subslice_inclusive_ok(v: &[u8]) {
+ assert!(v.len() > 4);
+ let _ = v[0];
+ let _ = v[1..=4];
+}
+
+fn subslice_inclusive_bad(v: &[u8]) {
+ assert!(v.len() > 4);
+ let _ = v[0];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v[1..=4];
+}
+
+fn index_different_slices_ok(v1: &[u8], v2: &[u8]) {
+ assert!(v1.len() > 12);
+ assert!(v2.len() > 15);
+ let _ = v1[0] + v1[12];
+ let _ = v2[5] + v2[15];
+}
+
+fn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) {
+ assert!(v1.len() > 12);
+ assert!(v2.len() > 15);
+ let _ = v1[0] + v1[12];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v2[5] + v2[15];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+fn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) {
+ assert!(v1.len() > 12);
+ assert!(v2.len() > 15);
+ let _ = v1[0] + v1[12];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v2[5] + v2[15];
+}
+
+fn side_effect() -> &'static [u8] {
+ &[]
+}
+
+fn index_side_effect_expr() {
+ let _ = side_effect()[0] + side_effect()[1];
+}
+
+// ok, single access for different slices
+fn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) {
+ let _ = v1[0] + v2[1];
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs
new file mode 100644
index 000000000..0b4b883ac
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs
@@ -0,0 +1,121 @@
+#![allow(unused)]
+#![warn(clippy::missing_asserts_for_indexing)]
+
+// ok
+fn sum_with_assert(v: &[u8]) -> u8 {
+ assert!(v.len() > 4);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+// ok
+fn sum_with_assert_other_way(v: &[u8]) -> u8 {
+ assert!(5 <= v.len());
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+// ok
+fn sum_with_assert_ge(v: &[u8]) -> u8 {
+ assert!(v.len() >= 5);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+// ok
+fn sum_with_assert_ge_other_way(v: &[u8]) -> u8 {
+ assert!(4 < v.len());
+ v[0] + v[1] + v[2] + v[3] + v[4]
+}
+
+fn sum_with_assert_lt(v: &[u8]) -> u8 {
+ assert!(v.len() < 5);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+fn sum_with_assert_le(v: &[u8]) -> u8 {
+ assert!(v.len() <= 5);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+fn sum_with_incorrect_assert_len(v: &[u8]) -> u8 {
+ assert!(v.len() > 3);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+fn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 {
+ assert!(v.len() >= 4);
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+
+// ok, don't lint for single array access
+fn single_access(v: &[u8]) -> u8 {
+ v[0]
+}
+
+// ok
+fn subslice_ok(v: &[u8]) {
+ assert!(v.len() > 3);
+ let _ = v[0];
+ let _ = v[1..4];
+}
+
+fn subslice_bad(v: &[u8]) {
+ assert!(v.len() >= 3);
+ let _ = v[0];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v[1..4];
+}
+
+// ok
+fn subslice_inclusive_ok(v: &[u8]) {
+ assert!(v.len() > 4);
+ let _ = v[0];
+ let _ = v[1..=4];
+}
+
+fn subslice_inclusive_bad(v: &[u8]) {
+ assert!(v.len() >= 4);
+ let _ = v[0];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v[1..=4];
+}
+
+fn index_different_slices_ok(v1: &[u8], v2: &[u8]) {
+ assert!(v1.len() > 12);
+ assert!(v2.len() > 15);
+ let _ = v1[0] + v1[12];
+ let _ = v2[5] + v2[15];
+}
+
+fn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) {
+ assert!(v1.len() >= 12);
+ assert!(v2.len() >= 15);
+ let _ = v1[0] + v1[12];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v2[5] + v2[15];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+}
+fn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) {
+ assert!(v1.len() >= 12);
+ assert!(v2.len() > 15);
+ let _ = v1[0] + v1[12];
+ //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+ let _ = v2[5] + v2[15];
+}
+
+fn side_effect() -> &'static [u8] {
+ &[]
+}
+
+fn index_side_effect_expr() {
+ let _ = side_effect()[0] + side_effect()[1];
+}
+
+// ok, single access for different slices
+fn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) {
+ let _ = v1[0] + v2[1];
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr
new file mode 100644
index 000000000..a3e66d795
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr
@@ -0,0 +1,253 @@
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:30:5
+ |
+LL | assert!(v.len() < 5);
+ | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)`
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:30:5
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:30:12
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:30:19
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:30:26
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:30:33
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+ = note: asserting the length before indexing will elide bounds checks
+ = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]`
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:36:5
+ |
+LL | assert!(v.len() <= 5);
+ | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)`
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:36:5
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:36:12
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:36:19
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:36:26
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:36:33
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:42:5
+ |
+LL | assert!(v.len() > 3);
+ | -------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)`
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:42:5
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:42:12
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:42:19
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:42:26
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:42:33
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:48:5
+ |
+LL | assert!(v.len() >= 4);
+ | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)`
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:48:5
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:48:12
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:48:19
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:48:26
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:48:33
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:66:13
+ |
+LL | assert!(v.len() >= 3);
+ | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 3)`
+LL | let _ = v[0];
+ | _____________^
+LL | |
+LL | | let _ = v[1..4];
+ | |___________________^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:66:13
+ |
+LL | let _ = v[0];
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:68:13
+ |
+LL | let _ = v[1..4];
+ | ^^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:80:13
+ |
+LL | assert!(v.len() >= 4);
+ | --------------------- help: provide the highest index that is indexed with: `assert!(v.len() > 4)`
+LL | let _ = v[0];
+ | _____________^
+LL | |
+LL | | let _ = v[1..=4];
+ | |____________________^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:80:13
+ |
+LL | let _ = v[0];
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:82:13
+ |
+LL | let _ = v[1..=4];
+ | ^^^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:95:13
+ |
+LL | assert!(v1.len() >= 12);
+ | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)`
+LL | assert!(v2.len() >= 15);
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^^^^^^^^^^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:95:13
+ |
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:95:21
+ |
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:97:13
+ |
+LL | assert!(v2.len() >= 15);
+ | ----------------------- help: provide the highest index that is indexed with: `assert!(v2.len() > 15)`
+...
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^^^^^^^^^^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:97:13
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:97:21
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+ --> $DIR/missing_asserts_for_indexing.rs:103:13
+ |
+LL | assert!(v1.len() >= 12);
+ | ----------------------- help: provide the highest index that is indexed with: `assert!(v1.len() > 12)`
+LL | assert!(v2.len() > 15);
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^^^^^^^^^^
+ |
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:103:13
+ |
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing.rs:103:21
+ |
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: aborting due to 9 previous errors
+
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs
new file mode 100644
index 000000000..4346ed892
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.rs
@@ -0,0 +1,49 @@
+#![allow(unused)]
+#![warn(clippy::missing_asserts_for_indexing)]
+
+fn sum(v: &[u8]) -> u8 {
+ v[0] + v[1] + v[2] + v[3] + v[4]
+ //~^ ERROR: indexing into a slice multiple times without an `assert`
+}
+
+fn subslice(v: &[u8]) {
+ let _ = v[0];
+ //~^ ERROR: indexing into a slice multiple times without an `assert`
+ let _ = v[1..4];
+}
+
+fn variables(v: &[u8]) -> u8 {
+ let a = v[0];
+ //~^ ERROR: indexing into a slice multiple times without an `assert`
+ let b = v[1];
+ let c = v[2];
+ a + b + c
+}
+
+fn index_different_slices(v1: &[u8], v2: &[u8]) {
+ let _ = v1[0] + v1[12];
+ let _ = v2[5] + v2[15];
+}
+
+fn index_different_slices2(v1: &[u8], v2: &[u8]) {
+ assert!(v1.len() > 12);
+ let _ = v1[0] + v1[12];
+ let _ = v2[5] + v2[15];
+}
+
+struct Foo<'a> {
+ v: &'a [u8],
+ v2: &'a [u8],
+}
+
+fn index_struct_field(f: &Foo<'_>) {
+ let _ = f.v[0] + f.v[1];
+ //~^ ERROR: indexing into a slice multiple times without an `assert`
+}
+
+fn index_struct_different_fields(f: &Foo<'_>) {
+ // ok, different fields
+ let _ = f.v[0] + f.v2[1];
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr
new file mode 100644
index 000000000..12c9eed5d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing_unfixable.stderr
@@ -0,0 +1,164 @@
+error: indexing into a slice multiple times without an `assert`
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:5:5
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider asserting the length before indexing: `assert!(v.len() > 4);`
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:5:5
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:5:12
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:5:19
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:5:26
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:5:33
+ |
+LL | v[0] + v[1] + v[2] + v[3] + v[4]
+ | ^^^^
+ = note: asserting the length before indexing will elide bounds checks
+ = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]`
+
+error: indexing into a slice multiple times without an `assert`
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:10:13
+ |
+LL | let _ = v[0];
+ | _____________^
+LL | |
+LL | | let _ = v[1..4];
+ | |___________________^
+ |
+ = help: consider asserting the length before indexing: `assert!(v.len() > 3);`
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:10:13
+ |
+LL | let _ = v[0];
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:12:13
+ |
+LL | let _ = v[1..4];
+ | ^^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times without an `assert`
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:16:13
+ |
+LL | let a = v[0];
+ | _____________^
+LL | |
+LL | | let b = v[1];
+LL | | let c = v[2];
+ | |________________^
+ |
+ = help: consider asserting the length before indexing: `assert!(v.len() > 2);`
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:16:13
+ |
+LL | let a = v[0];
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:18:13
+ |
+LL | let b = v[1];
+ | ^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:19:13
+ |
+LL | let c = v[2];
+ | ^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times without an `assert`
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:24:13
+ |
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider asserting the length before indexing: `assert!(v1.len() > 12);`
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:24:13
+ |
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:24:21
+ |
+LL | let _ = v1[0] + v1[12];
+ | ^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times without an `assert`
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:25:13
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider asserting the length before indexing: `assert!(v2.len() > 15);`
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:25:13
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:25:21
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times without an `assert`
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:31:13
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider asserting the length before indexing: `assert!(v2.len() > 15);`
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:31:13
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:31:21
+ |
+LL | let _ = v2[5] + v2[15];
+ | ^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times without an `assert`
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:40:13
+ |
+LL | let _ = f.v[0] + f.v[1];
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: consider asserting the length before indexing: `assert!(f.v.len() > 1);`
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:40:13
+ |
+LL | let _ = f.v[0] + f.v[1];
+ | ^^^^^^
+note: slice indexed here
+ --> $DIR/missing_asserts_for_indexing_unfixable.rs:40:22
+ |
+LL | let _ = f.v[0] + f.v[1];
+ | ^^^^^^
+ = note: asserting the length before indexing will elide bounds checks
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
index 06e053524..d026e0096 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
@@ -3,7 +3,7 @@
//! The .stderr output of this test should be empty. Otherwise it's a bug somewhere.
//@aux-build:helper.rs
-//@aux-build:../auxiliary/proc_macros.rs:proc-macro
+//@aux-build:../auxiliary/proc_macros.rs
#![warn(clippy::missing_const_for_fn)]
#![feature(start)]
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
index 3aaee67e1..6985c2d0c 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
@@ -12,37 +12,45 @@ struct Game {
impl Game {
// Could be const
pub fn new() -> Self {
+ //~^ ERROR: this could be a `const fn`
+ //~| NOTE: `-D clippy::missing-const-for-fn` implied by `-D warnings`
Self { guess: 42 }
}
fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
+ //~^ ERROR: this could be a `const fn`
b
}
}
// Could be const
fn one() -> i32 {
+ //~^ ERROR: this could be a `const fn`
1
}
// Could also be const
fn two() -> i32 {
+ //~^ ERROR: this could be a `const fn`
let abc = 2;
abc
}
// Could be const (since Rust 1.39)
fn string() -> String {
+ //~^ ERROR: this could be a `const fn`
String::new()
}
// Could be const
unsafe fn four() -> i32 {
+ //~^ ERROR: this could be a `const fn`
4
}
// Could also be const
fn generic<T>(t: T) -> T {
+ //~^ ERROR: this could be a `const fn`
t
}
@@ -51,6 +59,7 @@ fn sub(x: u32) -> usize {
}
fn generic_arr<T: Copy>(t: [T; 1]) -> T {
+ //~^ ERROR: this could be a `const fn`
t[0]
}
@@ -64,6 +73,7 @@ mod with_drop {
impl B {
// This can be const, because `a` is passed by reference
pub fn b(self, a: &A) -> B {
+ //~^ ERROR: this could be a `const fn`
B
}
}
@@ -73,6 +83,7 @@ mod with_drop {
mod const_fn_stabilized_before_msrv {
// This could be const because `u8::is_ascii_digit` is a stable const function in 1.47.
fn const_fn_stabilized_before_msrv(byte: u8) {
+ //~^ ERROR: this could be a `const fn`
byte.is_ascii_digit();
}
}
@@ -84,6 +95,7 @@ fn msrv_1_45() -> i32 {
#[clippy::msrv = "1.46"]
fn msrv_1_46() -> i32 {
+ //~^ ERROR: this could be a `const fn`
46
}
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
index 66cf4e315..b3a8ad8fa 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
@@ -2,89 +2,102 @@ error: this could be a `const fn`
--> $DIR/could_be_const.rs:14:5
|
LL | / pub fn new() -> Self {
+LL | |
+LL | |
LL | | Self { guess: 42 }
LL | | }
| |_____^
|
= note: `-D clippy::missing-const-for-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_fn)]`
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:18:5
+ --> $DIR/could_be_const.rs:20:5
|
LL | / fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
+LL | |
LL | | b
LL | | }
| |_____^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:24:1
+ --> $DIR/could_be_const.rs:27:1
|
LL | / fn one() -> i32 {
+LL | |
LL | | 1
LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:29:1
+ --> $DIR/could_be_const.rs:33:1
|
LL | / fn two() -> i32 {
+LL | |
LL | | let abc = 2;
LL | | abc
LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:35:1
+ --> $DIR/could_be_const.rs:40:1
|
LL | / fn string() -> String {
+LL | |
LL | | String::new()
LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:40:1
+ --> $DIR/could_be_const.rs:46:1
|
LL | / unsafe fn four() -> i32 {
+LL | |
LL | | 4
LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:45:1
+ --> $DIR/could_be_const.rs:52:1
|
LL | / fn generic<T>(t: T) -> T {
+LL | |
LL | | t
LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:53:1
+ --> $DIR/could_be_const.rs:61:1
|
LL | / fn generic_arr<T: Copy>(t: [T; 1]) -> T {
+LL | |
LL | | t[0]
LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:66:9
+ --> $DIR/could_be_const.rs:75:9
|
LL | / pub fn b(self, a: &A) -> B {
+LL | |
LL | | B
LL | | }
| |_________^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:75:5
+ --> $DIR/could_be_const.rs:85:5
|
LL | / fn const_fn_stabilized_before_msrv(byte: u8) {
+LL | |
LL | | byte.is_ascii_digit();
LL | | }
| |_____^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:86:1
+ --> $DIR/could_be_const.rs:97:1
|
LL | / fn msrv_1_46() -> i32 {
+LL | |
LL | | 46
LL | | }
| |_^
diff --git a/src/tools/clippy/tests/ui/missing_doc.rs b/src/tools/clippy/tests/ui/missing_doc.rs
index 83ebf09c8..9bfad3b96 100644
--- a/src/tools/clippy/tests/ui/missing_doc.rs
+++ b/src/tools/clippy/tests/ui/missing_doc.rs
@@ -1,5 +1,5 @@
//@needs-asm-support
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![warn(clippy::missing_docs_in_private_items)]
// When denying at the crate level, be sure to not get random warnings from the
diff --git a/src/tools/clippy/tests/ui/missing_doc.stderr b/src/tools/clippy/tests/ui/missing_doc.stderr
index 4e8a49bf1..1d8007fa5 100644
--- a/src/tools/clippy/tests/ui/missing_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc.stderr
@@ -5,6 +5,7 @@ LL | type Typedef = String;
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]`
error: missing documentation for a module
--> $DIR/missing_doc.rs:19:1
diff --git a/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs b/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs
index 51fd57df8..73584ac8c 100644
--- a/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs
+++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.rs
@@ -1,3 +1,5 @@
#![warn(clippy::missing_docs_in_private_items)]
+//~^ ERROR: missing documentation for the crate
+//~| NOTE: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
fn main() {}
diff --git a/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
index 19516bf5f..c684bc8e7 100644
--- a/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc_crate_missing.stderr
@@ -3,10 +3,13 @@ error: missing documentation for the crate
|
LL | / #![warn(clippy::missing_docs_in_private_items)]
LL | |
+LL | |
+LL | |
LL | | fn main() {}
| |____________^
|
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.rs b/src/tools/clippy/tests/ui/missing_doc_impl.rs
index 2d45132f9..520ddbe16 100644
--- a/src/tools/clippy/tests/ui/missing_doc_impl.rs
+++ b/src/tools/clippy/tests/ui/missing_doc_impl.rs
@@ -1,4 +1,4 @@
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![warn(clippy::missing_docs_in_private_items)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr
index 111d65469..e303b7b7d 100644
--- a/src/tools/clippy/tests/ui/missing_doc_impl.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr
@@ -8,6 +8,7 @@ LL | | }
| |_^
|
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]`
error: missing documentation for a struct field
--> $DIR/missing_doc_impl.rs:14:5
diff --git a/src/tools/clippy/tests/ui/missing_fields_in_debug.rs b/src/tools/clippy/tests/ui/missing_fields_in_debug.rs
index c156d394e..e91e8ab7f 100644
--- a/src/tools/clippy/tests/ui/missing_fields_in_debug.rs
+++ b/src/tools/clippy/tests/ui/missing_fields_in_debug.rs
@@ -11,6 +11,7 @@ struct NamedStruct1Ignored {
}
impl fmt::Debug for NamedStruct1Ignored {
+ //~^ ERROR: manual `Debug` impl does not include all fields
// unused field: hidden
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
@@ -29,6 +30,7 @@ struct NamedStructMultipleIgnored {
}
impl fmt::Debug for NamedStructMultipleIgnored {
+ //~^ ERROR: manual `Debug` impl does not include all fields
// unused fields: hidden, hidden2, hidden4
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
@@ -90,6 +92,7 @@ struct MultiExprDebugImpl {
// ok
impl fmt::Debug for MultiExprDebugImpl {
+ //~^ ERROR: manual `Debug` impl does not include all fields
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut f = formatter.debug_struct("MultiExprDebugImpl");
f.field("a", &self.a);
diff --git a/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr b/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr
index ef9d02aba..481b2c632 100644
--- a/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr
+++ b/src/tools/clippy/tests/ui/missing_fields_in_debug.stderr
@@ -2,9 +2,9 @@ error: manual `Debug` impl does not include all fields
--> $DIR/missing_fields_in_debug.rs:13:1
|
LL | / impl fmt::Debug for NamedStruct1Ignored {
+LL | |
LL | | // unused field: hidden
LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-LL | | formatter
... |
LL | | }
LL | | }
@@ -18,31 +18,32 @@ LL | hidden: u32,
= help: consider including all fields in this `Debug` impl
= help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields
= note: `-D clippy::missing-fields-in-debug` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_fields_in_debug)]`
error: manual `Debug` impl does not include all fields
- --> $DIR/missing_fields_in_debug.rs:31:1
+ --> $DIR/missing_fields_in_debug.rs:32:1
|
LL | / impl fmt::Debug for NamedStructMultipleIgnored {
+LL | |
LL | | // unused fields: hidden, hidden2, hidden4
LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-LL | | formatter
... |
LL | | }
LL | | }
| |_^
|
note: this field is unused
- --> $DIR/missing_fields_in_debug.rs:25:5
+ --> $DIR/missing_fields_in_debug.rs:26:5
|
LL | hidden: u32,
| ^^^^^^^^^^^
note: this field is unused
- --> $DIR/missing_fields_in_debug.rs:26:5
+ --> $DIR/missing_fields_in_debug.rs:27:5
|
LL | hidden2: String,
| ^^^^^^^^^^^^^^^
note: this field is unused
- --> $DIR/missing_fields_in_debug.rs:28:5
+ --> $DIR/missing_fields_in_debug.rs:29:5
|
LL | hidden4: ((((u8), u16), u32), u64),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,19 +51,19 @@ LL | hidden4: ((((u8), u16), u32), u64),
= help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields
error: manual `Debug` impl does not include all fields
- --> $DIR/missing_fields_in_debug.rs:92:1
+ --> $DIR/missing_fields_in_debug.rs:94:1
|
LL | / impl fmt::Debug for MultiExprDebugImpl {
+LL | |
LL | | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
LL | | let mut f = formatter.debug_struct("MultiExprDebugImpl");
-LL | | f.field("a", &self.a);
-LL | | f.finish()
+... |
LL | | }
LL | | }
| |_^
|
note: this field is unused
- --> $DIR/missing_fields_in_debug.rs:88:5
+ --> $DIR/missing_fields_in_debug.rs:90:5
|
LL | b: String,
| ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/missing_inline.rs b/src/tools/clippy/tests/ui/missing_inline.rs
index 07f8e3888..dca85b94d 100644
--- a/src/tools/clippy/tests/ui/missing_inline.rs
+++ b/src/tools/clippy/tests/ui/missing_inline.rs
@@ -16,7 +16,10 @@ mod module {} // ok
pub mod pub_module {} // ok
fn foo() {}
-pub fn pub_foo() {} // missing #[inline]
+// missing #[inline]
+pub fn pub_foo() {}
+//~^ ERROR: missing `#[inline]` for a function
+//~| NOTE: `-D clippy::missing-inline-in-public-items` implied by `-D warnings`
#[inline]
pub fn pub_foo_inline() {} // ok
#[inline(always)]
@@ -32,7 +35,9 @@ trait Bar {
pub trait PubBar {
fn PubBar_a(); // ok
- fn PubBar_b() {} // missing #[inline]
+ // missing #[inline]
+ fn PubBar_b() {}
+ //~^ ERROR: missing `#[inline]` for a default trait method
#[inline]
fn PubBar_c() {} // ok
}
@@ -46,9 +51,15 @@ impl PubBar for Foo {
// all of these need inline because PubFoo is exported
impl PubBar for PubFoo {
- fn PubBar_a() {} // missing #[inline]
- fn PubBar_b() {} // missing #[inline]
- fn PubBar_c() {} // missing #[inline]
+ // missing #[inline]
+ fn PubBar_a() {}
+ //~^ ERROR: missing `#[inline]` for a method
+ // missing #[inline]
+ fn PubBar_b() {}
+ //~^ ERROR: missing `#[inline]` for a method
+ // missing #[inline]
+ fn PubBar_c() {}
+ //~^ ERROR: missing `#[inline]` for a method
}
// do not need inline because Foo is not exported
@@ -58,7 +69,9 @@ impl Foo {
// need inline because PubFoo is exported
impl PubFoo {
- pub fn PubFooImpl() {} // missing #[inline]
+ // missing #[inline]
+ pub fn PubFooImpl() {}
+ //~^ ERROR: missing `#[inline]` for a method
}
// do not lint this since users cannot control the external code
diff --git a/src/tools/clippy/tests/ui/missing_inline.stderr b/src/tools/clippy/tests/ui/missing_inline.stderr
index 40b92b764..da2a2a7fe 100644
--- a/src/tools/clippy/tests/ui/missing_inline.stderr
+++ b/src/tools/clippy/tests/ui/missing_inline.stderr
@@ -1,39 +1,40 @@
error: missing `#[inline]` for a function
- --> $DIR/missing_inline.rs:19:1
+ --> $DIR/missing_inline.rs:20:1
|
-LL | pub fn pub_foo() {} // missing #[inline]
+LL | pub fn pub_foo() {}
| ^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::missing-inline-in-public-items` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_inline_in_public_items)]`
error: missing `#[inline]` for a default trait method
- --> $DIR/missing_inline.rs:35:5
+ --> $DIR/missing_inline.rs:39:5
|
-LL | fn PubBar_b() {} // missing #[inline]
+LL | fn PubBar_b() {}
| ^^^^^^^^^^^^^^^^
error: missing `#[inline]` for a method
- --> $DIR/missing_inline.rs:49:5
+ --> $DIR/missing_inline.rs:55:5
|
-LL | fn PubBar_a() {} // missing #[inline]
+LL | fn PubBar_a() {}
| ^^^^^^^^^^^^^^^^
error: missing `#[inline]` for a method
- --> $DIR/missing_inline.rs:50:5
+ --> $DIR/missing_inline.rs:58:5
|
-LL | fn PubBar_b() {} // missing #[inline]
+LL | fn PubBar_b() {}
| ^^^^^^^^^^^^^^^^
error: missing `#[inline]` for a method
- --> $DIR/missing_inline.rs:51:5
+ --> $DIR/missing_inline.rs:61:5
|
-LL | fn PubBar_c() {} // missing #[inline]
+LL | fn PubBar_c() {}
| ^^^^^^^^^^^^^^^^
error: missing `#[inline]` for a method
- --> $DIR/missing_inline.rs:61:5
+ --> $DIR/missing_inline.rs:73:5
|
-LL | pub fn PubFooImpl() {} // missing #[inline]
+LL | pub fn PubFooImpl() {}
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.stderr b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
index 3dbe2dfbd..efee48550 100644
--- a/src/tools/clippy/tests/ui/missing_panics_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
@@ -10,6 +10,7 @@ note: first possible panic found here
LL | result.unwrap()
| ^^^^^^^^^^^^^^^
= note: `-D clippy::missing-panics-doc` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_panics_doc)]`
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:19:1
diff --git a/src/tools/clippy/tests/ui/missing_spin_loop.fixed b/src/tools/clippy/tests/ui/missing_spin_loop.fixed
index a15298dc3..b6520d478 100644
--- a/src/tools/clippy/tests/ui/missing_spin_loop.fixed
+++ b/src/tools/clippy/tests/ui/missing_spin_loop.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::missing_spin_loop)]
#![allow(clippy::bool_comparison)]
#![allow(unused_braces)]
diff --git a/src/tools/clippy/tests/ui/missing_spin_loop.rs b/src/tools/clippy/tests/ui/missing_spin_loop.rs
index be74581ec..7b115c66a 100644
--- a/src/tools/clippy/tests/ui/missing_spin_loop.rs
+++ b/src/tools/clippy/tests/ui/missing_spin_loop.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::missing_spin_loop)]
#![allow(clippy::bool_comparison)]
#![allow(unused_braces)]
diff --git a/src/tools/clippy/tests/ui/missing_spin_loop.stderr b/src/tools/clippy/tests/ui/missing_spin_loop.stderr
index 5795c2c21..a84c19d59 100644
--- a/src/tools/clippy/tests/ui/missing_spin_loop.stderr
+++ b/src/tools/clippy/tests/ui/missing_spin_loop.stderr
@@ -1,37 +1,38 @@
error: busy-waiting loop should at least have a spin loop hint
- --> $DIR/missing_spin_loop.rs:11:37
+ --> $DIR/missing_spin_loop.rs:10:37
|
LL | while b.load(Ordering::Acquire) {}
| ^^ help: try: `{ std::hint::spin_loop() }`
|
= note: `-D clippy::missing-spin-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_spin_loop)]`
error: busy-waiting loop should at least have a spin loop hint
- --> $DIR/missing_spin_loop.rs:13:37
+ --> $DIR/missing_spin_loop.rs:12:37
|
LL | while !b.load(Ordering::SeqCst) {}
| ^^ help: try: `{ std::hint::spin_loop() }`
error: busy-waiting loop should at least have a spin loop hint
- --> $DIR/missing_spin_loop.rs:15:46
+ --> $DIR/missing_spin_loop.rs:14:46
|
LL | while b.load(Ordering::Acquire) == false {}
| ^^ help: try: `{ std::hint::spin_loop() }`
error: busy-waiting loop should at least have a spin loop hint
- --> $DIR/missing_spin_loop.rs:17:49
+ --> $DIR/missing_spin_loop.rs:16:49
|
LL | while { true == b.load(Ordering::Acquire) } {}
| ^^ help: try: `{ std::hint::spin_loop() }`
error: busy-waiting loop should at least have a spin loop hint
- --> $DIR/missing_spin_loop.rs:19:93
+ --> $DIR/missing_spin_loop.rs:18:93
|
LL | while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) {}
| ^^ help: try: `{ std::hint::spin_loop() }`
error: busy-waiting loop should at least have a spin loop hint
- --> $DIR/missing_spin_loop.rs:21:94
+ --> $DIR/missing_spin_loop.rs:20:94
|
LL | while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) {}
| ^^ help: try: `{ std::hint::spin_loop() }`
diff --git a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed
index 960e5c05f..497e0e243 100644
--- a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed
+++ b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::missing_spin_loop)]
#![feature(lang_items, start, libc)]
#![no_std]
diff --git a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs
index e532ca62d..1c85a9c58 100644
--- a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs
+++ b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::missing_spin_loop)]
#![feature(lang_items, start, libc)]
#![no_std]
diff --git a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr
index 3322a7aae..0b7be4616 100644
--- a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr
+++ b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.stderr
@@ -1,10 +1,11 @@
error: busy-waiting loop should at least have a spin loop hint
- --> $DIR/missing_spin_loop_no_std.rs:13:37
+ --> $DIR/missing_spin_loop_no_std.rs:12:37
|
LL | while b.load(Ordering::Acquire) {}
| ^^ help: try: `{ core::hint::spin_loop() }`
|
= note: `-D clippy::missing-spin-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_spin_loop)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/missing_trait_methods.rs b/src/tools/clippy/tests/ui/missing_trait_methods.rs
index 8df885919..1b09b717f 100644
--- a/src/tools/clippy/tests/ui/missing_trait_methods.rs
+++ b/src/tools/clippy/tests/ui/missing_trait_methods.rs
@@ -20,8 +20,10 @@ trait B {
struct Partial;
impl A for Partial {}
+//~^ ERROR: missing trait method provided by default: `provided`
impl B for Partial {
+ //~^ ERROR: missing trait method provided by default: `b`
fn required() {}
fn a(_: usize) -> usize {
diff --git a/src/tools/clippy/tests/ui/missing_trait_methods.stderr b/src/tools/clippy/tests/ui/missing_trait_methods.stderr
index 0c5205e19..3e20a51e0 100644
--- a/src/tools/clippy/tests/ui/missing_trait_methods.stderr
+++ b/src/tools/clippy/tests/ui/missing_trait_methods.stderr
@@ -10,9 +10,10 @@ help: implement the method
LL | fn provided() {}
| ^^^^^^^^^^^^^
= note: `-D clippy::missing-trait-methods` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::missing_trait_methods)]`
error: missing trait method provided by default: `b`
- --> $DIR/missing_trait_methods.rs:24:1
+ --> $DIR/missing_trait_methods.rs:25:1
|
LL | impl B for Partial {
| ^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
index 9c2ffcb02..861764a2a 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![allow(
dead_code,
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
index a0a1e96a7..4a15c335f 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![allow(
dead_code,
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
index ef8e6a33d..ecd73497a 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
@@ -1,5 +1,5 @@
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:17:18
+ --> $DIR/mistyped_literal_suffix.rs:16:18
|
LL | let fail14 = 2_32;
| ^^^^ help: did you mean to write: `2_i32`
@@ -7,91 +7,91 @@ LL | let fail14 = 2_32;
= note: `#[deny(clippy::mistyped_literal_suffixes)]` on by default
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:18:18
+ --> $DIR/mistyped_literal_suffix.rs:17:18
|
LL | let fail15 = 4_64;
| ^^^^ help: did you mean to write: `4_i64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:19:18
+ --> $DIR/mistyped_literal_suffix.rs:18:18
|
LL | let fail16 = 7_8; //
| ^^^ help: did you mean to write: `7_i8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:20:18
+ --> $DIR/mistyped_literal_suffix.rs:19:18
|
LL | let fail17 = 23_16; //
| ^^^^^ help: did you mean to write: `23_i16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:23:18
+ --> $DIR/mistyped_literal_suffix.rs:22:18
|
LL | let fail20 = 2__8; //
| ^^^^ help: did you mean to write: `2_i8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:24:18
+ --> $DIR/mistyped_literal_suffix.rs:23:18
|
LL | let fail21 = 4___16; //
| ^^^^^^ help: did you mean to write: `4_i16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:27:18
+ --> $DIR/mistyped_literal_suffix.rs:26:18
|
LL | let fail25 = 1E2_32;
| ^^^^^^ help: did you mean to write: `1E2_f32`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:28:18
+ --> $DIR/mistyped_literal_suffix.rs:27:18
|
LL | let fail26 = 43E7_64;
| ^^^^^^^ help: did you mean to write: `43E7_f64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:29:18
+ --> $DIR/mistyped_literal_suffix.rs:28:18
|
LL | let fail27 = 243E17_32;
| ^^^^^^^^^ help: did you mean to write: `243E17_f32`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:30:18
+ --> $DIR/mistyped_literal_suffix.rs:29:18
|
LL | let fail28 = 241251235E723_64;
| ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:34:18
+ --> $DIR/mistyped_literal_suffix.rs:33:18
|
LL | let fail30 = 127_8; // should be i8
| ^^^^^ help: did you mean to write: `127_i8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:35:18
+ --> $DIR/mistyped_literal_suffix.rs:34:18
|
LL | let fail31 = 240_8; // should be u8
| ^^^^^ help: did you mean to write: `240_u8`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:37:18
+ --> $DIR/mistyped_literal_suffix.rs:36:18
|
LL | let fail33 = 0x1234_16;
| ^^^^^^^^^ help: did you mean to write: `0x1234_i16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:38:18
+ --> $DIR/mistyped_literal_suffix.rs:37:18
|
LL | let fail34 = 0xABCD_16;
| ^^^^^^^^^ help: did you mean to write: `0xABCD_u16`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:40:18
+ --> $DIR/mistyped_literal_suffix.rs:39:18
|
LL | let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64`
error: mistyped literal suffix
- --> $DIR/mistyped_literal_suffix.rs:46:13
+ --> $DIR/mistyped_literal_suffix.rs:45:13
|
LL | let _ = 1.12345E1_32;
| ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32`
diff --git a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs
index 6efc7657e..241536abd 100644
--- a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.rs
@@ -12,9 +12,11 @@ fn main() {
x = 1;
1
} + x;
+ //~^ ERROR: unsequenced read of `x`
// Example from iss#277
x += {
+ //~^ ERROR: unsequenced read of `x`
x = 20;
2
};
@@ -28,6 +30,7 @@ fn main() {
let base = Foo { a: 4, b: 5 };
let foo = Foo {
a: x,
+ //~^ ERROR: unsequenced read of `x`
..{
x = 6;
base
@@ -37,6 +40,7 @@ fn main() {
let closure = || {
let mut x = 0;
x += {
+ //~^ ERROR: unsequenced read of `x`
x = 20;
2
};
diff --git a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr
index 8cc68b0ac..3dad98815 100644
--- a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr
+++ b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr
@@ -10,39 +10,40 @@ note: whether read occurs before this write depends on evaluation order
LL | x = 1;
| ^^^^^
= note: `-D clippy::mixed-read-write-in-expression` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mixed_read_write_in_expression)]`
error: unsequenced read of `x`
- --> $DIR/mixed_read_write_in_expression.rs:17:5
+ --> $DIR/mixed_read_write_in_expression.rs:18:5
|
LL | x += {
| ^
|
note: whether read occurs before this write depends on evaluation order
- --> $DIR/mixed_read_write_in_expression.rs:18:9
+ --> $DIR/mixed_read_write_in_expression.rs:20:9
|
LL | x = 20;
| ^^^^^^
error: unsequenced read of `x`
- --> $DIR/mixed_read_write_in_expression.rs:30:12
+ --> $DIR/mixed_read_write_in_expression.rs:32:12
|
LL | a: x,
| ^
|
note: whether read occurs before this write depends on evaluation order
- --> $DIR/mixed_read_write_in_expression.rs:32:13
+ --> $DIR/mixed_read_write_in_expression.rs:35:13
|
LL | x = 6;
| ^^^^^
error: unsequenced read of `x`
- --> $DIR/mixed_read_write_in_expression.rs:39:9
+ --> $DIR/mixed_read_write_in_expression.rs:42:9
|
LL | x += {
| ^
|
note: whether read occurs before this write depends on evaluation order
- --> $DIR/mixed_read_write_in_expression.rs:40:13
+ --> $DIR/mixed_read_write_in_expression.rs:44:13
|
LL | x = 20;
| ^^^^^^
diff --git a/src/tools/clippy/tests/ui/module_inception.rs b/src/tools/clippy/tests/ui/module_inception.rs
index 802c3ec39..ad46e0c29 100644
--- a/src/tools/clippy/tests/ui/module_inception.rs
+++ b/src/tools/clippy/tests/ui/module_inception.rs
@@ -3,11 +3,14 @@
pub mod foo2 {
pub mod bar2 {
pub mod bar2 {
+ //~^ ERROR: module has the same name as its containing module
+ //~| NOTE: `-D clippy::module-inception` implied by `-D warnings`
pub mod foo2 {}
}
pub mod foo2 {}
}
pub mod foo2 {
+ //~^ ERROR: module has the same name as its containing module
pub mod bar2 {}
}
}
@@ -15,11 +18,13 @@ pub mod foo2 {
mod foo {
mod bar {
mod bar {
+ //~^ ERROR: module has the same name as its containing module
mod foo {}
}
mod foo {}
}
mod foo {
+ //~^ ERROR: module has the same name as its containing module
mod bar {}
}
}
diff --git a/src/tools/clippy/tests/ui/module_inception.stderr b/src/tools/clippy/tests/ui/module_inception.stderr
index ebb8e296f..d5856614f 100644
--- a/src/tools/clippy/tests/ui/module_inception.stderr
+++ b/src/tools/clippy/tests/ui/module_inception.stderr
@@ -2,32 +2,38 @@ error: module has the same name as its containing module
--> $DIR/module_inception.rs:5:9
|
LL | / pub mod bar2 {
+LL | |
+LL | |
LL | | pub mod foo2 {}
LL | | }
| |_________^
|
= note: `-D clippy::module-inception` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::module_inception)]`
error: module has the same name as its containing module
- --> $DIR/module_inception.rs:10:5
+ --> $DIR/module_inception.rs:12:5
|
LL | / pub mod foo2 {
+LL | |
LL | | pub mod bar2 {}
LL | | }
| |_____^
error: module has the same name as its containing module
- --> $DIR/module_inception.rs:17:9
+ --> $DIR/module_inception.rs:20:9
|
LL | / mod bar {
+LL | |
LL | | mod foo {}
LL | | }
| |_________^
error: module has the same name as its containing module
- --> $DIR/module_inception.rs:22:5
+ --> $DIR/module_inception.rs:26:5
|
LL | / mod foo {
+LL | |
LL | | mod bar {}
LL | | }
| |_____^
diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.rs b/src/tools/clippy/tests/ui/module_name_repetitions.rs
index fb2c76123..a6cf03890 100644
--- a/src/tools/clippy/tests/ui/module_name_repetitions.rs
+++ b/src/tools/clippy/tests/ui/module_name_repetitions.rs
@@ -6,10 +6,16 @@
mod foo {
pub fn foo() {}
pub fn foo_bar() {}
+ //~^ ERROR: item name starts with its containing module's name
+ //~| NOTE: `-D clippy::module-name-repetitions` implied by `-D warnings`
pub fn bar_foo() {}
+ //~^ ERROR: item name ends with its containing module's name
pub struct FooCake;
+ //~^ ERROR: item name starts with its containing module's name
pub enum CakeFoo {}
+ //~^ ERROR: item name ends with its containing module's name
pub struct Foo7Bar;
+ //~^ ERROR: item name starts with its containing module's name
// Should not warn
pub struct Foobar;
diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.stderr b/src/tools/clippy/tests/ui/module_name_repetitions.stderr
index 277801194..1854d3a85 100644
--- a/src/tools/clippy/tests/ui/module_name_repetitions.stderr
+++ b/src/tools/clippy/tests/ui/module_name_repetitions.stderr
@@ -5,27 +5,28 @@ LL | pub fn foo_bar() {}
| ^^^^^^^
|
= note: `-D clippy::module-name-repetitions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]`
error: item name ends with its containing module's name
- --> $DIR/module_name_repetitions.rs:9:12
+ --> $DIR/module_name_repetitions.rs:11:12
|
LL | pub fn bar_foo() {}
| ^^^^^^^
error: item name starts with its containing module's name
- --> $DIR/module_name_repetitions.rs:10:16
+ --> $DIR/module_name_repetitions.rs:13:16
|
LL | pub struct FooCake;
| ^^^^^^^
error: item name ends with its containing module's name
- --> $DIR/module_name_repetitions.rs:11:14
+ --> $DIR/module_name_repetitions.rs:15:14
|
LL | pub enum CakeFoo {}
| ^^^^^^^
error: item name starts with its containing module's name
- --> $DIR/module_name_repetitions.rs:12:16
+ --> $DIR/module_name_repetitions.rs:17:16
|
LL | pub struct Foo7Bar;
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_float.rs b/src/tools/clippy/tests/ui/modulo_arithmetic_float.rs
index b1861f07c..37895ea09 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_float.rs
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_float.rs
@@ -4,22 +4,42 @@
fn main() {
// Lint when both sides are const and of the opposite sign
-1.6 % 2.1;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1.600 %
+ //~| NOTE: double check for expected result especially when interoperating with differ
1.6 % -2.1;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1.600 %
+ //~| NOTE: double check for expected result especially when interoperating with differ
(1.1 - 2.3) % (1.1 + 2.3);
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1.200 %
+ //~| NOTE: double check for expected result especially when interoperating with differ
(1.1 + 2.3) % (1.1 - 2.3);
+ //~^ ERROR: you are using modulo operator on constants with different signs: `3.400 %
+ //~| NOTE: double check for expected result especially when interoperating with differ
// Lint on floating point numbers
let a_f32: f32 = -1.6;
let mut b_f32: f32 = 2.1;
a_f32 % b_f32;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_f32 % a_f32;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_f32 %= a_f32;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a_f64: f64 = -1.6;
let mut b_f64: f64 = 2.1;
a_f64 % b_f64;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_f64 % a_f64;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_f64 %= a_f64;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
// No lint when both sides are const and of the same sign
1.6 % 2.1;
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr
index 36106de31..46c8d0288 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr
@@ -6,9 +6,10 @@ LL | -1.6 % 2.1;
|
= note: double check for expected result especially when interoperating with different languages
= note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`
error: you are using modulo operator on constants with different signs: `1.600 % -2.100`
- --> $DIR/modulo_arithmetic_float.rs:7:5
+ --> $DIR/modulo_arithmetic_float.rs:9:5
|
LL | 1.6 % -2.1;
| ^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | 1.6 % -2.1;
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on constants with different signs: `-1.200 % 3.400`
- --> $DIR/modulo_arithmetic_float.rs:8:5
+ --> $DIR/modulo_arithmetic_float.rs:12:5
|
LL | (1.1 - 2.3) % (1.1 + 2.3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | (1.1 - 2.3) % (1.1 + 2.3);
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on constants with different signs: `3.400 % -1.200`
- --> $DIR/modulo_arithmetic_float.rs:9:5
+ --> $DIR/modulo_arithmetic_float.rs:15:5
|
LL | (1.1 + 2.3) % (1.1 - 2.3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | (1.1 + 2.3) % (1.1 - 2.3);
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_float.rs:14:5
+ --> $DIR/modulo_arithmetic_float.rs:22:5
|
LL | a_f32 % b_f32;
| ^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | a_f32 % b_f32;
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_float.rs:15:5
+ --> $DIR/modulo_arithmetic_float.rs:25:5
|
LL | b_f32 % a_f32;
| ^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | b_f32 % a_f32;
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_float.rs:16:5
+ --> $DIR/modulo_arithmetic_float.rs:28:5
|
LL | b_f32 %= a_f32;
| ^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | b_f32 %= a_f32;
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_float.rs:20:5
+ --> $DIR/modulo_arithmetic_float.rs:34:5
|
LL | a_f64 % b_f64;
| ^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | a_f64 % b_f64;
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_float.rs:21:5
+ --> $DIR/modulo_arithmetic_float.rs:37:5
|
LL | b_f64 % a_f64;
| ^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | b_f64 % a_f64;
= note: double check for expected result especially when interoperating with different languages
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_float.rs:22:5
+ --> $DIR/modulo_arithmetic_float.rs:40:5
|
LL | b_f64 %= a_f64;
| ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs
index fc1acc39e..4dbed2402 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs
@@ -6,43 +6,77 @@ fn main() {
let a = -1;
let mut b = 2;
a % b;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b % a;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b %= a;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a_i8: i8 = 1;
let mut b_i8: i8 = 2;
a_i8 % b_i8;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_i8 %= a_i8;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a_i16: i16 = 1;
let mut b_i16: i16 = 2;
a_i16 % b_i16;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_i16 %= a_i16;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a_i32: i32 = 1;
let mut b_i32: i32 = 2;
a_i32 % b_i32;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_i32 %= a_i32;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a_i64: i64 = 1;
let mut b_i64: i64 = 2;
a_i64 % b_i64;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_i64 %= a_i64;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a_i128: i128 = 1;
let mut b_i128: i128 = 2;
a_i128 % b_i128;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_i128 %= a_i128;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a_isize: isize = 1;
let mut b_isize: isize = 2;
a_isize % b_isize;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b_isize %= a_isize;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
let a = 1;
let mut b = 2;
a % b;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
b %= a;
+ //~^ ERROR: you are using modulo operator on types that might have different signs
+ //~| NOTE: double check for expected result especially when interoperating with differ
// No lint on unsigned integral value
let a_u8: u8 = 17;
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr
index 9ff676ff6..033a016c0 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr
@@ -7,9 +7,10 @@ LL | a % b;
= note: double check for expected result especially when interoperating with different languages
= note: or consider using `rem_euclid` or similar function
= note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:9:5
+ --> $DIR/modulo_arithmetic_integral.rs:11:5
|
LL | b % a;
| ^^^^^
@@ -18,7 +19,7 @@ LL | b % a;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:10:5
+ --> $DIR/modulo_arithmetic_integral.rs:14:5
|
LL | b %= a;
| ^^^^^^
@@ -27,7 +28,7 @@ LL | b %= a;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:14:5
+ --> $DIR/modulo_arithmetic_integral.rs:20:5
|
LL | a_i8 % b_i8;
| ^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL | a_i8 % b_i8;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:15:5
+ --> $DIR/modulo_arithmetic_integral.rs:23:5
|
LL | b_i8 %= a_i8;
| ^^^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | b_i8 %= a_i8;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:19:5
+ --> $DIR/modulo_arithmetic_integral.rs:29:5
|
LL | a_i16 % b_i16;
| ^^^^^^^^^^^^^
@@ -54,7 +55,7 @@ LL | a_i16 % b_i16;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:20:5
+ --> $DIR/modulo_arithmetic_integral.rs:32:5
|
LL | b_i16 %= a_i16;
| ^^^^^^^^^^^^^^
@@ -63,7 +64,7 @@ LL | b_i16 %= a_i16;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:24:5
+ --> $DIR/modulo_arithmetic_integral.rs:38:5
|
LL | a_i32 % b_i32;
| ^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | a_i32 % b_i32;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:25:5
+ --> $DIR/modulo_arithmetic_integral.rs:41:5
|
LL | b_i32 %= a_i32;
| ^^^^^^^^^^^^^^
@@ -81,7 +82,7 @@ LL | b_i32 %= a_i32;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:29:5
+ --> $DIR/modulo_arithmetic_integral.rs:47:5
|
LL | a_i64 % b_i64;
| ^^^^^^^^^^^^^
@@ -90,7 +91,7 @@ LL | a_i64 % b_i64;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:30:5
+ --> $DIR/modulo_arithmetic_integral.rs:50:5
|
LL | b_i64 %= a_i64;
| ^^^^^^^^^^^^^^
@@ -99,7 +100,7 @@ LL | b_i64 %= a_i64;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:34:5
+ --> $DIR/modulo_arithmetic_integral.rs:56:5
|
LL | a_i128 % b_i128;
| ^^^^^^^^^^^^^^^
@@ -108,7 +109,7 @@ LL | a_i128 % b_i128;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:35:5
+ --> $DIR/modulo_arithmetic_integral.rs:59:5
|
LL | b_i128 %= a_i128;
| ^^^^^^^^^^^^^^^^
@@ -117,7 +118,7 @@ LL | b_i128 %= a_i128;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:39:5
+ --> $DIR/modulo_arithmetic_integral.rs:65:5
|
LL | a_isize % b_isize;
| ^^^^^^^^^^^^^^^^^
@@ -126,7 +127,7 @@ LL | a_isize % b_isize;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:40:5
+ --> $DIR/modulo_arithmetic_integral.rs:68:5
|
LL | b_isize %= a_isize;
| ^^^^^^^^^^^^^^^^^^
@@ -135,7 +136,7 @@ LL | b_isize %= a_isize;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:44:5
+ --> $DIR/modulo_arithmetic_integral.rs:74:5
|
LL | a % b;
| ^^^^^
@@ -144,7 +145,7 @@ LL | a % b;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on types that might have different signs
- --> $DIR/modulo_arithmetic_integral.rs:45:5
+ --> $DIR/modulo_arithmetic_integral.rs:77:5
|
LL | b %= a;
| ^^^^^^
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
index 3ebe46bc5..dbc679a69 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
@@ -9,23 +9,57 @@
fn main() {
// Lint when both sides are const and of the opposite sign
-1 % 2;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
1 % -2;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
(1 - 2) % (1 + 2);
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 3`
+ //~| NOTE: double check for expected result especially when interoperating with differ
(1 + 2) % (1 - 2);
+ //~^ ERROR: you are using modulo operator on constants with different signs: `3 % -1`
+ //~| NOTE: double check for expected result especially when interoperating with differ
35 * (7 - 4 * 2) % (-500 * -600);
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-35 % 30
+ //~| NOTE: double check for expected result especially when interoperating with differ
-1i8 % 2i8;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
1i8 % -2i8;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
-1i16 % 2i16;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
1i16 % -2i16;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
-1i32 % 2i32;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
1i32 % -2i32;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
-1i64 % 2i64;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
1i64 % -2i64;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
-1i128 % 2i128;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
1i128 % -2i128;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
-1isize % 2isize;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `-1 % 2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
1isize % -2isize;
+ //~^ ERROR: you are using modulo operator on constants with different signs: `1 % -2`
+ //~| NOTE: double check for expected result especially when interoperating with differ
// No lint when both sides are const and of the same sign
1 % 2;
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
index 1453d44f4..47ed2261a 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
@@ -7,9 +7,10 @@ LL | -1 % 2;
= note: double check for expected result especially when interoperating with different languages
= note: or consider using `rem_euclid` or similar function
= note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`
error: you are using modulo operator on constants with different signs: `1 % -2`
- --> $DIR/modulo_arithmetic_integral_const.rs:12:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:14:5
|
LL | 1 % -2;
| ^^^^^^
@@ -18,7 +19,7 @@ LL | 1 % -2;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-1 % 3`
- --> $DIR/modulo_arithmetic_integral_const.rs:13:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:17:5
|
LL | (1 - 2) % (1 + 2);
| ^^^^^^^^^^^^^^^^^
@@ -27,7 +28,7 @@ LL | (1 - 2) % (1 + 2);
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `3 % -1`
- --> $DIR/modulo_arithmetic_integral_const.rs:14:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:20:5
|
LL | (1 + 2) % (1 - 2);
| ^^^^^^^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL | (1 + 2) % (1 - 2);
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-35 % 300000`
- --> $DIR/modulo_arithmetic_integral_const.rs:15:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:23:5
|
LL | 35 * (7 - 4 * 2) % (-500 * -600);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | 35 * (7 - 4 * 2) % (-500 * -600);
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-1 % 2`
- --> $DIR/modulo_arithmetic_integral_const.rs:17:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:27:5
|
LL | -1i8 % 2i8;
| ^^^^^^^^^^
@@ -54,7 +55,7 @@ LL | -1i8 % 2i8;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `1 % -2`
- --> $DIR/modulo_arithmetic_integral_const.rs:18:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:30:5
|
LL | 1i8 % -2i8;
| ^^^^^^^^^^
@@ -63,7 +64,7 @@ LL | 1i8 % -2i8;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-1 % 2`
- --> $DIR/modulo_arithmetic_integral_const.rs:19:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:33:5
|
LL | -1i16 % 2i16;
| ^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | -1i16 % 2i16;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `1 % -2`
- --> $DIR/modulo_arithmetic_integral_const.rs:20:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:36:5
|
LL | 1i16 % -2i16;
| ^^^^^^^^^^^^
@@ -81,7 +82,7 @@ LL | 1i16 % -2i16;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-1 % 2`
- --> $DIR/modulo_arithmetic_integral_const.rs:21:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:39:5
|
LL | -1i32 % 2i32;
| ^^^^^^^^^^^^
@@ -90,7 +91,7 @@ LL | -1i32 % 2i32;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `1 % -2`
- --> $DIR/modulo_arithmetic_integral_const.rs:22:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:42:5
|
LL | 1i32 % -2i32;
| ^^^^^^^^^^^^
@@ -99,7 +100,7 @@ LL | 1i32 % -2i32;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-1 % 2`
- --> $DIR/modulo_arithmetic_integral_const.rs:23:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:45:5
|
LL | -1i64 % 2i64;
| ^^^^^^^^^^^^
@@ -108,7 +109,7 @@ LL | -1i64 % 2i64;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `1 % -2`
- --> $DIR/modulo_arithmetic_integral_const.rs:24:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:48:5
|
LL | 1i64 % -2i64;
| ^^^^^^^^^^^^
@@ -117,7 +118,7 @@ LL | 1i64 % -2i64;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-1 % 2`
- --> $DIR/modulo_arithmetic_integral_const.rs:25:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:51:5
|
LL | -1i128 % 2i128;
| ^^^^^^^^^^^^^^
@@ -126,7 +127,7 @@ LL | -1i128 % 2i128;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `1 % -2`
- --> $DIR/modulo_arithmetic_integral_const.rs:26:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:54:5
|
LL | 1i128 % -2i128;
| ^^^^^^^^^^^^^^
@@ -135,7 +136,7 @@ LL | 1i128 % -2i128;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `-1 % 2`
- --> $DIR/modulo_arithmetic_integral_const.rs:27:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:57:5
|
LL | -1isize % 2isize;
| ^^^^^^^^^^^^^^^^
@@ -144,7 +145,7 @@ LL | -1isize % 2isize;
= note: or consider using `rem_euclid` or similar function
error: you are using modulo operator on constants with different signs: `1 % -2`
- --> $DIR/modulo_arithmetic_integral_const.rs:28:5
+ --> $DIR/modulo_arithmetic_integral_const.rs:60:5
|
LL | 1isize % -2isize;
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/modulo_one.rs b/src/tools/clippy/tests/ui/modulo_one.rs
index adff08e5d..c1dbe9d9a 100644
--- a/src/tools/clippy/tests/ui/modulo_one.rs
+++ b/src/tools/clippy/tests/ui/modulo_one.rs
@@ -6,18 +6,34 @@ static STATIC_NEG_ONE: i64 = 1 - 2;
fn main() {
10 % 1;
+ //~^ ERROR: any number modulo 1 will be 0
+ //~| NOTE: `-D clippy::modulo-one` implied by `-D warnings`
10 % -1;
+ //~^ ERROR: any number modulo -1 will panic/overflow or result in 0
10 % 2;
- i32::MIN % (-1); // also caught by rustc
+ // also caught by rustc
+ i32::MIN % (-1);
+ //~^ ERROR: this operation will panic at runtime
+ //~| NOTE: `#[deny(unconditional_panic)]` on by default
+ //~| ERROR: any number modulo -1 will panic/overflow or result in 0
const ONE: u32 = 1 * 1;
const NEG_ONE: i64 = 1 - 2;
const INT_MIN: i64 = i64::MIN;
2 % ONE;
- 5 % STATIC_ONE; // NOT caught by lint
+ //~^ ERROR: any number modulo 1 will be 0
+ // NOT caught by lint
+ 5 % STATIC_ONE;
2 % NEG_ONE;
- 5 % STATIC_NEG_ONE; // NOT caught by lint
- INT_MIN % NEG_ONE; // also caught by rustc
- INT_MIN % STATIC_NEG_ONE; // ONLY caught by rustc
+ //~^ ERROR: any number modulo -1 will panic/overflow or result in 0
+ // NOT caught by lint
+ 5 % STATIC_NEG_ONE;
+ // also caught by rustc
+ INT_MIN % NEG_ONE;
+ //~^ ERROR: this operation will panic at runtime
+ //~| ERROR: any number modulo -1 will panic/overflow or result in 0
+ // ONLY caught by rustc
+ INT_MIN % STATIC_NEG_ONE;
+ //~^ ERROR: this operation will panic at runtime
}
diff --git a/src/tools/clippy/tests/ui/modulo_one.stderr b/src/tools/clippy/tests/ui/modulo_one.stderr
index 83a76f81d..cc211ab6c 100644
--- a/src/tools/clippy/tests/ui/modulo_one.stderr
+++ b/src/tools/clippy/tests/ui/modulo_one.stderr
@@ -1,21 +1,21 @@
error: this operation will panic at runtime
- --> $DIR/modulo_one.rs:11:5
+ --> $DIR/modulo_one.rs:15:5
|
-LL | i32::MIN % (-1); // also caught by rustc
+LL | i32::MIN % (-1);
| ^^^^^^^^^^^^^^^ attempt to compute `i32::MIN % -1_i32`, which would overflow
|
= note: `#[deny(unconditional_panic)]` on by default
error: this operation will panic at runtime
- --> $DIR/modulo_one.rs:21:5
+ --> $DIR/modulo_one.rs:33:5
|
-LL | INT_MIN % NEG_ONE; // also caught by rustc
+LL | INT_MIN % NEG_ONE;
| ^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow
error: this operation will panic at runtime
- --> $DIR/modulo_one.rs:22:5
+ --> $DIR/modulo_one.rs:37:5
|
-LL | INT_MIN % STATIC_NEG_ONE; // ONLY caught by rustc
+LL | INT_MIN % STATIC_NEG_ONE;
| ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i64::MIN % -1_i64`, which would overflow
error: any number modulo 1 will be 0
@@ -25,35 +25,36 @@ LL | 10 % 1;
| ^^^^^^
|
= note: `-D clippy::modulo-one` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::modulo_one)]`
error: any number modulo -1 will panic/overflow or result in 0
- --> $DIR/modulo_one.rs:9:5
+ --> $DIR/modulo_one.rs:11:5
|
LL | 10 % -1;
| ^^^^^^^
error: any number modulo -1 will panic/overflow or result in 0
- --> $DIR/modulo_one.rs:11:5
+ --> $DIR/modulo_one.rs:15:5
|
-LL | i32::MIN % (-1); // also caught by rustc
+LL | i32::MIN % (-1);
| ^^^^^^^^^^^^^^^
error: any number modulo 1 will be 0
- --> $DIR/modulo_one.rs:17:5
+ --> $DIR/modulo_one.rs:24:5
|
LL | 2 % ONE;
| ^^^^^^^
error: any number modulo -1 will panic/overflow or result in 0
- --> $DIR/modulo_one.rs:19:5
+ --> $DIR/modulo_one.rs:28:5
|
LL | 2 % NEG_ONE;
| ^^^^^^^^^^^
error: any number modulo -1 will panic/overflow or result in 0
- --> $DIR/modulo_one.rs:21:5
+ --> $DIR/modulo_one.rs:33:5
|
-LL | INT_MIN % NEG_ONE; // also caught by rustc
+LL | INT_MIN % NEG_ONE;
| ^^^^^^^^^^^^^^^^^
error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/multi_assignments.rs b/src/tools/clippy/tests/ui/multi_assignments.rs
index b186bf8bb..cdbf13b68 100644
--- a/src/tools/clippy/tests/ui/multi_assignments.rs
+++ b/src/tools/clippy/tests/ui/multi_assignments.rs
@@ -2,8 +2,15 @@
fn main() {
let (mut a, mut b, mut c, mut d) = ((), (), (), ());
a = b = c;
+ //~^ ERROR: assignments don't nest intuitively
+ //~| NOTE: `-D clippy::multi-assignments` implied by `-D warnings`
a = b = c = d;
+ //~^ ERROR: assignments don't nest intuitively
+ //~| ERROR: assignments don't nest intuitively
a = b = { c };
+ //~^ ERROR: assignments don't nest intuitively
a = { b = c };
+ //~^ ERROR: assignments don't nest intuitively
a = (b = c);
+ //~^ ERROR: assignments don't nest intuitively
}
diff --git a/src/tools/clippy/tests/ui/multi_assignments.stderr b/src/tools/clippy/tests/ui/multi_assignments.stderr
index d6c42bb69..9719b5e66 100644
--- a/src/tools/clippy/tests/ui/multi_assignments.stderr
+++ b/src/tools/clippy/tests/ui/multi_assignments.stderr
@@ -5,33 +5,34 @@ LL | a = b = c;
| ^^^^^^^^^
|
= note: `-D clippy::multi-assignments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::multi_assignments)]`
error: assignments don't nest intuitively
- --> $DIR/multi_assignments.rs:5:5
+ --> $DIR/multi_assignments.rs:7:5
|
LL | a = b = c = d;
| ^^^^^^^^^^^^^
error: assignments don't nest intuitively
- --> $DIR/multi_assignments.rs:5:9
+ --> $DIR/multi_assignments.rs:7:9
|
LL | a = b = c = d;
| ^^^^^^^^^
error: assignments don't nest intuitively
- --> $DIR/multi_assignments.rs:6:5
+ --> $DIR/multi_assignments.rs:10:5
|
LL | a = b = { c };
| ^^^^^^^^^^^^^
error: assignments don't nest intuitively
- --> $DIR/multi_assignments.rs:7:5
+ --> $DIR/multi_assignments.rs:12:5
|
LL | a = { b = c };
| ^^^^^^^^^^^^^
error: assignments don't nest intuitively
- --> $DIR/multi_assignments.rs:8:5
+ --> $DIR/multi_assignments.rs:14:5
|
LL | a = (b = c);
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
index 23ad36bb4..4ef6f0ca9 100644
--- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused)]
#![allow(deref_nullptr)]
#![allow(clippy::unnecessary_operation)]
diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
index badc284ec..4803a5089 100644
--- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
+++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
@@ -18,6 +18,7 @@ note: unsafe function call occurs here
LL | not_very_safe();
| ^^^^^^^^^^^^^^^
= note: `-D clippy::multiple-unsafe-ops-per-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]`
error: this `unsafe` block contains 2 unsafe operations, expected only one
--> $DIR/multiple_unsafe_ops_per_block.rs:45:5
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed
index 3ca20c07d..3ed705b29 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.fixed
+++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(never_type)]
#![allow(
unused_mut,
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.rs b/src/tools/clippy/tests/ui/must_use_candidates.rs
index dc4e0118e..ab8efea0a 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.rs
+++ b/src/tools/clippy/tests/ui/must_use_candidates.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(never_type)]
#![allow(
unused_mut,
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.stderr b/src/tools/clippy/tests/ui/must_use_candidates.stderr
index 5fb302ccb..581399f3e 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.stderr
+++ b/src/tools/clippy/tests/ui/must_use_candidates.stderr
@@ -1,31 +1,32 @@
error: this function could have a `#[must_use]` attribute
- --> $DIR/must_use_candidates.rs:17:1
+ --> $DIR/must_use_candidates.rs:16:1
|
LL | pub fn pure(i: u8) -> u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8`
|
= note: `-D clippy::must-use-candidate` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]`
error: this method could have a `#[must_use]` attribute
- --> $DIR/must_use_candidates.rs:22:5
+ --> $DIR/must_use_candidates.rs:21:5
|
LL | pub fn inherent_pure(&self) -> u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8`
error: this function could have a `#[must_use]` attribute
- --> $DIR/must_use_candidates.rs:53:1
+ --> $DIR/must_use_candidates.rs:52:1
|
LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool`
error: this function could have a `#[must_use]` attribute
- --> $DIR/must_use_candidates.rs:65:1
+ --> $DIR/must_use_candidates.rs:64:1
|
LL | pub fn rcd(_x: Rc<u32>) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc<u32>) -> bool`
error: this function could have a `#[must_use]` attribute
- --> $DIR/must_use_candidates.rs:73:1
+ --> $DIR/must_use_candidates.rs:72:1
|
LL | pub fn arcd(_x: Arc<u32>) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc<u32>) -> bool`
diff --git a/src/tools/clippy/tests/ui/must_use_unit.fixed b/src/tools/clippy/tests/ui/must_use_unit.fixed
index c460fd7c6..75f91e668 100644
--- a/src/tools/clippy/tests/ui/must_use_unit.fixed
+++ b/src/tools/clippy/tests/ui/must_use_unit.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::must_use_unit)]
#![allow(clippy::unused_unit)]
diff --git a/src/tools/clippy/tests/ui/must_use_unit.rs b/src/tools/clippy/tests/ui/must_use_unit.rs
index fe95624f7..1305910ed 100644
--- a/src/tools/clippy/tests/ui/must_use_unit.rs
+++ b/src/tools/clippy/tests/ui/must_use_unit.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::must_use_unit)]
#![allow(clippy::unused_unit)]
diff --git a/src/tools/clippy/tests/ui/must_use_unit.stderr b/src/tools/clippy/tests/ui/must_use_unit.stderr
index 15e0906b6..e67d9b5b9 100644
--- a/src/tools/clippy/tests/ui/must_use_unit.stderr
+++ b/src/tools/clippy/tests/ui/must_use_unit.stderr
@@ -1,5 +1,5 @@
error: this unit-returning function has a `#[must_use]` attribute
- --> $DIR/must_use_unit.rs:11:1
+ --> $DIR/must_use_unit.rs:10:1
|
LL | #[must_use]
| ----------- help: remove the attribute
@@ -7,9 +7,10 @@ LL | pub fn must_use_default() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::must-use-unit` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]`
error: this unit-returning function has a `#[must_use]` attribute
- --> $DIR/must_use_unit.rs:14:1
+ --> $DIR/must_use_unit.rs:13:1
|
LL | #[must_use]
| ----------- help: remove the attribute
@@ -17,7 +18,7 @@ LL | pub fn must_use_unit() -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this unit-returning function has a `#[must_use]` attribute
- --> $DIR/must_use_unit.rs:17:1
+ --> $DIR/must_use_unit.rs:16:1
|
LL | #[must_use = "With note"]
| ------------------------- help: remove the attribute
diff --git a/src/tools/clippy/tests/ui/mut_from_ref.rs b/src/tools/clippy/tests/ui/mut_from_ref.rs
index 8c0c23b65..0ab6d77de 100644
--- a/src/tools/clippy/tests/ui/mut_from_ref.rs
+++ b/src/tools/clippy/tests/ui/mut_from_ref.rs
@@ -5,12 +5,14 @@ struct Foo;
impl Foo {
fn this_wont_hurt_a_bit(&self) -> &mut Foo {
+ //~^ ERROR: mutable borrow from immutable input(s)
unsafe { unimplemented!() }
}
}
trait Ouch {
fn ouch(x: &Foo) -> &mut Foo;
+ //~^ ERROR: mutable borrow from immutable input(s)
}
impl Ouch for Foo {
@@ -20,14 +22,17 @@ impl Ouch for Foo {
}
fn fail(x: &u32) -> &mut u16 {
+ //~^ ERROR: mutable borrow from immutable input(s)
unsafe { unimplemented!() }
}
fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {
+ //~^ ERROR: mutable borrow from immutable input(s)
unsafe { unimplemented!() }
}
fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {
+ //~^ ERROR: mutable borrow from immutable input(s)
unsafe { unimplemented!() }
}
@@ -42,6 +47,7 @@ fn also_works<'a>(x: &'a u32, y: &'a mut u32) -> &'a mut u32 {
}
unsafe fn also_broken(x: &u32) -> &mut u32 {
+ //~^ ERROR: mutable borrow from immutable input(s)
unimplemented!()
}
diff --git a/src/tools/clippy/tests/ui/mut_from_ref.stderr b/src/tools/clippy/tests/ui/mut_from_ref.stderr
index c20ff54bf..38f47b9ad 100644
--- a/src/tools/clippy/tests/ui/mut_from_ref.stderr
+++ b/src/tools/clippy/tests/ui/mut_from_ref.stderr
@@ -10,63 +10,64 @@ note: immutable borrow here
LL | fn this_wont_hurt_a_bit(&self) -> &mut Foo {
| ^^^^^
= note: `-D clippy::mut-from-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mut_from_ref)]`
error: mutable borrow from immutable input(s)
- --> $DIR/mut_from_ref.rs:13:25
+ --> $DIR/mut_from_ref.rs:14:25
|
LL | fn ouch(x: &Foo) -> &mut Foo;
| ^^^^^^^^
|
note: immutable borrow here
- --> $DIR/mut_from_ref.rs:13:16
+ --> $DIR/mut_from_ref.rs:14:16
|
LL | fn ouch(x: &Foo) -> &mut Foo;
| ^^^^
error: mutable borrow from immutable input(s)
- --> $DIR/mut_from_ref.rs:22:21
+ --> $DIR/mut_from_ref.rs:24:21
|
LL | fn fail(x: &u32) -> &mut u16 {
| ^^^^^^^^
|
note: immutable borrow here
- --> $DIR/mut_from_ref.rs:22:12
+ --> $DIR/mut_from_ref.rs:24:12
|
LL | fn fail(x: &u32) -> &mut u16 {
| ^^^^
error: mutable borrow from immutable input(s)
- --> $DIR/mut_from_ref.rs:26:50
+ --> $DIR/mut_from_ref.rs:29:50
|
LL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {
| ^^^^^^^^^^^
|
note: immutable borrow here
- --> $DIR/mut_from_ref.rs:26:25
+ --> $DIR/mut_from_ref.rs:29:25
|
LL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {
| ^^^^^^^
error: mutable borrow from immutable input(s)
- --> $DIR/mut_from_ref.rs:30:67
+ --> $DIR/mut_from_ref.rs:34:67
|
LL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {
| ^^^^^^^^^^^
|
note: immutable borrow here
- --> $DIR/mut_from_ref.rs:30:27
+ --> $DIR/mut_from_ref.rs:34:27
|
LL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {
| ^^^^^^^ ^^^^^^^
error: mutable borrow from immutable input(s)
- --> $DIR/mut_from_ref.rs:44:35
+ --> $DIR/mut_from_ref.rs:49:35
|
LL | unsafe fn also_broken(x: &u32) -> &mut u32 {
| ^^^^^^^^
|
note: immutable borrow here
- --> $DIR/mut_from_ref.rs:44:26
+ --> $DIR/mut_from_ref.rs:49:26
|
LL | unsafe fn also_broken(x: &u32) -> &mut u32 {
| ^^^^
diff --git a/src/tools/clippy/tests/ui/mut_key.rs b/src/tools/clippy/tests/ui/mut_key.rs
index 15d68c089..2d70bfd4c 100644
--- a/src/tools/clippy/tests/ui/mut_key.rs
+++ b/src/tools/clippy/tests/ui/mut_key.rs
@@ -5,7 +5,7 @@ use std::rc::Rc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::Relaxed;
use std::sync::Arc;
-
+//@no-rustfix
struct Key(AtomicUsize);
impl Clone for Key {
@@ -29,7 +29,11 @@ impl Hash for Key {
}
fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<Key> {
+ //~^ ERROR: mutable key type
+ //~| NOTE: `-D clippy::mutable-key-type` implied by `-D warnings`
+ //~| ERROR: mutable key type
let _other: HashMap<Key, bool> = HashMap::new();
+ //~^ ERROR: mutable key type
m.keys().cloned().collect()
}
@@ -57,6 +61,7 @@ fn generics_are_ok_too<K>(_m: &mut HashSet<K>) {
fn tuples<U>(_m: &mut HashMap<((), U), ()>) {}
fn tuples_bad<U>(_m: &mut HashMap<(Key, U), bool>) {}
+//~^ ERROR: mutable key type
fn main() {
let _ = should_not_take_this_arg(&mut HashMap::new(), 1);
@@ -69,18 +74,31 @@ fn main() {
raw_mut_ptr_is_ok(&mut HashMap::new());
let _map = HashMap::<Cell<usize>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<&mut Cell<usize>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<&mut usize, usize>::new();
+ //~^ ERROR: mutable key type
// Collection types from `std` who's impl of `Hash` or `Ord` delegate their type parameters
let _map = HashMap::<Vec<Cell<usize>>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<BTreeMap<Cell<usize>, ()>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<BTreeMap<(), Cell<usize>>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<BTreeSet<Cell<usize>>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<Option<Cell<usize>>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<Option<Vec<Cell<usize>>>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<Result<&mut usize, ()>, usize>::new();
+ //~^ ERROR: mutable key type
// Smart pointers from `std` who's impl of `Hash` or `Ord` delegate their type parameters
let _map = HashMap::<Box<Cell<usize>>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<Rc<Cell<usize>>, usize>::new();
+ //~^ ERROR: mutable key type
let _map = HashMap::<Arc<Cell<usize>>, usize>::new();
+ //~^ ERROR: mutable key type
}
diff --git a/src/tools/clippy/tests/ui/mut_key.stderr b/src/tools/clippy/tests/ui/mut_key.stderr
index 95b9546bf..48eeaff78 100644
--- a/src/tools/clippy/tests/ui/mut_key.stderr
+++ b/src/tools/clippy/tests/ui/mut_key.stderr
@@ -5,6 +5,7 @@ LL | fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> Hash
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::mutable-key-type` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mutable_key_type)]`
error: mutable key type
--> $DIR/mut_key.rs:31:72
@@ -13,91 +14,91 @@ LL | fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> Hash
| ^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:32:5
+ --> $DIR/mut_key.rs:35:5
|
LL | let _other: HashMap<Key, bool> = HashMap::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:59:22
+ --> $DIR/mut_key.rs:63:22
|
LL | fn tuples_bad<U>(_m: &mut HashMap<(Key, U), bool>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:71:5
+ --> $DIR/mut_key.rs:76:5
|
LL | let _map = HashMap::<Cell<usize>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:72:5
+ --> $DIR/mut_key.rs:78:5
|
LL | let _map = HashMap::<&mut Cell<usize>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:73:5
+ --> $DIR/mut_key.rs:80:5
|
LL | let _map = HashMap::<&mut usize, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:75:5
+ --> $DIR/mut_key.rs:83:5
|
LL | let _map = HashMap::<Vec<Cell<usize>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:76:5
+ --> $DIR/mut_key.rs:85:5
|
LL | let _map = HashMap::<BTreeMap<Cell<usize>, ()>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:77:5
+ --> $DIR/mut_key.rs:87:5
|
LL | let _map = HashMap::<BTreeMap<(), Cell<usize>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:78:5
+ --> $DIR/mut_key.rs:89:5
|
LL | let _map = HashMap::<BTreeSet<Cell<usize>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:79:5
+ --> $DIR/mut_key.rs:91:5
|
LL | let _map = HashMap::<Option<Cell<usize>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:80:5
+ --> $DIR/mut_key.rs:93:5
|
LL | let _map = HashMap::<Option<Vec<Cell<usize>>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:81:5
+ --> $DIR/mut_key.rs:95:5
|
LL | let _map = HashMap::<Result<&mut usize, ()>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:83:5
+ --> $DIR/mut_key.rs:98:5
|
LL | let _map = HashMap::<Box<Cell<usize>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:84:5
+ --> $DIR/mut_key.rs:100:5
|
LL | let _map = HashMap::<Rc<Cell<usize>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: mutable key type
- --> $DIR/mut_key.rs:85:5
+ --> $DIR/mut_key.rs:102:5
|
LL | let _map = HashMap::<Arc<Cell<usize>>, usize>::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mut_mut.rs b/src/tools/clippy/tests/ui/mut_mut.rs
index fe7d53e8e..72a171119 100644
--- a/src/tools/clippy/tests/ui/mut_mut.rs
+++ b/src/tools/clippy/tests/ui/mut_mut.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::mut_mut)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/mut_mut.stderr b/src/tools/clippy/tests/ui/mut_mut.stderr
index 58a1c4e68..5ed9cd1af 100644
--- a/src/tools/clippy/tests/ui/mut_mut.stderr
+++ b/src/tools/clippy/tests/ui/mut_mut.stderr
@@ -5,6 +5,7 @@ LL | fn fun(x: &mut &mut u32) -> bool {
| ^^^^^^^^^^^^^
|
= note: `-D clippy::mut-mut` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]`
error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:31:17
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
index 433817a4e..bbedbb2be 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, unused_mut)]
#![warn(clippy::mut_mutex_lock)]
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.rs b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
index 567a0b59e..74116100e 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.rs
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, unused_mut)]
#![warn(clippy::mut_mutex_lock)]
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
index 21c1b3486..9b20016be 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
@@ -1,10 +1,11 @@
error: calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference
- --> $DIR/mut_mutex_lock.rs:11:33
+ --> $DIR/mut_mutex_lock.rs:10:33
|
LL | let mut value = value_mutex.lock().unwrap();
| ^^^^ help: change this to: `get_mut`
|
= note: `-D clippy::mut-mutex-lock` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mut_mutex_lock)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/mut_range_bound.rs b/src/tools/clippy/tests/ui/mut_range_bound.rs
index 7fdeb27ed..7aebbf498 100644
--- a/src/tools/clippy/tests/ui/mut_range_bound.rs
+++ b/src/tools/clippy/tests/ui/mut_range_bound.rs
@@ -6,14 +6,18 @@ fn mut_range_bound_upper() {
let mut m = 4;
for i in 0..m {
m = 5;
- } // warning
+ //~^ ERROR: attempt to mutate range bound within loop
+ //~| NOTE: the range of the loop is unchanged
+ }
}
fn mut_range_bound_lower() {
let mut m = 4;
for i in m..10 {
m *= 2;
- } // warning
+ //~^ ERROR: attempt to mutate range bound within loop
+ //~| NOTE: the range of the loop is unchanged
+ }
}
fn mut_range_bound_both() {
@@ -21,8 +25,12 @@ fn mut_range_bound_both() {
let mut n = 6;
for i in m..n {
m = 5;
+ //~^ ERROR: attempt to mutate range bound within loop
+ //~| NOTE: the range of the loop is unchanged
n = 7;
- } // warning (1 for each mutated bound)
+ //~^ ERROR: attempt to mutate range bound within loop
+ //~| NOTE: the range of the loop is unchanged
+ }
}
fn mut_range_bound_no_mutation() {
@@ -35,7 +43,9 @@ fn mut_range_bound_no_mutation() {
fn mut_borrow_range_bound() {
let mut m = 4;
for i in 0..m {
- let n = &mut m; // warning
+ let n = &mut m;
+ //~^ ERROR: attempt to mutate range bound within loop
+ //~| NOTE: the range of the loop is unchanged
*n += 1;
}
}
@@ -43,7 +53,7 @@ fn mut_borrow_range_bound() {
fn immut_borrow_range_bound() {
let mut m = 4;
for i in 0..m {
- let n = &m; // should be no warning?
+ let n = &m;
}
}
@@ -67,7 +77,10 @@ fn mut_range_bound_break() {
fn mut_range_bound_no_immediate_break() {
let mut m = 4;
for i in 0..m {
- m = 2; // warning because it is not immediately followed by break
+ // warning because it is not immediately followed by break
+ m = 2;
+ //~^ ERROR: attempt to mutate range bound within loop
+ //~| NOTE: the range of the loop is unchanged
if m == 4 {
break;
}
@@ -76,7 +89,10 @@ fn mut_range_bound_no_immediate_break() {
let mut n = 3;
for i in n..10 {
if n == 4 {
- n = 1; // FIXME: warning because it is not immediately followed by break
+ // FIXME: warning because it is not immediately followed by break
+ n = 1;
+ //~^ ERROR: attempt to mutate range bound within loop
+ //~| NOTE: the range of the loop is unchanged
let _ = 2;
break;
}
diff --git a/src/tools/clippy/tests/ui/mut_range_bound.stderr b/src/tools/clippy/tests/ui/mut_range_bound.stderr
index b679b7a0a..42f8a161f 100644
--- a/src/tools/clippy/tests/ui/mut_range_bound.stderr
+++ b/src/tools/clippy/tests/ui/mut_range_bound.stderr
@@ -6,9 +6,10 @@ LL | m = 5;
|
= note: the range of the loop is unchanged
= note: `-D clippy::mut-range-bound` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mut_range_bound)]`
error: attempt to mutate range bound within loop
- --> $DIR/mut_range_bound.rs:15:9
+ --> $DIR/mut_range_bound.rs:17:9
|
LL | m *= 2;
| ^
@@ -16,7 +17,7 @@ LL | m *= 2;
= note: the range of the loop is unchanged
error: attempt to mutate range bound within loop
- --> $DIR/mut_range_bound.rs:23:9
+ --> $DIR/mut_range_bound.rs:27:9
|
LL | m = 5;
| ^
@@ -24,7 +25,7 @@ LL | m = 5;
= note: the range of the loop is unchanged
error: attempt to mutate range bound within loop
- --> $DIR/mut_range_bound.rs:24:9
+ --> $DIR/mut_range_bound.rs:30:9
|
LL | n = 7;
| ^
@@ -32,25 +33,25 @@ LL | n = 7;
= note: the range of the loop is unchanged
error: attempt to mutate range bound within loop
- --> $DIR/mut_range_bound.rs:38:22
+ --> $DIR/mut_range_bound.rs:46:22
|
-LL | let n = &mut m; // warning
+LL | let n = &mut m;
| ^
|
= note: the range of the loop is unchanged
error: attempt to mutate range bound within loop
- --> $DIR/mut_range_bound.rs:70:9
+ --> $DIR/mut_range_bound.rs:81:9
|
-LL | m = 2; // warning because it is not immediately followed by break
+LL | m = 2;
| ^
|
= note: the range of the loop is unchanged
error: attempt to mutate range bound within loop
- --> $DIR/mut_range_bound.rs:79:13
+ --> $DIR/mut_range_bound.rs:93:13
|
-LL | n = 1; // FIXME: warning because it is not immediately followed by break
+LL | n = 1;
| ^
|
= note: the range of the loop is unchanged
diff --git a/src/tools/clippy/tests/ui/mut_reference.rs b/src/tools/clippy/tests/ui/mut_reference.rs
index 00661c51a..1d7faaa5e 100644
--- a/src/tools/clippy/tests/ui/mut_reference.rs
+++ b/src/tools/clippy/tests/ui/mut_reference.rs
@@ -1,5 +1,5 @@
#![allow(unused_variables, dead_code)]
-
+//@no-rustfix
fn takes_an_immutable_reference(a: &i32) {}
fn takes_a_mutable_reference(a: &mut i32) {}
@@ -28,12 +28,16 @@ impl MyStruct {
fn main() {
// Functions
takes_an_immutable_reference(&mut 42);
+ //~^ ERROR: the function `takes_an_immutable_reference` doesn't need a mutable referen
+ //~| NOTE: `-D clippy::unnecessary-mut-passed` implied by `-D warnings`
let as_ptr: fn(&i32) = takes_an_immutable_reference;
as_ptr(&mut 42);
+ //~^ ERROR: the function `as_ptr` doesn't need a mutable reference
// Methods
let my_struct = MyStruct;
my_struct.takes_an_immutable_reference(&mut 42);
+ //~^ ERROR: the method `takes_an_immutable_reference` doesn't need a mutable reference
// No error
diff --git a/src/tools/clippy/tests/ui/mut_reference.stderr b/src/tools/clippy/tests/ui/mut_reference.stderr
index 4ce1cfa4f..87db08e2a 100644
--- a/src/tools/clippy/tests/ui/mut_reference.stderr
+++ b/src/tools/clippy/tests/ui/mut_reference.stderr
@@ -5,15 +5,16 @@ LL | takes_an_immutable_reference(&mut 42);
| ^^^^^^^
|
= note: `-D clippy::unnecessary-mut-passed` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_mut_passed)]`
error: the function `as_ptr` doesn't need a mutable reference
- --> $DIR/mut_reference.rs:32:12
+ --> $DIR/mut_reference.rs:34:12
|
LL | as_ptr(&mut 42);
| ^^^^^^^
error: the method `takes_an_immutable_reference` doesn't need a mutable reference
- --> $DIR/mut_reference.rs:36:44
+ --> $DIR/mut_reference.rs:39:44
|
LL | my_struct.takes_an_immutable_reference(&mut 42);
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mutex_atomic.rs b/src/tools/clippy/tests/ui/mutex_atomic.rs
index 47b3dad39..198b95d8c 100644
--- a/src/tools/clippy/tests/ui/mutex_atomic.rs
+++ b/src/tools/clippy/tests/ui/mutex_atomic.rs
@@ -6,12 +6,21 @@
fn main() {
use std::sync::Mutex;
Mutex::new(true);
+ //~^ ERROR: consider using an `AtomicBool` instead of a `Mutex` here; if you just want
+ //~| NOTE: `-D clippy::mutex-atomic` implied by `-D warnings`
Mutex::new(5usize);
+ //~^ ERROR: consider using an `AtomicUsize` instead of a `Mutex` here; if you just wan
Mutex::new(9isize);
+ //~^ ERROR: consider using an `AtomicIsize` instead of a `Mutex` here; if you just wan
let mut x = 4u32;
Mutex::new(&x as *const u32);
+ //~^ ERROR: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want
Mutex::new(&mut x as *mut u32);
+ //~^ ERROR: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want
Mutex::new(0u32);
+ //~^ ERROR: consider using an `AtomicUsize` instead of a `Mutex` here; if you just wan
+ //~| NOTE: `-D clippy::mutex-integer` implied by `-D warnings`
Mutex::new(0i32);
+ //~^ ERROR: consider using an `AtomicIsize` instead of a `Mutex` here; if you just wan
Mutex::new(0f32); // there are no float atomics, so this should not lint
}
diff --git a/src/tools/clippy/tests/ui/mutex_atomic.stderr b/src/tools/clippy/tests/ui/mutex_atomic.stderr
index 262028a87..483e1ce15 100644
--- a/src/tools/clippy/tests/ui/mutex_atomic.stderr
+++ b/src/tools/clippy/tests/ui/mutex_atomic.stderr
@@ -5,41 +5,43 @@ LL | Mutex::new(true);
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::mutex-atomic` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mutex_atomic)]`
error: consider using an `AtomicUsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>`
- --> $DIR/mutex_atomic.rs:9:5
+ --> $DIR/mutex_atomic.rs:11:5
|
LL | Mutex::new(5usize);
| ^^^^^^^^^^^^^^^^^^
error: consider using an `AtomicIsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>`
- --> $DIR/mutex_atomic.rs:10:5
+ --> $DIR/mutex_atomic.rs:13:5
|
LL | Mutex::new(9isize);
| ^^^^^^^^^^^^^^^^^^
error: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>`
- --> $DIR/mutex_atomic.rs:12:5
+ --> $DIR/mutex_atomic.rs:16:5
|
LL | Mutex::new(&x as *const u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: consider using an `AtomicPtr` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>`
- --> $DIR/mutex_atomic.rs:13:5
+ --> $DIR/mutex_atomic.rs:18:5
|
LL | Mutex::new(&mut x as *mut u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: consider using an `AtomicUsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>`
- --> $DIR/mutex_atomic.rs:14:5
+ --> $DIR/mutex_atomic.rs:20:5
|
LL | Mutex::new(0u32);
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::mutex-integer` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mutex_integer)]`
error: consider using an `AtomicIsize` instead of a `Mutex` here; if you just want the locking behavior and not the internal type, consider using `Mutex<()>`
- --> $DIR/mutex_atomic.rs:15:5
+ --> $DIR/mutex_atomic.rs:23:5
|
LL | Mutex::new(0i32);
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed
index d7eb1a047..9da60c687 100644
--- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_arbitrary_self_type)]
#![allow(unused_mut, clippy::needless_lifetimes)]
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs
index 85a2a957f..fc4ec5cb0 100644
--- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_arbitrary_self_type)]
#![allow(unused_mut, clippy::needless_lifetimes)]
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.stderr b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.stderr
index f4c645d35..fe2ac34f7 100644
--- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.stderr
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.stderr
@@ -1,37 +1,38 @@
error: the type of the `self` parameter does not need to be arbitrary
- --> $DIR/needless_arbitrary_self_type.rs:12:16
+ --> $DIR/needless_arbitrary_self_type.rs:10:16
|
LL | pub fn bad(self: Self) {
| ^^^^^^^^^^ help: consider to change this parameter to: `self`
|
= note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]`
error: the type of the `self` parameter does not need to be arbitrary
- --> $DIR/needless_arbitrary_self_type.rs:20:20
+ --> $DIR/needless_arbitrary_self_type.rs:18:20
|
LL | pub fn mut_bad(mut self: Self) {
| ^^^^^^^^^^^^^^ help: consider to change this parameter to: `mut self`
error: the type of the `self` parameter does not need to be arbitrary
- --> $DIR/needless_arbitrary_self_type.rs:28:20
+ --> $DIR/needless_arbitrary_self_type.rs:26:20
|
LL | pub fn ref_bad(self: &Self) {
| ^^^^^^^^^^^ help: consider to change this parameter to: `&self`
error: the type of the `self` parameter does not need to be arbitrary
- --> $DIR/needless_arbitrary_self_type.rs:36:38
+ --> $DIR/needless_arbitrary_self_type.rs:34:38
|
LL | pub fn ref_bad_with_lifetime<'a>(self: &'a Self) {
| ^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'a self`
error: the type of the `self` parameter does not need to be arbitrary
- --> $DIR/needless_arbitrary_self_type.rs:44:24
+ --> $DIR/needless_arbitrary_self_type.rs:42:24
|
LL | pub fn mut_ref_bad(self: &mut Self) {
| ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&mut self`
error: the type of the `self` parameter does not need to be arbitrary
- --> $DIR/needless_arbitrary_self_type.rs:52:42
+ --> $DIR/needless_arbitrary_self_type.rs:50:42
|
LL | pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) {
| ^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'a mut self`
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.fixed b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.fixed
new file mode 100644
index 000000000..62a6e5932
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.fixed
@@ -0,0 +1,46 @@
+//@aux-build:proc_macro_attr.rs
+
+#![warn(clippy::needless_arbitrary_self_type)]
+
+#[macro_use]
+extern crate proc_macro_attr;
+
+mod issue_6089 {
+ // Check that we don't lint if the `self` parameter comes from expansion
+
+ macro_rules! test_from_expansion {
+ () => {
+ trait T1 {
+ fn test(self: &Self);
+ }
+
+ struct S1;
+
+ impl T1 for S1 {
+ fn test(self: &Self) {}
+ }
+ };
+ }
+
+ test_from_expansion!();
+
+ // If only the lifetime name comes from expansion we will lint, but the suggestion will have
+ // placeholders and will not be applied automatically, as we can't reliably know the original name.
+ // This specific case happened with async_trait.
+
+ trait T2 {
+ fn call_with_mut_self(&mut self);
+ }
+
+ struct S2;
+
+ // The method's signature will be expanded to:
+ // fn call_with_mut_self<'life0>(self: &'life0 mut Self) {}
+ #[rename_my_lifetimes]
+ impl T2 for S2 {
+ #[allow(clippy::needless_lifetimes)]
+ fn call_with_mut_self(&mut self) {}
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
index 321aa69a1..00871f9f4 100644
--- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
@@ -1,7 +1,4 @@
-//@aux-build:proc_macro_attr.rs:proc-macro
-// Flaky test, see https://github.com/rust-lang/rust/issues/113585.
-//@ignore-32bit
-//@ignore-64bit
+//@aux-build:proc_macro_attr.rs
#![warn(clippy::needless_arbitrary_self_type)]
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr
index c7df5936d..183e2dbc8 100644
--- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr
@@ -5,6 +5,7 @@ LL | fn call_with_mut_self(self: &mut Self) {}
| ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&mut self`
|
= note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed b/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed
index 7543ab72c..201f8a4c1 100644
--- a/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed
+++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_bitwise_bool)]
fn returns_bool() -> bool {
diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.rs b/src/tools/clippy/tests/ui/needless_bitwise_bool.rs
index 2cea701dc..b0e5014b7 100644
--- a/src/tools/clippy/tests/ui/needless_bitwise_bool.rs
+++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_bitwise_bool)]
fn returns_bool() -> bool {
diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr b/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr
index 63c88ef63..2ed9208e6 100644
--- a/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr
+++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.stderr
@@ -1,10 +1,11 @@
error: use of bitwise operator instead of lazy operator between booleans
- --> $DIR/needless_bitwise_bool.rs:24:8
+ --> $DIR/needless_bitwise_bool.rs:22:8
|
LL | if y & !x {
| ^^^^^^ help: try: `y && !x`
|
= note: `-D clippy::needless-bitwise-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_bitwise_bool)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed
index 7d0e55652..c9ea831f8 100644
--- a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed
+++ b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_bool)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.rs b/src/tools/clippy/tests/ui/needless_bool/fixable.rs
index 88bfe8af7..b83d9c3f2 100644
--- a/src/tools/clippy/tests/ui/needless_bool/fixable.rs
+++ b/src/tools/clippy/tests/ui/needless_bool/fixable.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_bool)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.stderr b/src/tools/clippy/tests/ui/needless_bool/fixable.stderr
index 1476aea43..2b189c898 100644
--- a/src/tools/clippy/tests/ui/needless_bool/fixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_bool/fixable.stderr
@@ -1,5 +1,5 @@
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:42:5
+ --> $DIR/fixable.rs:40:5
|
LL | / if x {
LL | | true
@@ -9,9 +9,10 @@ LL | | };
| |_____^ help: you can reduce it to: `x`
|
= note: `-D clippy::needless-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:47:5
+ --> $DIR/fixable.rs:45:5
|
LL | / if x {
LL | | false
@@ -21,7 +22,7 @@ LL | | };
| |_____^ help: you can reduce it to: `!x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:52:5
+ --> $DIR/fixable.rs:50:5
|
LL | / if x && y {
LL | | false
@@ -31,7 +32,7 @@ LL | | };
| |_____^ help: you can reduce it to: `!(x && y)`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:60:5
+ --> $DIR/fixable.rs:58:5
|
LL | / if a == b {
LL | | false
@@ -41,7 +42,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a != b`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:65:5
+ --> $DIR/fixable.rs:63:5
|
LL | / if a != b {
LL | | false
@@ -51,7 +52,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a == b`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:70:5
+ --> $DIR/fixable.rs:68:5
|
LL | / if a < b {
LL | | false
@@ -61,7 +62,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a >= b`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:75:5
+ --> $DIR/fixable.rs:73:5
|
LL | / if a <= b {
LL | | false
@@ -71,7 +72,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a > b`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:80:5
+ --> $DIR/fixable.rs:78:5
|
LL | / if a > b {
LL | | false
@@ -81,7 +82,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a <= b`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:85:5
+ --> $DIR/fixable.rs:83:5
|
LL | / if a >= b {
LL | | false
@@ -91,7 +92,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a < b`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:113:5
+ --> $DIR/fixable.rs:111:5
|
LL | / if x {
LL | | return true;
@@ -101,7 +102,7 @@ LL | | };
| |_____^ help: you can reduce it to: `return x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:121:5
+ --> $DIR/fixable.rs:119:5
|
LL | / if x {
LL | | return false;
@@ -111,7 +112,7 @@ LL | | };
| |_____^ help: you can reduce it to: `return !x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:129:5
+ --> $DIR/fixable.rs:127:5
|
LL | / if x && y {
LL | | return true;
@@ -121,7 +122,7 @@ LL | | };
| |_____^ help: you can reduce it to: `return x && y`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:137:5
+ --> $DIR/fixable.rs:135:5
|
LL | / if x && y {
LL | | return false;
@@ -131,33 +132,34 @@ LL | | };
| |_____^ help: you can reduce it to: `return !(x && y)`
error: equality checks against true are unnecessary
- --> $DIR/fixable.rs:145:8
+ --> $DIR/fixable.rs:143:8
|
LL | if x == true {};
| ^^^^^^^^^ help: try simplifying it as shown: `x`
|
= note: `-D clippy::bool-comparison` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
error: equality checks against false can be replaced by a negation
- --> $DIR/fixable.rs:149:8
+ --> $DIR/fixable.rs:147:8
|
LL | if x == false {};
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: equality checks against true are unnecessary
- --> $DIR/fixable.rs:159:8
+ --> $DIR/fixable.rs:157:8
|
LL | if x == true {};
| ^^^^^^^^^ help: try simplifying it as shown: `x`
error: equality checks against false can be replaced by a negation
- --> $DIR/fixable.rs:160:8
+ --> $DIR/fixable.rs:158:8
|
LL | if x == false {};
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:169:12
+ --> $DIR/fixable.rs:167:12
|
LL | } else if returns_bool() {
| ____________^
@@ -168,7 +170,7 @@ LL | | };
| |_____^ help: you can reduce it to: `{ !returns_bool() }`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:182:5
+ --> $DIR/fixable.rs:180:5
|
LL | / if unsafe { no(4) } & 1 != 0 {
LL | | true
@@ -178,13 +180,13 @@ LL | | };
| |_____^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:187:30
+ --> $DIR/fixable.rs:185:30
|
LL | let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `unsafe { no(4) } & 1 != 0`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:190:9
+ --> $DIR/fixable.rs:188:9
|
LL | if unsafe { no(4) } & 1 != 0 { true } else { false }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`
diff --git a/src/tools/clippy/tests/ui/needless_bool/simple.stderr b/src/tools/clippy/tests/ui/needless_bool/simple.stderr
index 0ccc9416b..a44205c59 100644
--- a/src/tools/clippy/tests/ui/needless_bool/simple.stderr
+++ b/src/tools/clippy/tests/ui/needless_bool/simple.stderr
@@ -9,6 +9,7 @@ LL | | };
| |_____^
|
= note: `-D clippy::needless-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]`
error: this if-then-else expression will always return false
--> $DIR/simple.rs:19:5
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.fixed b/src/tools/clippy/tests/ui/needless_bool_assign.fixed
index 3ed31d4d7..7b10fe78c 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.fixed
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::needless_bool_assign)]
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.rs b/src/tools/clippy/tests/ui/needless_bool_assign.rs
index efaeb67fa..85c0a5777 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.rs
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::needless_bool_assign)]
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.stderr b/src/tools/clippy/tests/ui/needless_bool_assign.stderr
index 601bbed54..7866c89bd 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.stderr
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.stderr
@@ -1,5 +1,5 @@
error: this if-then-else expression assigns a bool literal
- --> $DIR/needless_bool_assign.rs:15:5
+ --> $DIR/needless_bool_assign.rs:13:5
|
LL | / if random() && random() {
LL | | a.field = true;
@@ -9,9 +9,10 @@ LL | | }
| |_____^ help: you can reduce it to: `a.field = random() && random();`
|
= note: `-D clippy::needless-bool-assign` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_bool_assign)]`
error: this if-then-else expression assigns a bool literal
- --> $DIR/needless_bool_assign.rs:20:5
+ --> $DIR/needless_bool_assign.rs:18:5
|
LL | / if random() && random() {
LL | | a.field = false;
@@ -21,7 +22,7 @@ LL | | }
| |_____^ help: you can reduce it to: `a.field = !(random() && random());`
error: this if-then-else expression assigns a bool literal
- --> $DIR/needless_bool_assign.rs:34:5
+ --> $DIR/needless_bool_assign.rs:32:5
|
LL | / if random() {
LL | | a.field = true;
@@ -31,7 +32,7 @@ LL | | }
| |_____^ help: you can reduce it to: `random(); a.field = true;`
error: this `if` has identical blocks
- --> $DIR/needless_bool_assign.rs:34:17
+ --> $DIR/needless_bool_assign.rs:32:17
|
LL | if random() {
| _________________^
@@ -40,7 +41,7 @@ LL | | } else {
| |_____^
|
note: same as this
- --> $DIR/needless_bool_assign.rs:36:12
+ --> $DIR/needless_bool_assign.rs:34:12
|
LL | } else {
| ____________^
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index 1dfbee150..c2c5f765a 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(lint_reasons)]
#![allow(
unused,
@@ -132,21 +131,6 @@ fn main() {
0
}
}
-
- let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
- let _ = std::path::Path::new(".").join(".");
- deref_target_is_x(X);
- multiple_constraints([[""]]);
- multiple_constraints_normalizes_to_same(X, X);
- let _ = Some("").unwrap_or("");
- let _ = std::fs::write("x", "".to_string());
-
- only_sized(&""); // Don't lint. `Sized` is only bound
- let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
- let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
- ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
- refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
- multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
}
#[allow(clippy::needless_borrowed_reference)]
@@ -202,103 +186,6 @@ mod issue9160 {
}
}
-#[derive(Clone, Copy)]
-struct X;
-
-impl std::ops::Deref for X {
- type Target = X;
- fn deref(&self) -> &Self::Target {
- self
- }
-}
-
-fn deref_target_is_x<T>(_: T)
-where
- T: std::ops::Deref<Target = X>,
-{
-}
-
-fn multiple_constraints<T, U, V, X, Y>(_: T)
-where
- T: IntoIterator<Item = U> + IntoIterator<Item = X>,
- U: IntoIterator<Item = V>,
- V: AsRef<str>,
- X: IntoIterator<Item = Y>,
- Y: AsRef<std::ffi::OsStr>,
-{
-}
-
-fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
-where
- T: std::ops::Deref<Target = U>,
- U: std::ops::Deref<Target = V>,
-{
-}
-
-fn only_sized<T>(_: T) {}
-
-fn ref_as_ref_path<T: 'static>(_: &'static T)
-where
- &'static T: AsRef<std::path::Path>,
-{
-}
-
-trait RefsOnly {
- type Referent;
-}
-
-impl<T> RefsOnly for &T {
- type Referent = T;
-}
-
-fn refs_only<T, U>(_: T)
-where
- T: RefsOnly<Referent = U>,
-{
-}
-
-fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
-where
- T: IntoIterator<Item = U>,
- U: IntoIterator<Item = V>,
- V: AsRef<str>,
-{
-}
-
-// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-mod copyable_iterator {
- #[derive(Clone, Copy)]
- struct Iter;
- impl Iterator for Iter {
- type Item = ();
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
- }
- fn takes_iter(_: impl Iterator) {}
- fn dont_warn(mut x: Iter) {
- takes_iter(&mut x);
- }
- #[allow(unused_mut)]
- fn warn(mut x: &mut Iter) {
- takes_iter(x)
- }
-}
-
-#[clippy::msrv = "1.52.0"]
-mod under_msrv {
- fn foo() {
- let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
- }
-}
-
-#[clippy::msrv = "1.53.0"]
-mod meets_msrv {
- fn foo() {
- let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
- }
-}
-
fn issue9383() {
// Should not lint because unions need explicit deref when accessing field
use std::mem::ManuallyDrop;
@@ -327,180 +214,15 @@ fn issue9383() {
}
}
-fn closure_test() {
- let env = "env".to_owned();
- let arg = "arg".to_owned();
- let f = |arg| {
- let loc = "loc".to_owned();
- let _ = std::fs::write("x", &env); // Don't lint. In environment
- let _ = std::fs::write("x", arg);
- let _ = std::fs::write("x", loc);
- };
- let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
- f(arg);
-}
-
-mod significant_drop {
- #[derive(Debug)]
- struct X;
-
- #[derive(Debug)]
- struct Y;
-
- impl Drop for Y {
- fn drop(&mut self) {}
- }
-
- fn foo(x: X, y: Y) {
- debug(x);
- debug(&y); // Don't lint. Has significant drop
- }
-
- fn debug(_: impl std::fmt::Debug) {}
-}
-
-mod used_exactly_once {
- fn foo(x: String) {
- use_x(x);
- }
- fn use_x(_: impl AsRef<str>) {}
-}
-
-mod used_more_than_once {
- fn foo(x: String) {
- use_x(&x);
- use_x_again(&x);
- }
- fn use_x(_: impl AsRef<str>) {}
- fn use_x_again(_: impl AsRef<str>) {}
-}
-
-// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
-mod issue_9111 {
- struct A;
-
- impl Extend<u8> for A {
- fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
- unimplemented!()
- }
- }
-
- impl<'a> Extend<&'a u8> for A {
- fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
- unimplemented!()
- }
- }
-
- fn main() {
- let mut a = A;
- a.extend(&[]); // vs a.extend([]);
- }
-}
-
-mod issue_9710 {
- fn main() {
- let string = String::new();
- for _i in 0..10 {
- f(&string);
- }
- }
-
- fn f<T: AsRef<str>>(_: T) {}
-}
-
-mod issue_9739 {
- fn foo<D: std::fmt::Display>(_it: impl IntoIterator<Item = D>) {}
-
- fn main() {
- foo(if std::env::var_os("HI").is_some() {
- &[0]
- } else {
- &[] as &[u32]
- });
- }
-}
-
-mod issue_9739_method_variant {
- struct S;
-
- impl S {
- fn foo<D: std::fmt::Display>(&self, _it: impl IntoIterator<Item = D>) {}
- }
-
- fn main() {
- S.foo(if std::env::var_os("HI").is_some() {
- &[0]
- } else {
- &[] as &[u32]
- });
- }
-}
-
-mod issue_9782 {
- fn foo<T: AsRef<[u8]>>(t: T) {
- println!("{}", std::mem::size_of::<T>());
- let _t: &[u8] = t.as_ref();
- }
-
- fn main() {
- let a: [u8; 100] = [0u8; 100];
-
- // 100
- foo::<[u8; 100]>(a);
- foo(a);
-
- // 16
- foo::<&[u8]>(&a);
- foo(a.as_slice());
-
- // 8
- foo::<&[u8; 100]>(&a);
- foo(a);
- }
-}
-
-mod issue_9782_type_relative_variant {
- struct S;
-
- impl S {
- fn foo<T: AsRef<[u8]>>(t: T) {
- println!("{}", std::mem::size_of::<T>());
- let _t: &[u8] = t.as_ref();
- }
- }
-
- fn main() {
- let a: [u8; 100] = [0u8; 100];
-
- S::foo::<&[u8; 100]>(&a);
- }
-}
-
-mod issue_9782_method_variant {
+mod issue_10253 {
struct S;
-
- impl S {
- fn foo<T: AsRef<[u8]>>(&self, t: T) {
- println!("{}", std::mem::size_of::<T>());
- let _t: &[u8] = t.as_ref();
- }
+ trait X {
+ fn f<T>(&self);
}
-
- fn main() {
- let a: [u8; 100] = [0u8; 100];
-
- S.foo::<&[u8; 100]>(&a);
+ impl X for &S {
+ fn f<T>(&self) {}
}
-}
-
-mod issue_10535 {
- static SOME_STATIC: String = String::new();
-
- static UNIT: () = compute(&SOME_STATIC);
-
- pub const fn compute<T>(_: T)
- where
- T: Copy,
- {
+ fn f() {
+ (&S).f::<()>();
}
}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 3c0d73f5f..0cd6e41b8 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(lint_reasons)]
#![allow(
unused,
@@ -132,21 +131,6 @@ fn main() {
0
}
}
-
- let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
- let _ = std::path::Path::new(".").join(&&".");
- deref_target_is_x(&X);
- multiple_constraints(&[[""]]);
- multiple_constraints_normalizes_to_same(&X, X);
- let _ = Some("").unwrap_or(&"");
- let _ = std::fs::write("x", &"".to_string());
-
- only_sized(&""); // Don't lint. `Sized` is only bound
- let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
- let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
- ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
- refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
- multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
}
#[allow(clippy::needless_borrowed_reference)]
@@ -202,103 +186,6 @@ mod issue9160 {
}
}
-#[derive(Clone, Copy)]
-struct X;
-
-impl std::ops::Deref for X {
- type Target = X;
- fn deref(&self) -> &Self::Target {
- self
- }
-}
-
-fn deref_target_is_x<T>(_: T)
-where
- T: std::ops::Deref<Target = X>,
-{
-}
-
-fn multiple_constraints<T, U, V, X, Y>(_: T)
-where
- T: IntoIterator<Item = U> + IntoIterator<Item = X>,
- U: IntoIterator<Item = V>,
- V: AsRef<str>,
- X: IntoIterator<Item = Y>,
- Y: AsRef<std::ffi::OsStr>,
-{
-}
-
-fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
-where
- T: std::ops::Deref<Target = U>,
- U: std::ops::Deref<Target = V>,
-{
-}
-
-fn only_sized<T>(_: T) {}
-
-fn ref_as_ref_path<T: 'static>(_: &'static T)
-where
- &'static T: AsRef<std::path::Path>,
-{
-}
-
-trait RefsOnly {
- type Referent;
-}
-
-impl<T> RefsOnly for &T {
- type Referent = T;
-}
-
-fn refs_only<T, U>(_: T)
-where
- T: RefsOnly<Referent = U>,
-{
-}
-
-fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
-where
- T: IntoIterator<Item = U>,
- U: IntoIterator<Item = V>,
- V: AsRef<str>,
-{
-}
-
-// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-mod copyable_iterator {
- #[derive(Clone, Copy)]
- struct Iter;
- impl Iterator for Iter {
- type Item = ();
- fn next(&mut self) -> Option<Self::Item> {
- None
- }
- }
- fn takes_iter(_: impl Iterator) {}
- fn dont_warn(mut x: Iter) {
- takes_iter(&mut x);
- }
- #[allow(unused_mut)]
- fn warn(mut x: &mut Iter) {
- takes_iter(&mut x)
- }
-}
-
-#[clippy::msrv = "1.52.0"]
-mod under_msrv {
- fn foo() {
- let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
- }
-}
-
-#[clippy::msrv = "1.53.0"]
-mod meets_msrv {
- fn foo() {
- let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
- }
-}
-
fn issue9383() {
// Should not lint because unions need explicit deref when accessing field
use std::mem::ManuallyDrop;
@@ -327,180 +214,15 @@ fn issue9383() {
}
}
-fn closure_test() {
- let env = "env".to_owned();
- let arg = "arg".to_owned();
- let f = |arg| {
- let loc = "loc".to_owned();
- let _ = std::fs::write("x", &env); // Don't lint. In environment
- let _ = std::fs::write("x", &arg);
- let _ = std::fs::write("x", &loc);
- };
- let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
- f(arg);
-}
-
-mod significant_drop {
- #[derive(Debug)]
- struct X;
-
- #[derive(Debug)]
- struct Y;
-
- impl Drop for Y {
- fn drop(&mut self) {}
- }
-
- fn foo(x: X, y: Y) {
- debug(&x);
- debug(&y); // Don't lint. Has significant drop
- }
-
- fn debug(_: impl std::fmt::Debug) {}
-}
-
-mod used_exactly_once {
- fn foo(x: String) {
- use_x(&x);
- }
- fn use_x(_: impl AsRef<str>) {}
-}
-
-mod used_more_than_once {
- fn foo(x: String) {
- use_x(&x);
- use_x_again(&x);
- }
- fn use_x(_: impl AsRef<str>) {}
- fn use_x_again(_: impl AsRef<str>) {}
-}
-
-// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
-mod issue_9111 {
- struct A;
-
- impl Extend<u8> for A {
- fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
- unimplemented!()
- }
- }
-
- impl<'a> Extend<&'a u8> for A {
- fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
- unimplemented!()
- }
- }
-
- fn main() {
- let mut a = A;
- a.extend(&[]); // vs a.extend([]);
- }
-}
-
-mod issue_9710 {
- fn main() {
- let string = String::new();
- for _i in 0..10 {
- f(&string);
- }
- }
-
- fn f<T: AsRef<str>>(_: T) {}
-}
-
-mod issue_9739 {
- fn foo<D: std::fmt::Display>(_it: impl IntoIterator<Item = D>) {}
-
- fn main() {
- foo(if std::env::var_os("HI").is_some() {
- &[0]
- } else {
- &[] as &[u32]
- });
- }
-}
-
-mod issue_9739_method_variant {
- struct S;
-
- impl S {
- fn foo<D: std::fmt::Display>(&self, _it: impl IntoIterator<Item = D>) {}
- }
-
- fn main() {
- S.foo(if std::env::var_os("HI").is_some() {
- &[0]
- } else {
- &[] as &[u32]
- });
- }
-}
-
-mod issue_9782 {
- fn foo<T: AsRef<[u8]>>(t: T) {
- println!("{}", std::mem::size_of::<T>());
- let _t: &[u8] = t.as_ref();
- }
-
- fn main() {
- let a: [u8; 100] = [0u8; 100];
-
- // 100
- foo::<[u8; 100]>(a);
- foo(a);
-
- // 16
- foo::<&[u8]>(&a);
- foo(a.as_slice());
-
- // 8
- foo::<&[u8; 100]>(&a);
- foo(&a);
- }
-}
-
-mod issue_9782_type_relative_variant {
- struct S;
-
- impl S {
- fn foo<T: AsRef<[u8]>>(t: T) {
- println!("{}", std::mem::size_of::<T>());
- let _t: &[u8] = t.as_ref();
- }
- }
-
- fn main() {
- let a: [u8; 100] = [0u8; 100];
-
- S::foo::<&[u8; 100]>(&a);
- }
-}
-
-mod issue_9782_method_variant {
+mod issue_10253 {
struct S;
-
- impl S {
- fn foo<T: AsRef<[u8]>>(&self, t: T) {
- println!("{}", std::mem::size_of::<T>());
- let _t: &[u8] = t.as_ref();
- }
+ trait X {
+ fn f<T>(&self);
}
-
- fn main() {
- let a: [u8; 100] = [0u8; 100];
-
- S.foo::<&[u8; 100]>(&a);
+ impl X for &S {
+ fn f<T>(&self) {}
}
-}
-
-mod issue_10535 {
- static SOME_STATIC: String = String::new();
-
- static UNIT: () = compute(&SOME_STATIC);
-
- pub const fn compute<T>(_: T)
- where
- T: Copy,
- {
+ fn f() {
+ (&S).f::<()>();
}
}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index f85b4fb46..e91b78b0a 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -1,220 +1,137 @@
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:16:15
+ --> $DIR/needless_borrow.rs:15:15
|
LL | let _ = x(&&a); // warn
| ^^^ help: change this to: `&a`
|
= note: `-D clippy::needless-borrow` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:20:13
+ --> $DIR/needless_borrow.rs:19:13
|
LL | mut_ref(&mut &mut b); // warn
| ^^^^^^^^^^^ help: change this to: `&mut b`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:32:13
+ --> $DIR/needless_borrow.rs:31:13
|
LL | &&a
| ^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:34:15
+ --> $DIR/needless_borrow.rs:33:15
|
LL | 46 => &&a,
| ^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:40:27
+ --> $DIR/needless_borrow.rs:39:27
|
LL | break &ref_a;
| ^^^^^^ help: change this to: `ref_a`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:47:15
+ --> $DIR/needless_borrow.rs:46:15
|
LL | let _ = x(&&&a);
| ^^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:48:15
+ --> $DIR/needless_borrow.rs:47:15
|
LL | let _ = x(&mut &&a);
| ^^^^^^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:49:15
+ --> $DIR/needless_borrow.rs:48:15
|
LL | let _ = x(&&&mut b);
| ^^^^^^^^ help: change this to: `&mut b`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:50:15
+ --> $DIR/needless_borrow.rs:49:15
|
LL | let _ = x(&&ref_a);
| ^^^^^^^ help: change this to: `ref_a`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:53:11
+ --> $DIR/needless_borrow.rs:52:11
|
LL | x(&b);
| ^^ help: change this to: `b`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:60:13
+ --> $DIR/needless_borrow.rs:59:13
|
LL | mut_ref(&mut x);
| ^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:61:13
+ --> $DIR/needless_borrow.rs:60:13
|
LL | mut_ref(&mut &mut x);
| ^^^^^^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:62:23
+ --> $DIR/needless_borrow.rs:61:23
|
LL | let y: &mut i32 = &mut x;
| ^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:63:23
+ --> $DIR/needless_borrow.rs:62:23
|
LL | let y: &mut i32 = &mut &mut x;
| ^^^^^^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:72:14
+ --> $DIR/needless_borrow.rs:71:14
|
LL | 0 => &mut x,
| ^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:78:14
+ --> $DIR/needless_borrow.rs:77:14
|
LL | 0 => &mut x,
| ^^^^^^ help: change this to: `x`
error: this expression borrows a value the compiler would automatically borrow
- --> $DIR/needless_borrow.rs:90:13
+ --> $DIR/needless_borrow.rs:89:13
|
LL | let _ = (&x).0;
| ^^^^ help: change this to: `x`
error: this expression borrows a value the compiler would automatically borrow
- --> $DIR/needless_borrow.rs:92:22
+ --> $DIR/needless_borrow.rs:91:22
|
LL | let _ = unsafe { (&*x).0 };
| ^^^^^ help: change this to: `(*x)`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:102:5
+ --> $DIR/needless_borrow.rs:101:5
|
LL | (&&()).foo();
| ^^^^^^ help: change this to: `(&())`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:111:5
+ --> $DIR/needless_borrow.rs:110:5
|
LL | (&&5).foo();
| ^^^^^ help: change this to: `(&5)`
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:136:51
- |
-LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
- | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:137:44
- |
-LL | let _ = std::path::Path::new(".").join(&&".");
- | ^^^^^ help: change this to: `"."`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:138:23
- |
-LL | deref_target_is_x(&X);
- | ^^ help: change this to: `X`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:139:26
- |
-LL | multiple_constraints(&[[""]]);
- | ^^^^^^^ help: change this to: `[[""]]`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:140:45
- |
-LL | multiple_constraints_normalizes_to_same(&X, X);
- | ^^ help: change this to: `X`
-
-error: this expression creates a reference which is immediately dereferenced by the compiler
- --> $DIR/needless_borrow.rs:141:32
- |
-LL | let _ = Some("").unwrap_or(&"");
- | ^^^ help: change this to: `""`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:142:33
- |
-LL | let _ = std::fs::write("x", &"".to_string());
- | ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()`
-
error: this expression borrows a value the compiler would automatically borrow
- --> $DIR/needless_borrow.rs:191:13
+ --> $DIR/needless_borrow.rs:175:13
|
LL | (&self.f)()
| ^^^^^^^^^ help: change this to: `(self.f)`
error: this expression borrows a value the compiler would automatically borrow
- --> $DIR/needless_borrow.rs:200:13
+ --> $DIR/needless_borrow.rs:184:13
|
LL | (&mut self.f)()
| ^^^^^^^^^^^^^ help: change this to: `(self.f)`
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:284:20
- |
-LL | takes_iter(&mut x)
- | ^^^^^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:298:55
- |
-LL | let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
- | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:336:37
- |
-LL | let _ = std::fs::write("x", &arg);
- | ^^^^ help: change this to: `arg`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:337:37
- |
-LL | let _ = std::fs::write("x", &loc);
- | ^^^^ help: change this to: `loc`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:355:15
- |
-LL | debug(&x);
- | ^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:364:15
- |
-LL | use_x(&x);
- | ^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:458:13
- |
-LL | foo(&a);
- | ^^ help: change this to: `a`
-
-error: aborting due to 36 previous errors
+error: aborting due to 22 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.fixed b/src/tools/clippy/tests/ui/needless_borrow_pat.fixed
new file mode 100644
index 000000000..8f8887f08
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrow_pat.fixed
@@ -0,0 +1,163 @@
+// FIXME: run-rustfix waiting on multi-span suggestions
+
+#![warn(clippy::needless_borrow)]
+#![allow(clippy::needless_borrowed_reference, clippy::explicit_auto_deref)]
+
+fn f1(_: &str) {}
+macro_rules! m1 {
+ ($e:expr) => {
+ f1($e)
+ };
+}
+macro_rules! m3 {
+ ($i:ident) => {
+ Some(ref $i)
+ };
+}
+macro_rules! if_chain {
+ (if $e:expr; $($rest:tt)*) => {
+ if $e {
+ if_chain!($($rest)*)
+ }
+ };
+
+ (if let $p:pat = $e:expr; $($rest:tt)*) => {
+ if let $p = $e {
+ if_chain!($($rest)*)
+ }
+ };
+
+ (then $b:block) => {
+ $b
+ };
+}
+
+#[allow(dead_code)]
+fn main() {
+ let x = String::new();
+
+ // Ok, reference to a String.
+ let _: &String = match Some(x.clone()) {
+ Some(ref x) => x,
+ None => return,
+ };
+
+ // Ok, reference to a &mut String
+ let _: &&mut String = match Some(&mut x.clone()) {
+ Some(ref x) => x,
+ None => return,
+ };
+
+ // Ok, the pattern is from a macro
+ let _: &String = match Some(&x) {
+ m3!(x) => x,
+ None => return,
+ };
+
+ // Err, reference to a &String
+ let _: &String = match Some(&x) {
+ Some(x) => x,
+ //~^ ERROR: this pattern creates a reference to a reference
+ //~| NOTE: `-D clippy::needless-borrow` implied by `-D warnings`
+ None => return,
+ };
+
+ // Err, reference to a &String.
+ let _: &String = match Some(&x) {
+ Some(x) => x,
+ //~^ ERROR: this pattern creates a reference to a reference
+ None => return,
+ };
+
+ // Err, reference to a &String
+ let _: &String = match Some(&x) {
+ Some(x) => {
+ //~^ ERROR: this pattern creates a reference to a reference
+ f1(x);
+ f1(x);
+ x
+ },
+ None => return,
+ };
+
+ // Err, reference to a &String
+ match Some(&x) {
+ Some(x) => m1!(x),
+ //~^ ERROR: this pattern creates a reference to a reference
+ None => return,
+ };
+
+ // Err, reference to a &String
+ let _ = |&x: &&String| {
+ //~^ ERROR: this pattern creates a reference to a reference
+ let _: &String = x;
+ };
+
+ // Err, reference to a &String
+ let (y,) = (&x,);
+ //~^ ERROR: this pattern creates a reference to a reference
+ let _: &String = y;
+
+ let y = &&x;
+ // Ok, different y
+ let _: &String = *y;
+
+ let x = (0, 0);
+ // Err, reference to a &u32. Don't suggest adding a reference to the field access.
+ let _: u32 = match Some(&x) {
+ Some(x) => x.0,
+ //~^ ERROR: this pattern creates a reference to a reference
+ None => return,
+ };
+
+ enum E {
+ A(&'static u32),
+ B(&'static u32),
+ }
+ // Err, reference to &u32.
+ let _: &u32 = match E::A(&0) {
+ E::A(x) | E::B(x) => x,
+ //~^ ERROR: this pattern creates a reference to a reference
+ };
+
+ // Err, reference to &String.
+ if_chain! {
+ if true;
+ if let Some(x) = Some(&String::new());
+ //~^ ERROR: this pattern creates a reference to a reference
+ then {
+ f1(x);
+ }
+ }
+}
+
+// Err, reference to a &String
+fn f2<'a>(&x: &&'a String) -> &'a String {
+ //~^ ERROR: this pattern creates a reference to a reference
+ let _: &String = x;
+ x
+}
+
+trait T1 {
+ // Err, reference to a &String
+ fn f(&x: &&String) {
+ //~^ ERROR: this pattern creates a reference to a reference
+ let _: &String = x;
+ }
+}
+
+struct S;
+impl T1 for S {
+ // Err, reference to a &String
+ fn f(&x: &&String) {
+ //~^ ERROR: this pattern creates a reference to a reference
+ let _: &String = x;
+ }
+}
+
+// Ok - used to error due to rustc bug
+#[allow(dead_code)]
+#[derive(Debug)]
+enum Foo<'a> {
+ Str(&'a str),
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.rs b/src/tools/clippy/tests/ui/needless_borrow_pat.rs
index 222e8e617..56dbd923f 100644
--- a/src/tools/clippy/tests/ui/needless_borrow_pat.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow_pat.rs
@@ -57,18 +57,22 @@ fn main() {
// Err, reference to a &String
let _: &String = match Some(&x) {
Some(ref x) => x,
+ //~^ ERROR: this pattern creates a reference to a reference
+ //~| NOTE: `-D clippy::needless-borrow` implied by `-D warnings`
None => return,
};
// Err, reference to a &String.
let _: &String = match Some(&x) {
Some(ref x) => *x,
+ //~^ ERROR: this pattern creates a reference to a reference
None => return,
};
// Err, reference to a &String
let _: &String = match Some(&x) {
Some(ref x) => {
+ //~^ ERROR: this pattern creates a reference to a reference
f1(x);
f1(*x);
x
@@ -79,16 +83,19 @@ fn main() {
// Err, reference to a &String
match Some(&x) {
Some(ref x) => m1!(x),
+ //~^ ERROR: this pattern creates a reference to a reference
None => return,
};
// Err, reference to a &String
let _ = |&ref x: &&String| {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &String = x;
};
// Err, reference to a &String
let (ref y,) = (&x,);
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &String = *y;
let y = &&x;
@@ -99,6 +106,7 @@ fn main() {
// Err, reference to a &u32. Don't suggest adding a reference to the field access.
let _: u32 = match Some(&x) {
Some(ref x) => x.0,
+ //~^ ERROR: this pattern creates a reference to a reference
None => return,
};
@@ -109,12 +117,14 @@ fn main() {
// Err, reference to &u32.
let _: &u32 = match E::A(&0) {
E::A(ref x) | E::B(ref x) => *x,
+ //~^ ERROR: this pattern creates a reference to a reference
};
// Err, reference to &String.
if_chain! {
if true;
if let Some(ref x) = Some(&String::new());
+ //~^ ERROR: this pattern creates a reference to a reference
then {
f1(x);
}
@@ -123,6 +133,7 @@ fn main() {
// Err, reference to a &String
fn f2<'a>(&ref x: &&'a String) -> &'a String {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &String = x;
*x
}
@@ -130,6 +141,7 @@ fn f2<'a>(&ref x: &&'a String) -> &'a String {
trait T1 {
// Err, reference to a &String
fn f(&ref x: &&String) {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &String = x;
}
}
@@ -138,6 +150,7 @@ struct S;
impl T1 for S {
// Err, reference to a &String
fn f(&ref x: &&String) {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &String = *x;
}
}
diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.stderr b/src/tools/clippy/tests/ui/needless_borrow_pat.stderr
index 2d9b8f159..ce3a36e35 100644
--- a/src/tools/clippy/tests/ui/needless_borrow_pat.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow_pat.stderr
@@ -5,9 +5,10 @@ LL | Some(ref x) => x,
| ^^^^^ help: try: `x`
|
= note: `-D clippy::needless-borrow` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:65:14
+ --> $DIR/needless_borrow_pat.rs:67:14
|
LL | Some(ref x) => *x,
| ^^^^^
@@ -18,7 +19,7 @@ LL | Some(x) => x,
| ~ ~
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:71:14
+ --> $DIR/needless_borrow_pat.rs:74:14
|
LL | Some(ref x) => {
| ^^^^^
@@ -26,24 +27,25 @@ LL | Some(ref x) => {
help: try
|
LL ~ Some(x) => {
+LL |
LL | f1(x);
LL ~ f1(x);
|
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:81:14
+ --> $DIR/needless_borrow_pat.rs:85:14
|
LL | Some(ref x) => m1!(x),
| ^^^^^ help: try: `x`
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:86:15
+ --> $DIR/needless_borrow_pat.rs:91:15
|
LL | let _ = |&ref x: &&String| {
| ^^^^^ help: try: `x`
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:91:10
+ --> $DIR/needless_borrow_pat.rs:97:10
|
LL | let (ref y,) = (&x,);
| ^^^^^
@@ -51,17 +53,18 @@ LL | let (ref y,) = (&x,);
help: try
|
LL ~ let (y,) = (&x,);
+LL |
LL ~ let _: &String = y;
|
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:101:14
+ --> $DIR/needless_borrow_pat.rs:108:14
|
LL | Some(ref x) => x.0,
| ^^^^^ help: try: `x`
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:111:14
+ --> $DIR/needless_borrow_pat.rs:119:14
|
LL | E::A(ref x) | E::B(ref x) => *x,
| ^^^^^ ^^^^^
@@ -72,13 +75,13 @@ LL | E::A(x) | E::B(x) => x,
| ~ ~ ~
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:117:21
+ --> $DIR/needless_borrow_pat.rs:126:21
|
LL | if let Some(ref x) = Some(&String::new());
| ^^^^^ help: try: `x`
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:125:12
+ --> $DIR/needless_borrow_pat.rs:135:12
|
LL | fn f2<'a>(&ref x: &&'a String) -> &'a String {
| ^^^^^
@@ -86,18 +89,19 @@ LL | fn f2<'a>(&ref x: &&'a String) -> &'a String {
help: try
|
LL ~ fn f2<'a>(&x: &&'a String) -> &'a String {
+LL |
LL | let _: &String = x;
LL ~ x
|
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:132:11
+ --> $DIR/needless_borrow_pat.rs:143:11
|
LL | fn f(&ref x: &&String) {
| ^^^^^ help: try: `x`
error: this pattern creates a reference to a reference
- --> $DIR/needless_borrow_pat.rs:140:11
+ --> $DIR/needless_borrow_pat.rs:152:11
|
LL | fn f(&ref x: &&String) {
| ^^^^^
@@ -105,6 +109,7 @@ LL | fn f(&ref x: &&String) {
help: try
|
LL ~ fn f(&x: &&String) {
+LL |
LL ~ let _: &String = x;
|
diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed b/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed
index 59a38425b..5d2fd0950 100644
--- a/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_borrowed_reference)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.rs b/src/tools/clippy/tests/ui/needless_borrowed_ref.rs
index e48b19cb1..556fd3a35 100644
--- a/src/tools/clippy/tests/ui/needless_borrowed_ref.rs
+++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_borrowed_reference)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr b/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr
index 35497a01e..15261cfce 100644
--- a/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr
@@ -1,10 +1,11 @@
error: this pattern takes a reference on something that is being dereferenced
- --> $DIR/needless_borrowed_ref.rs:32:34
+ --> $DIR/needless_borrowed_ref.rs:30:34
|
LL | let _ = v.iter_mut().filter(|&ref a| a.is_empty());
| ^^^^^^
|
= note: `-D clippy::needless-borrowed-reference` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_borrowed_reference)]`
help: try removing the `&ref` part
|
LL - let _ = v.iter_mut().filter(|&ref a| a.is_empty());
@@ -12,7 +13,7 @@ LL + let _ = v.iter_mut().filter(|a| a.is_empty());
|
error: this pattern takes a reference on something that is being dereferenced
- --> $DIR/needless_borrowed_ref.rs:36:17
+ --> $DIR/needless_borrowed_ref.rs:34:17
|
LL | if let Some(&ref v) = thingy {}
| ^^^^^^
@@ -24,7 +25,7 @@ LL + if let Some(v) = thingy {}
|
error: this pattern takes a reference on something that is being dereferenced
- --> $DIR/needless_borrowed_ref.rs:38:14
+ --> $DIR/needless_borrowed_ref.rs:36:14
|
LL | if let &[&ref a, ref b] = slice_of_refs {}
| ^^^^^^
@@ -36,7 +37,7 @@ LL + if let &[a, ref b] = slice_of_refs {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:40:9
+ --> $DIR/needless_borrowed_ref.rs:38:9
|
LL | let &[ref a, ..] = &array;
| ^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL + let [a, ..] = &array;
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:41:9
+ --> $DIR/needless_borrowed_ref.rs:39:9
|
LL | let &[ref a, ref b, ..] = &array;
| ^^^^^^^^^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL + let [a, b, ..] = &array;
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:43:12
+ --> $DIR/needless_borrowed_ref.rs:41:12
|
LL | if let &[ref a, ref b] = slice {}
| ^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL + if let [a, b] = slice {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:44:12
+ --> $DIR/needless_borrowed_ref.rs:42:12
|
LL | if let &[ref a, ref b] = &vec[..] {}
| ^^^^^^^^^^^^^^^
@@ -84,7 +85,7 @@ LL + if let [a, b] = &vec[..] {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:46:12
+ --> $DIR/needless_borrowed_ref.rs:44:12
|
LL | if let &[ref a, ref b, ..] = slice {}
| ^^^^^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL + if let [a, b, ..] = slice {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:47:12
+ --> $DIR/needless_borrowed_ref.rs:45:12
|
LL | if let &[ref a, .., ref b] = slice {}
| ^^^^^^^^^^^^^^^^^^^
@@ -108,7 +109,7 @@ LL + if let [a, .., b] = slice {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:48:12
+ --> $DIR/needless_borrowed_ref.rs:46:12
|
LL | if let &[.., ref a, ref b] = slice {}
| ^^^^^^^^^^^^^^^^^^^
@@ -120,7 +121,7 @@ LL + if let [.., a, b] = slice {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:50:12
+ --> $DIR/needless_borrowed_ref.rs:48:12
|
LL | if let &[ref a, _] = slice {}
| ^^^^^^^^^^^
@@ -132,7 +133,7 @@ LL + if let [a, _] = slice {}
|
error: dereferencing a tuple pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:52:12
+ --> $DIR/needless_borrowed_ref.rs:50:12
|
LL | if let &(ref a, ref b, ref c) = &tuple {}
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +145,7 @@ LL + if let (a, b, c) = &tuple {}
|
error: dereferencing a tuple pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:53:12
+ --> $DIR/needless_borrowed_ref.rs:51:12
|
LL | if let &(ref a, _, ref c) = &tuple {}
| ^^^^^^^^^^^^^^^^^^
@@ -156,7 +157,7 @@ LL + if let (a, _, c) = &tuple {}
|
error: dereferencing a tuple pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:54:12
+ --> $DIR/needless_borrowed_ref.rs:52:12
|
LL | if let &(ref a, ..) = &tuple {}
| ^^^^^^^^^^^^
@@ -168,7 +169,7 @@ LL + if let (a, ..) = &tuple {}
|
error: dereferencing a tuple pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:56:12
+ --> $DIR/needless_borrowed_ref.rs:54:12
|
LL | if let &TupleStruct(ref a, ..) = &tuple_struct {}
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -180,7 +181,7 @@ LL + if let TupleStruct(a, ..) = &tuple_struct {}
|
error: dereferencing a struct pattern where every field's pattern takes a reference
- --> $DIR/needless_borrowed_ref.rs:58:12
+ --> $DIR/needless_borrowed_ref.rs:56:12
|
LL | if let &Struct {
| ____________^
@@ -199,7 +200,7 @@ LL ~ c: renamed,
|
error: dereferencing a struct pattern where every field's pattern takes a reference
- --> $DIR/needless_borrowed_ref.rs:65:12
+ --> $DIR/needless_borrowed_ref.rs:63:12
|
LL | if let &Struct { ref a, b: _, .. } = &s {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
new file mode 100644
index 000000000..2a335516f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
@@ -0,0 +1,287 @@
+#![warn(clippy::needless_borrows_for_generic_args)]
+#![allow(
+ clippy::unnecessary_to_owned,
+ clippy::unnecessary_literal_unwrap,
+ clippy::needless_borrow
+)]
+
+use core::ops::Deref;
+use std::any::Any;
+use std::ffi::OsStr;
+use std::fmt::{Debug, Display};
+use std::path::Path;
+use std::process::Command;
+
+fn main() {
+ let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap();
+ let _ = Path::new(".").join(".");
+ let _ = Any::type_id(&""); // Don't lint. `Any` is only bound
+ let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+ let _ = Some("").unwrap_or(&"");
+ let _ = std::fs::write("x", "".to_string());
+
+ {
+ #[derive(Clone, Copy)]
+ struct X;
+
+ impl Deref for X {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+ }
+
+ fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}
+
+ deref_target_is_x(X);
+ }
+ {
+ fn multiple_constraints<T, U, V, X, Y>(_: T)
+ where
+ T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+ X: IntoIterator<Item = Y>,
+ Y: AsRef<OsStr>,
+ {
+ }
+
+ multiple_constraints([[""]]);
+ }
+ {
+ #[derive(Clone, Copy)]
+ struct X;
+
+ impl Deref for X {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+ }
+
+ fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+ where
+ T: Deref<Target = U>,
+ U: Deref<Target = V>,
+ {
+ }
+
+ multiple_constraints_normalizes_to_same(X, X);
+ }
+ {
+ fn only_sized<T>(_: T) {}
+ only_sized(&""); // Don't lint. `Sized` is only bound
+ }
+ {
+ fn ref_as_ref_path<T: 'static>(_: &'static T)
+ where
+ &'static T: AsRef<Path>,
+ {
+ }
+
+ ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+ }
+ {
+ trait RefsOnly {
+ type Referent;
+ }
+
+ impl<T> RefsOnly for &T {
+ type Referent = T;
+ }
+
+ fn refs_only<T, U>(_: T)
+ where
+ T: RefsOnly<Referent = U>,
+ {
+ }
+
+ refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+ }
+ {
+ fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+ where
+ T: IntoIterator<Item = U>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+ {
+ }
+ multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
+ }
+ // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+ {
+ #[derive(Clone, Copy)]
+ struct Iter;
+ impl Iterator for Iter {
+ type Item = ();
+ fn next(&mut self) -> Option<Self::Item> {
+ None
+ }
+ }
+ fn takes_iter(_: impl Iterator) {}
+ fn dont_warn(mut x: Iter) {
+ takes_iter(&mut x);
+ }
+ #[allow(unused_mut)]
+ fn warn(mut x: &mut Iter) {
+ takes_iter(x)
+ }
+ }
+ #[clippy::msrv = "1.52.0"]
+ {
+ let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ };
+ #[clippy::msrv = "1.53.0"]
+ {
+ let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap();
+ };
+ {
+ let env = "env".to_owned();
+ let arg = "arg".to_owned();
+ let f = |arg| {
+ let loc = "loc".to_owned();
+ let _ = std::fs::write("x", &env); // Don't lint. In environment
+ let _ = std::fs::write("x", arg);
+ let _ = std::fs::write("x", loc);
+ };
+ let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
+ f(arg);
+ }
+ {
+ #[derive(Debug)]
+ struct X;
+
+ impl Drop for X {
+ fn drop(&mut self) {}
+ }
+
+ fn f(_: impl Debug) {}
+
+ let x = X;
+ f(&x); // Don't lint. Has significant drop
+ }
+ {
+ fn f(_: impl AsRef<str>) {}
+
+ let x = String::new();
+ f(x);
+ }
+ {
+ fn f(_: impl AsRef<str>) {}
+ fn f2(_: impl AsRef<str>) {}
+
+ let x = String::new();
+ f(&x);
+ f2(&x);
+ }
+ // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
+ // issue 9111
+ {
+ struct A;
+
+ impl Extend<u8> for A {
+ fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
+ unimplemented!()
+ }
+ }
+
+ impl<'a> Extend<&'a u8> for A {
+ fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
+ unimplemented!()
+ }
+ }
+
+ let mut a = A;
+ a.extend(&[]); // vs a.extend([]);
+ }
+ // issue 9710
+ {
+ fn f(_: impl AsRef<str>) {}
+
+ let x = String::new();
+ for _ in 0..10 {
+ f(&x);
+ }
+ }
+ // issue 9739
+ {
+ fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}
+ foo(if std::env::var_os("HI").is_some() {
+ &[0]
+ } else {
+ &[] as &[u32]
+ });
+ }
+ {
+ struct S;
+
+ impl S {
+ fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}
+ }
+
+ S.foo(if std::env::var_os("HI").is_some() {
+ &[0]
+ } else {
+ &[] as &[u32]
+ });
+ }
+ // issue 9782
+ {
+ fn foo<T: AsRef<[u8]>>(t: T) {
+ println!("{}", std::mem::size_of::<T>());
+ let _t: &[u8] = t.as_ref();
+ }
+
+ let a: [u8; 100] = [0u8; 100];
+
+ // 100
+ foo::<[u8; 100]>(a);
+ foo(a);
+
+ // 16
+ foo::<&[u8]>(&a);
+ foo(a.as_slice());
+
+ // 8
+ foo::<&[u8; 100]>(&a);
+ foo(a);
+ }
+ {
+ struct S;
+
+ impl S {
+ fn foo<T: AsRef<[u8]>>(t: T) {
+ println!("{}", std::mem::size_of::<T>());
+ let _t: &[u8] = t.as_ref();
+ }
+ }
+
+ let a: [u8; 100] = [0u8; 100];
+ S::foo::<&[u8; 100]>(&a);
+ }
+ {
+ struct S;
+
+ impl S {
+ fn foo<T: AsRef<[u8]>>(&self, t: T) {
+ println!("{}", std::mem::size_of::<T>());
+ let _t: &[u8] = t.as_ref();
+ }
+ }
+
+ let a: [u8; 100] = [0u8; 100];
+ S.foo::<&[u8; 100]>(&a);
+ }
+ // issue 10535
+ {
+ static SOME_STATIC: String = String::new();
+
+ static UNIT: () = compute(&SOME_STATIC);
+
+ pub const fn compute<T>(_: T)
+ where
+ T: Copy,
+ {
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
new file mode 100644
index 000000000..f0567f486
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
@@ -0,0 +1,287 @@
+#![warn(clippy::needless_borrows_for_generic_args)]
+#![allow(
+ clippy::unnecessary_to_owned,
+ clippy::unnecessary_literal_unwrap,
+ clippy::needless_borrow
+)]
+
+use core::ops::Deref;
+use std::any::Any;
+use std::ffi::OsStr;
+use std::fmt::{Debug, Display};
+use std::path::Path;
+use std::process::Command;
+
+fn main() {
+ let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ let _ = Path::new(".").join(&&".");
+ let _ = Any::type_id(&""); // Don't lint. `Any` is only bound
+ let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+ let _ = Some("").unwrap_or(&"");
+ let _ = std::fs::write("x", &"".to_string());
+
+ {
+ #[derive(Clone, Copy)]
+ struct X;
+
+ impl Deref for X {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+ }
+
+ fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}
+
+ deref_target_is_x(&X);
+ }
+ {
+ fn multiple_constraints<T, U, V, X, Y>(_: T)
+ where
+ T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+ X: IntoIterator<Item = Y>,
+ Y: AsRef<OsStr>,
+ {
+ }
+
+ multiple_constraints(&[[""]]);
+ }
+ {
+ #[derive(Clone, Copy)]
+ struct X;
+
+ impl Deref for X {
+ type Target = X;
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+ }
+
+ fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+ where
+ T: Deref<Target = U>,
+ U: Deref<Target = V>,
+ {
+ }
+
+ multiple_constraints_normalizes_to_same(&X, X);
+ }
+ {
+ fn only_sized<T>(_: T) {}
+ only_sized(&""); // Don't lint. `Sized` is only bound
+ }
+ {
+ fn ref_as_ref_path<T: 'static>(_: &'static T)
+ where
+ &'static T: AsRef<Path>,
+ {
+ }
+
+ ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+ }
+ {
+ trait RefsOnly {
+ type Referent;
+ }
+
+ impl<T> RefsOnly for &T {
+ type Referent = T;
+ }
+
+ fn refs_only<T, U>(_: T)
+ where
+ T: RefsOnly<Referent = U>,
+ {
+ }
+
+ refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+ }
+ {
+ fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+ where
+ T: IntoIterator<Item = U>,
+ U: IntoIterator<Item = V>,
+ V: AsRef<str>,
+ {
+ }
+ multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
+ }
+ // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+ {
+ #[derive(Clone, Copy)]
+ struct Iter;
+ impl Iterator for Iter {
+ type Item = ();
+ fn next(&mut self) -> Option<Self::Item> {
+ None
+ }
+ }
+ fn takes_iter(_: impl Iterator) {}
+ fn dont_warn(mut x: Iter) {
+ takes_iter(&mut x);
+ }
+ #[allow(unused_mut)]
+ fn warn(mut x: &mut Iter) {
+ takes_iter(&mut x)
+ }
+ }
+ #[clippy::msrv = "1.52.0"]
+ {
+ let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ };
+ #[clippy::msrv = "1.53.0"]
+ {
+ let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ };
+ {
+ let env = "env".to_owned();
+ let arg = "arg".to_owned();
+ let f = |arg| {
+ let loc = "loc".to_owned();
+ let _ = std::fs::write("x", &env); // Don't lint. In environment
+ let _ = std::fs::write("x", &arg);
+ let _ = std::fs::write("x", &loc);
+ };
+ let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
+ f(arg);
+ }
+ {
+ #[derive(Debug)]
+ struct X;
+
+ impl Drop for X {
+ fn drop(&mut self) {}
+ }
+
+ fn f(_: impl Debug) {}
+
+ let x = X;
+ f(&x); // Don't lint. Has significant drop
+ }
+ {
+ fn f(_: impl AsRef<str>) {}
+
+ let x = String::new();
+ f(&x);
+ }
+ {
+ fn f(_: impl AsRef<str>) {}
+ fn f2(_: impl AsRef<str>) {}
+
+ let x = String::new();
+ f(&x);
+ f2(&x);
+ }
+ // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
+ // issue 9111
+ {
+ struct A;
+
+ impl Extend<u8> for A {
+ fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
+ unimplemented!()
+ }
+ }
+
+ impl<'a> Extend<&'a u8> for A {
+ fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
+ unimplemented!()
+ }
+ }
+
+ let mut a = A;
+ a.extend(&[]); // vs a.extend([]);
+ }
+ // issue 9710
+ {
+ fn f(_: impl AsRef<str>) {}
+
+ let x = String::new();
+ for _ in 0..10 {
+ f(&x);
+ }
+ }
+ // issue 9739
+ {
+ fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}
+ foo(if std::env::var_os("HI").is_some() {
+ &[0]
+ } else {
+ &[] as &[u32]
+ });
+ }
+ {
+ struct S;
+
+ impl S {
+ fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}
+ }
+
+ S.foo(if std::env::var_os("HI").is_some() {
+ &[0]
+ } else {
+ &[] as &[u32]
+ });
+ }
+ // issue 9782
+ {
+ fn foo<T: AsRef<[u8]>>(t: T) {
+ println!("{}", std::mem::size_of::<T>());
+ let _t: &[u8] = t.as_ref();
+ }
+
+ let a: [u8; 100] = [0u8; 100];
+
+ // 100
+ foo::<[u8; 100]>(a);
+ foo(a);
+
+ // 16
+ foo::<&[u8]>(&a);
+ foo(a.as_slice());
+
+ // 8
+ foo::<&[u8; 100]>(&a);
+ foo(&a);
+ }
+ {
+ struct S;
+
+ impl S {
+ fn foo<T: AsRef<[u8]>>(t: T) {
+ println!("{}", std::mem::size_of::<T>());
+ let _t: &[u8] = t.as_ref();
+ }
+ }
+
+ let a: [u8; 100] = [0u8; 100];
+ S::foo::<&[u8; 100]>(&a);
+ }
+ {
+ struct S;
+
+ impl S {
+ fn foo<T: AsRef<[u8]>>(&self, t: T) {
+ println!("{}", std::mem::size_of::<T>());
+ let _t: &[u8] = t.as_ref();
+ }
+ }
+
+ let a: [u8; 100] = [0u8; 100];
+ S.foo::<&[u8; 100]>(&a);
+ }
+ // issue 10535
+ {
+ static SOME_STATIC: String = String::new();
+
+ static UNIT: () = compute(&SOME_STATIC);
+
+ pub const fn compute<T>(_: T)
+ where
+ T: Copy,
+ {
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr
new file mode 100644
index 000000000..e2cde2c59
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr
@@ -0,0 +1,77 @@
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:16:37
+ |
+LL | let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+ |
+ = note: `-D clippy::needless-borrows-for-generic-args` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_borrows_for_generic_args)]`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:17:33
+ |
+LL | let _ = Path::new(".").join(&&".");
+ | ^^^^^ help: change this to: `"."`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:21:33
+ |
+LL | let _ = std::fs::write("x", &"".to_string());
+ | ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:36:27
+ |
+LL | deref_target_is_x(&X);
+ | ^^ help: change this to: `X`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:49:30
+ |
+LL | multiple_constraints(&[[""]]);
+ | ^^^^^^^ help: change this to: `[[""]]`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:69:49
+ |
+LL | multiple_constraints_normalizes_to_same(&X, X);
+ | ^^ help: change this to: `X`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:127:24
+ |
+LL | takes_iter(&mut x)
+ | ^^^^^^ help: change this to: `x`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:136:41
+ |
+LL | let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+ | ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:144:41
+ |
+LL | let _ = std::fs::write("x", &arg);
+ | ^^^^ help: change this to: `arg`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:145:41
+ |
+LL | let _ = std::fs::write("x", &loc);
+ | ^^^^ help: change this to: `loc`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:167:11
+ |
+LL | f(&x);
+ | ^^ help: change this to: `x`
+
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrows_for_generic_args.rs:247:13
+ |
+LL | foo(&a);
+ | ^^ help: change this to: `a`
+
+error: aborting due to 12 previous errors
+
diff --git a/src/tools/clippy/tests/ui/needless_collect.fixed b/src/tools/clippy/tests/ui/needless_collect.fixed
index 0f0aaad17..bd83581bd 100644
--- a/src/tools/clippy/tests/ui/needless_collect.fixed
+++ b/src/tools/clippy/tests/ui/needless_collect.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::needless_if, clippy::suspicious_map, clippy::iter_count)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList};
diff --git a/src/tools/clippy/tests/ui/needless_collect.rs b/src/tools/clippy/tests/ui/needless_collect.rs
index 4f48f24b1..6a81a767b 100644
--- a/src/tools/clippy/tests/ui/needless_collect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::needless_if, clippy::suspicious_map, clippy::iter_count)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList};
diff --git a/src/tools/clippy/tests/ui/needless_collect.stderr b/src/tools/clippy/tests/ui/needless_collect.stderr
index ad22a7b05..2c21fc596 100644
--- a/src/tools/clippy/tests/ui/needless_collect.stderr
+++ b/src/tools/clippy/tests/ui/needless_collect.stderr
@@ -1,115 +1,116 @@
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:11:29
+ --> $DIR/needless_collect.rs:9:29
|
LL | let len = sample.iter().collect::<Vec<_>>().len();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()`
|
= note: `-D clippy::needless-collect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:12:22
+ --> $DIR/needless_collect.rs:10:22
|
LL | if sample.iter().collect::<Vec<_>>().is_empty() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:15:28
+ --> $DIR/needless_collect.rs:13:28
|
LL | sample.iter().cloned().collect::<Vec<_>>().contains(&1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:20:35
+ --> $DIR/needless_collect.rs:18:35
|
LL | sample.iter().map(|x| (x, x)).collect::<HashMap<_, _>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:21:35
+ --> $DIR/needless_collect.rs:19:35
|
LL | sample.iter().map(|x| (x, x)).collect::<BTreeMap<_, _>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:28:19
+ --> $DIR/needless_collect.rs:26:19
|
LL | sample.iter().collect::<LinkedList<_>>().len();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:29:19
+ --> $DIR/needless_collect.rs:27:19
|
LL | sample.iter().collect::<LinkedList<_>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:30:28
+ --> $DIR/needless_collect.rs:28:28
|
LL | sample.iter().cloned().collect::<LinkedList<_>>().contains(&1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:31:19
+ --> $DIR/needless_collect.rs:29:19
|
LL | sample.iter().collect::<LinkedList<_>>().contains(&&1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &1)`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:34:19
+ --> $DIR/needless_collect.rs:32:19
|
LL | sample.iter().collect::<BinaryHeap<_>>().len();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:35:19
+ --> $DIR/needless_collect.rs:33:19
|
LL | sample.iter().collect::<BinaryHeap<_>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:40:27
+ --> $DIR/needless_collect.rs:38:27
|
LL | let _ = sample.iter().collect::<HashSet<_>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:41:27
+ --> $DIR/needless_collect.rs:39:27
|
LL | let _ = sample.iter().collect::<HashSet<_>>().contains(&&0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:63:27
+ --> $DIR/needless_collect.rs:61:27
|
LL | let _ = sample.iter().collect::<VecWrapper<_>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:64:27
+ --> $DIR/needless_collect.rs:62:27
|
LL | let _ = sample.iter().collect::<VecWrapper<_>>().contains(&&0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)`
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:68:40
+ --> $DIR/needless_collect.rs:66:40
|
LL | Vec::<u8>::new().extend((0..10).collect::<Vec<_>>());
| ^^^^^^^^^^^^^^^^^^^^ help: remove this call
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:69:20
+ --> $DIR/needless_collect.rs:67:20
|
LL | foo((0..10).collect::<Vec<_>>());
| ^^^^^^^^^^^^^^^^^^^^ help: remove this call
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:70:49
+ --> $DIR/needless_collect.rs:68:49
|
LL | bar((0..10).collect::<Vec<_>>(), (0..10).collect::<Vec<_>>());
| ^^^^^^^^^^^^^^^^^^^^ help: remove this call
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect.rs:71:37
+ --> $DIR/needless_collect.rs:69:37
|
LL | baz((0..10), (), ('a'..='z').collect::<Vec<_>>())
| ^^^^^^^^^^^^^^^^^^^^ help: remove this call
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.rs b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
index d3d856c2c..9d66c5f25 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
@@ -1,18 +1,23 @@
#![allow(clippy::uninlined_format_args, clippy::useless_vec)]
#![allow(clippy::needless_if, clippy::uninlined_format_args)]
#![warn(clippy::needless_collect)]
-
+//@no-rustfix
use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
fn main() {
let sample = [1; 5];
let indirect_iter = sample.iter().collect::<Vec<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
+ //~| NOTE: `-D clippy::needless-collect` implied by `-D warnings`
indirect_iter.into_iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
let indirect_len = sample.iter().collect::<VecDeque<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
indirect_len.len();
let indirect_empty = sample.iter().collect::<VecDeque<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
indirect_empty.is_empty();
let indirect_contains = sample.iter().collect::<VecDeque<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
indirect_contains.contains(&&5);
let indirect_negative = sample.iter().collect::<Vec<_>>();
indirect_negative.len();
@@ -25,6 +30,7 @@ fn main() {
let a = "a".to_string();
let sample = vec![a.clone(), "b".to_string(), "c".to_string()];
let non_copy_contains = sample.into_iter().collect::<Vec<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
non_copy_contains.contains(&a);
// Fix #5991
@@ -54,21 +60,25 @@ mod issue7110 {
fn lint_vec(string: &str) -> usize {
let buffer: Vec<&str> = string.split('/').collect();
+ //~^ ERROR: avoid using `collect()` when not needed
buffer.len()
}
fn lint_vec_deque() -> usize {
let sample = [1; 5];
let indirect_len: VecDeque<_> = sample.iter().collect();
+ //~^ ERROR: avoid using `collect()` when not needed
indirect_len.len()
}
fn lint_linked_list() -> usize {
let sample = [1; 5];
let indirect_len: LinkedList<_> = sample.iter().collect();
+ //~^ ERROR: avoid using `collect()` when not needed
indirect_len.len()
}
fn lint_binary_heap() -> usize {
let sample = [1; 5];
let indirect_len: BinaryHeap<_> = sample.iter().collect();
+ //~^ ERROR: avoid using `collect()` when not needed
indirect_len.len()
}
fn dont_lint(string: &str) -> usize {
@@ -129,6 +139,7 @@ mod issue_8553 {
for i in 0..2 {
let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ //~^ ERROR: avoid using `collect()` when not needed
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
// Do lint
y.contains(&i);
@@ -154,6 +165,7 @@ mod issue_8553 {
while n > 2 {
let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ //~^ ERROR: avoid using `collect()` when not needed
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
// Do lint
y.contains(&n);
@@ -183,6 +195,7 @@ mod issue_8553 {
loop {
if n < 2 {
let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ //~^ ERROR: avoid using `collect()` when not needed
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
// Do lint
y.contains(&n);
@@ -219,6 +232,7 @@ mod issue_8553 {
while let Some(value) = optional {
let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
+ //~^ ERROR: avoid using `collect()` when not needed
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
if n < 2 {
// Do lint
@@ -244,6 +258,7 @@ mod issue_8553 {
let vec = vec![1, 2];
let v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let w = v.iter().collect::<Vec<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
// Do lint
for _ in 0..w.len() {
todo!();
@@ -266,6 +281,7 @@ mod issue_8553 {
let mut vec = vec![1, 2];
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut w = v.iter().collect::<Vec<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
// Do lint
while 1 == w.len() {
todo!();
@@ -288,6 +304,7 @@ mod issue_8553 {
let mut vec = vec![1, 2];
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut w = v.iter().collect::<Vec<_>>();
+ //~^ ERROR: avoid using `collect()` when not needed
// Do lint
while let Some(i) = Some(w.len()) {
todo!();
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
index 8f84c5596..3d1ad2a1c 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
@@ -3,130 +3,150 @@ error: avoid using `collect()` when not needed
|
LL | let indirect_iter = sample.iter().collect::<Vec<_>>();
| ^^^^^^^
+...
LL | indirect_iter.into_iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
| ------------------------- the iterator could be used here instead
|
= note: `-D clippy::needless-collect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]`
help: use the original Iterator instead of collecting it and then producing a new one
|
LL ~
+LL |
+LL |
LL ~ sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:11:38
+ --> $DIR/needless_collect_indirect.rs:13:38
|
LL | let indirect_len = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
+LL |
LL | indirect_len.len();
| ------------------ the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL ~ sample.iter().count();
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:13:40
+ --> $DIR/needless_collect_indirect.rs:16:40
|
LL | let indirect_empty = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
+LL |
LL | indirect_empty.is_empty();
| ------------------------- the iterator could be used here instead
|
help: check if the original Iterator has anything instead of collecting it and seeing if it's empty
|
LL ~
+LL |
LL ~ sample.iter().next().is_none();
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:15:43
+ --> $DIR/needless_collect_indirect.rs:19:43
|
LL | let indirect_contains = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
+LL |
LL | indirect_contains.contains(&&5);
| ------------------------------- the iterator could be used here instead
|
help: check if the original Iterator contains an element instead of collecting then checking
|
LL ~
+LL |
LL ~ sample.iter().any(|x| x == &5);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:27:48
+ --> $DIR/needless_collect_indirect.rs:32:48
|
LL | let non_copy_contains = sample.into_iter().collect::<Vec<_>>();
| ^^^^^^^
+LL |
LL | non_copy_contains.contains(&a);
| ------------------------------ the iterator could be used here instead
|
help: check if the original Iterator contains an element instead of collecting then checking
|
LL ~
+LL |
LL ~ sample.into_iter().any(|x| x == a);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:56:51
+ --> $DIR/needless_collect_indirect.rs:62:51
|
LL | let buffer: Vec<&str> = string.split('/').collect();
| ^^^^^^^
+LL |
LL | buffer.len()
| ------------ the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL ~ string.split('/').count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:61:55
+ --> $DIR/needless_collect_indirect.rs:68:55
|
LL | let indirect_len: VecDeque<_> = sample.iter().collect();
| ^^^^^^^
+LL |
LL | indirect_len.len()
| ------------------ the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:66:57
+ --> $DIR/needless_collect_indirect.rs:74:57
|
LL | let indirect_len: LinkedList<_> = sample.iter().collect();
| ^^^^^^^
+LL |
LL | indirect_len.len()
| ------------------ the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:71:57
+ --> $DIR/needless_collect_indirect.rs:80:57
|
LL | let indirect_len: BinaryHeap<_> = sample.iter().collect();
| ^^^^^^^
+LL |
LL | indirect_len.len()
| ------------------ the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:131:59
+ --> $DIR/needless_collect_indirect.rs:141:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -137,13 +157,14 @@ LL | y.contains(&i);
help: check if the original Iterator contains an element instead of collecting then checking
|
LL ~
+LL |
LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
LL | // Do lint
LL ~ vec.iter().map(|k| k * k).any(|x| x == i);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:156:59
+ --> $DIR/needless_collect_indirect.rs:167:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -154,13 +175,14 @@ LL | y.contains(&n);
help: check if the original Iterator contains an element instead of collecting then checking
|
LL ~
+LL |
LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
LL | // Do lint
LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:185:63
+ --> $DIR/needless_collect_indirect.rs:197:63
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -171,13 +193,14 @@ LL | y.contains(&n);
help: check if the original Iterator contains an element instead of collecting then checking
|
LL ~
+LL |
LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
LL | // Do lint
LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:221:59
+ --> $DIR/needless_collect_indirect.rs:234:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -188,56 +211,59 @@ LL | y.contains(&n);
help: check if the original Iterator contains an element instead of collecting then checking
|
LL ~
-LL | let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
-LL | if n < 2 {
+LL |
+ ...
LL | // Do lint
LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:246:26
+ --> $DIR/needless_collect_indirect.rs:260:26
|
LL | let w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
-LL | // Do lint
+...
LL | for _ in 0..w.len() {
| ------- the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL | // Do lint
LL ~ for _ in 0..v.iter().count() {
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:268:30
+ --> $DIR/needless_collect_indirect.rs:283:30
|
LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
-LL | // Do lint
+...
LL | while 1 == w.len() {
| ------- the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL | // Do lint
LL ~ while 1 == v.iter().count() {
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:290:30
+ --> $DIR/needless_collect_indirect.rs:306:30
|
LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
-LL | // Do lint
+...
LL | while let Some(i) = Some(w.len()) {
| ------- the iterator could be used here instead
|
help: take the original Iterator's count instead of collecting it and finding the length
|
LL ~
+LL |
LL | // Do lint
LL ~ while let Some(i) = Some(v.iter().count()) {
|
diff --git a/src/tools/clippy/tests/ui/needless_continue.rs b/src/tools/clippy/tests/ui/needless_continue.rs
index c891c9de3..c26a292c8 100644
--- a/src/tools/clippy/tests/ui/needless_continue.rs
+++ b/src/tools/clippy/tests/ui/needless_continue.rs
@@ -28,6 +28,7 @@ fn main() {
let i = 0;
println!("bar {} ", i);
} else {
+ //~^ ERROR: this `else` block is redundant
continue;
}
@@ -43,6 +44,7 @@ fn main() {
}
if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {
+ //~^ ERROR: there is no need for an explicit `else` block for this `if` expression
continue;
} else {
println!("Blabber");
@@ -55,21 +57,24 @@ fn main() {
fn simple_loop() {
loop {
- continue; // should lint here
+ continue;
+ //~^ ERROR: this `continue` expression is redundant
}
}
fn simple_loop2() {
loop {
println!("bleh");
- continue; // should lint here
+ continue;
+ //~^ ERROR: this `continue` expression is redundant
}
}
#[rustfmt::skip]
fn simple_loop3() {
loop {
- continue // should lint here
+ continue
+ //~^ ERROR: this `continue` expression is redundant
}
}
@@ -77,7 +82,8 @@ fn simple_loop3() {
fn simple_loop4() {
loop {
println!("bleh");
- continue // should lint here
+ continue
+ //~^ ERROR: this `continue` expression is redundant
}
}
@@ -128,13 +134,15 @@ mod issue_2329 {
if condition() {
println!("bar-3");
} else {
- continue 'inner; // should lint here
+ //~^ ERROR: this `else` block is redundant
+ continue 'inner;
}
println!("bar-4");
update_condition();
if condition() {
- continue; // should lint here
+ //~^ ERROR: there is no need for an explicit `else` block for this `if` ex
+ continue;
} else {
println!("bar-5");
}
diff --git a/src/tools/clippy/tests/ui/needless_continue.stderr b/src/tools/clippy/tests/ui/needless_continue.stderr
index d99989b54..31b5dc280 100644
--- a/src/tools/clippy/tests/ui/needless_continue.stderr
+++ b/src/tools/clippy/tests/ui/needless_continue.stderr
@@ -3,6 +3,7 @@ error: this `else` block is redundant
|
LL | } else {
| ________________^
+LL | |
LL | | continue;
LL | | }
| |_________^
@@ -25,6 +26,7 @@ LL | | }
println!("lama");
}
if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {
+
continue;
} else {
println!("Blabber");
@@ -33,11 +35,13 @@ LL | | }
println!("bleh");
}
= note: `-D clippy::needless-continue` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_continue)]`
error: there is no need for an explicit `else` block for this `if` expression
- --> $DIR/needless_continue.rs:45:9
+ --> $DIR/needless_continue.rs:46:9
|
LL | / if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {
+LL | |
LL | | continue;
LL | | } else {
LL | | println!("Blabber");
@@ -47,6 +51,7 @@ LL | | }
|
= help: consider dropping the `else` clause
if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {
+
continue;
}
{
@@ -55,43 +60,44 @@ LL | | }
}
error: this `continue` expression is redundant
- --> $DIR/needless_continue.rs:58:9
+ --> $DIR/needless_continue.rs:60:9
|
-LL | continue; // should lint here
+LL | continue;
| ^^^^^^^^^
|
= help: consider dropping the `continue` expression
error: this `continue` expression is redundant
- --> $DIR/needless_continue.rs:65:9
+ --> $DIR/needless_continue.rs:68:9
|
-LL | continue; // should lint here
+LL | continue;
| ^^^^^^^^^
|
= help: consider dropping the `continue` expression
error: this `continue` expression is redundant
- --> $DIR/needless_continue.rs:72:9
+ --> $DIR/needless_continue.rs:76:9
|
-LL | continue // should lint here
+LL | continue
| ^^^^^^^^
|
= help: consider dropping the `continue` expression
error: this `continue` expression is redundant
- --> $DIR/needless_continue.rs:80:9
+ --> $DIR/needless_continue.rs:85:9
|
-LL | continue // should lint here
+LL | continue
| ^^^^^^^^
|
= help: consider dropping the `continue` expression
error: this `else` block is redundant
- --> $DIR/needless_continue.rs:130:24
+ --> $DIR/needless_continue.rs:136:24
|
LL | } else {
| ________________________^
-LL | | continue 'inner; // should lint here
+LL | |
+LL | | continue 'inner;
LL | | }
| |_________________^
|
@@ -102,7 +108,8 @@ LL | | }
println!("bar-4");
update_condition();
if condition() {
- continue; // should lint here
+
+ continue;
} else {
println!("bar-5");
}
@@ -110,10 +117,11 @@ LL | | }
}
error: there is no need for an explicit `else` block for this `if` expression
- --> $DIR/needless_continue.rs:136:17
+ --> $DIR/needless_continue.rs:143:17
|
LL | / if condition() {
-LL | | continue; // should lint here
+LL | |
+LL | | continue;
LL | | } else {
LL | | println!("bar-5");
LL | | }
@@ -121,7 +129,8 @@ LL | | }
|
= help: consider dropping the `else` clause
if condition() {
- continue; // should lint here
+
+ continue;
}
{
println!("bar-5");
diff --git a/src/tools/clippy/tests/ui/needless_doc_main.rs b/src/tools/clippy/tests/ui/needless_doc_main.rs
index 83e9bbaa3..fee05926c 100644
--- a/src/tools/clippy/tests/ui/needless_doc_main.rs
+++ b/src/tools/clippy/tests/ui/needless_doc_main.rs
@@ -5,6 +5,8 @@
/// This should lint
/// ```
/// fn main() {
+//~^ ERROR: needless `fn main` in doctest
+//~| NOTE: `-D clippy::needless-doctest-main` implied by `-D warnings`
/// unimplemented!();
/// }
/// ```
@@ -12,6 +14,7 @@
/// With an explicit return type it should lint too
/// ```edition2015
/// fn main() -> () {
+//~^ ERROR: needless `fn main` in doctest
/// unimplemented!();
/// }
/// ```
@@ -19,12 +22,15 @@
/// This should, too.
/// ```rust
/// fn main() {
+//~^ ERROR: needless `fn main` in doctest
/// unimplemented!();
/// }
/// ```
///
/// This one too.
/// ```no_run
+/// // the fn is not always the first line
+//~^ ERROR: needless `fn main` in doctest
/// fn main() {
/// unimplemented!();
/// }
diff --git a/src/tools/clippy/tests/ui/needless_doc_main.stderr b/src/tools/clippy/tests/ui/needless_doc_main.stderr
index 05c7f9d33..842565486 100644
--- a/src/tools/clippy/tests/ui/needless_doc_main.stderr
+++ b/src/tools/clippy/tests/ui/needless_doc_main.stderr
@@ -1,28 +1,47 @@
error: needless `fn main` in doctest
- --> $DIR/needless_doc_main.rs:7:4
+ --> $DIR/needless_doc_main.rs:7:5
|
-LL | /// fn main() {
- | ^^^^^^^^^^^^
+LL | /// fn main() {
+ | _____^
+LL | |
+LL | |
+LL | | /// unimplemented!();
+LL | | /// }
+ | |_____^
|
= note: `-D clippy::needless-doctest-main` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_doctest_main)]`
error: needless `fn main` in doctest
- --> $DIR/needless_doc_main.rs:14:4
+ --> $DIR/needless_doc_main.rs:16:5
|
-LL | /// fn main() -> () {
- | ^^^^^^^^^^^^^^^^^^
+LL | /// fn main() -> () {
+ | _____^
+LL | |
+LL | | /// unimplemented!();
+LL | | /// }
+ | |_____^
error: needless `fn main` in doctest
- --> $DIR/needless_doc_main.rs:21:4
+ --> $DIR/needless_doc_main.rs:24:5
|
-LL | /// fn main() {
- | ^^^^^^^^^^^^
+LL | /// fn main() {
+ | _____^
+LL | |
+LL | | /// unimplemented!();
+LL | | /// }
+ | |_____^
error: needless `fn main` in doctest
- --> $DIR/needless_doc_main.rs:28:4
+ --> $DIR/needless_doc_main.rs:32:5
|
-LL | /// fn main() {
- | ^^^^^^^^^^^^
+LL | /// // the fn is not always the first line
+ | _____^
+LL | |
+LL | | /// fn main() {
+LL | | /// unimplemented!();
+LL | | /// }
+ | |_____^
error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_else.fixed b/src/tools/clippy/tests/ui/needless_else.fixed
index 06a161627..240b79bae 100644
--- a/src/tools/clippy/tests/ui/needless_else.fixed
+++ b/src/tools/clippy/tests/ui/needless_else.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::needless_else)]
#![allow(clippy::suspicious_else_formatting)]
diff --git a/src/tools/clippy/tests/ui/needless_else.rs b/src/tools/clippy/tests/ui/needless_else.rs
index 728032c47..ad84da170 100644
--- a/src/tools/clippy/tests/ui/needless_else.rs
+++ b/src/tools/clippy/tests/ui/needless_else.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::needless_else)]
#![allow(clippy::suspicious_else_formatting)]
diff --git a/src/tools/clippy/tests/ui/needless_else.stderr b/src/tools/clippy/tests/ui/needless_else.stderr
index 49cd78501..e6f7138e9 100644
--- a/src/tools/clippy/tests/ui/needless_else.stderr
+++ b/src/tools/clippy/tests/ui/needless_else.stderr
@@ -1,5 +1,5 @@
error: this `else` branch is empty
- --> $DIR/needless_else.rs:24:7
+ --> $DIR/needless_else.rs:23:7
|
LL | } else {
| _______^
@@ -7,6 +7,7 @@ LL | | }
| |_____^ help: you can remove it
|
= note: `-D clippy::needless-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_else)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
index 92572942b..8c0e7ba76 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::needless_for_each)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
index 95acbdff8..cdc903a63 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::needless_for_each)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
index aebb762cc..3b5163b01 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
@@ -1,5 +1,5 @@
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:16:5
+ --> $DIR/needless_for_each_fixable.rs:15:5
|
LL | / v.iter().for_each(|elem| {
LL | | acc += elem;
@@ -7,6 +7,7 @@ LL | | });
| |_______^
|
= note: `-D clippy::needless-for-each` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_for_each)]`
help: try
|
LL ~ for elem in v.iter() {
@@ -15,7 +16,7 @@ LL + }
|
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:19:5
+ --> $DIR/needless_for_each_fixable.rs:18:5
|
LL | / v.into_iter().for_each(|elem| {
LL | | acc += elem;
@@ -30,7 +31,7 @@ LL + }
|
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:23:5
+ --> $DIR/needless_for_each_fixable.rs:22:5
|
LL | / [1, 2, 3].iter().for_each(|elem| {
LL | | acc += elem;
@@ -45,7 +46,7 @@ LL + }
|
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:28:5
+ --> $DIR/needless_for_each_fixable.rs:27:5
|
LL | / hash_map.iter().for_each(|(k, v)| {
LL | | acc += k + v;
@@ -60,7 +61,7 @@ LL + }
|
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:31:5
+ --> $DIR/needless_for_each_fixable.rs:30:5
|
LL | / hash_map.iter_mut().for_each(|(k, v)| {
LL | | acc += *k + *v;
@@ -75,7 +76,7 @@ LL + }
|
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:34:5
+ --> $DIR/needless_for_each_fixable.rs:33:5
|
LL | / hash_map.keys().for_each(|k| {
LL | | acc += k;
@@ -90,7 +91,7 @@ LL + }
|
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:37:5
+ --> $DIR/needless_for_each_fixable.rs:36:5
|
LL | / hash_map.values().for_each(|v| {
LL | | acc += v;
@@ -105,7 +106,7 @@ LL + }
|
error: needless use of `for_each`
- --> $DIR/needless_for_each_fixable.rs:44:5
+ --> $DIR/needless_for_each_fixable.rs:43:5
|
LL | / my_vec().iter().for_each(|elem| {
LL | | acc += elem;
diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs b/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs
index 282c72881..2220cf9e1 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs
+++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::needless_for_each)]
#![allow(clippy::needless_return, clippy::uninlined_format_args)]
@@ -5,6 +6,8 @@ fn main() {
let v: Vec<i32> = Vec::new();
// This is unfixable because the closure includes `return`.
v.iter().for_each(|v| {
+ //~^ ERROR: needless use of `for_each`
+ //~| NOTE: `-D clippy::needless-for-each` implied by `-D warnings`
if *v == 10 {
return;
} else {
diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
index 7893ff31a..73f249ae6 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
@@ -1,19 +1,22 @@
error: needless use of `for_each`
- --> $DIR/needless_for_each_unfixable.rs:7:5
+ --> $DIR/needless_for_each_unfixable.rs:8:5
|
LL | / v.iter().for_each(|v| {
+LL | |
+LL | |
LL | | if *v == 10 {
-LL | | return;
-LL | | } else {
-LL | | println!("{}", v);
+... |
LL | | }
LL | | });
| |_______^
|
= note: `-D clippy::needless-for-each` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_for_each)]`
help: try
|
LL ~ for v in v.iter() {
+LL +
+LL +
LL + if *v == 10 {
LL + return;
LL + } else {
diff --git a/src/tools/clippy/tests/ui/needless_if.fixed b/src/tools/clippy/tests/ui/needless_if.fixed
index 6001c9e93..b84182c57 100644
--- a/src/tools/clippy/tests/ui/needless_if.fixed
+++ b/src/tools/clippy/tests/ui/needless_if.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(let_chains)]
#![allow(
clippy::blocks_in_if_conditions,
diff --git a/src/tools/clippy/tests/ui/needless_if.rs b/src/tools/clippy/tests/ui/needless_if.rs
index c6be4766d..6c6023c72 100644
--- a/src/tools/clippy/tests/ui/needless_if.rs
+++ b/src/tools/clippy/tests/ui/needless_if.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(let_chains)]
#![allow(
clippy::blocks_in_if_conditions,
diff --git a/src/tools/clippy/tests/ui/needless_if.stderr b/src/tools/clippy/tests/ui/needless_if.stderr
index 14de40095..ed5b9452b 100644
--- a/src/tools/clippy/tests/ui/needless_if.stderr
+++ b/src/tools/clippy/tests/ui/needless_if.stderr
@@ -1,19 +1,20 @@
error: this `if` branch is empty
- --> $DIR/needless_if.rs:27:5
+ --> $DIR/needless_if.rs:26:5
|
LL | if (true) {}
| ^^^^^^^^^^^^ help: you can remove it
|
= note: `-D clippy::needless-if` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_if)]`
error: this `if` branch is empty
- --> $DIR/needless_if.rs:29:5
+ --> $DIR/needless_if.rs:28:5
|
LL | if maybe_side_effect() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `maybe_side_effect();`
error: this `if` branch is empty
- --> $DIR/needless_if.rs:34:5
+ --> $DIR/needless_if.rs:33:5
|
LL | / if {
LL | | return;
@@ -28,7 +29,7 @@ LL + });
|
error: this `if` branch is empty
- --> $DIR/needless_if.rs:46:5
+ --> $DIR/needless_if.rs:45:5
|
LL | / if {
LL | | if let true = true && true { true } else { false }
@@ -44,19 +45,19 @@ LL + } && true);
|
error: this `if` branch is empty
- --> $DIR/needless_if.rs:84:5
+ --> $DIR/needless_if.rs:83:5
|
LL | if { maybe_side_effect() } {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() });`
error: this `if` branch is empty
- --> $DIR/needless_if.rs:86:5
+ --> $DIR/needless_if.rs:85:5
|
LL | if { maybe_side_effect() } && true {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() } && true);`
error: this `if` branch is empty
- --> $DIR/needless_if.rs:90:5
+ --> $DIR/needless_if.rs:89:5
|
LL | if true {}
| ^^^^^^^^^^ help: you can remove it: `true;`
diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed
index 933dd8bed..9f45da048 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.fixed
+++ b/src/tools/clippy/tests/ui/needless_late_init.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(let_chains)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs
index ba3a04e08..0dab0faad 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(let_chains)]
#![allow(unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr
index 78ba8e11c..602b1a683 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.stderr
+++ b/src/tools/clippy/tests/ui/needless_late_init.stderr
@@ -1,5 +1,5 @@
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:28:5
+ --> $DIR/needless_late_init.rs:27:5
|
LL | let a;
| ^^^^^^ created here
@@ -7,13 +7,14 @@ LL | a = "zero";
| ^^^^^^^^^^ initialised here
|
= note: `-D clippy::needless-late-init` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_late_init)]`
help: declare `a` here
|
LL | let a = "zero";
| ~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:31:5
+ --> $DIR/needless_late_init.rs:30:5
|
LL | let b;
| ^^^^^^ created here
@@ -27,7 +28,7 @@ LL | let b = 1;
| ~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:32:5
+ --> $DIR/needless_late_init.rs:31:5
|
LL | let c;
| ^^^^^^ created here
@@ -41,7 +42,7 @@ LL | let c = 2;
| ~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:36:5
+ --> $DIR/needless_late_init.rs:35:5
|
LL | let d: usize;
| ^^^^^^^^^^^^^ created here
@@ -54,7 +55,7 @@ LL | let d: usize = 1;
| ~~~~~~~~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:39:5
+ --> $DIR/needless_late_init.rs:38:5
|
LL | let e;
| ^^^^^^ created here
@@ -67,7 +68,7 @@ LL | let e = format!("{}", d);
| ~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:44:5
+ --> $DIR/needless_late_init.rs:43:5
|
LL | let a;
| ^^^^^^
@@ -88,7 +89,7 @@ LL | };
| +
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:53:5
+ --> $DIR/needless_late_init.rs:52:5
|
LL | let b;
| ^^^^^^
@@ -109,7 +110,7 @@ LL | };
| +
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:60:5
+ --> $DIR/needless_late_init.rs:59:5
|
LL | let d;
| ^^^^^^
@@ -130,7 +131,7 @@ LL | };
| +
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:68:5
+ --> $DIR/needless_late_init.rs:67:5
|
LL | let e;
| ^^^^^^
@@ -151,7 +152,7 @@ LL | };
| +
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:75:5
+ --> $DIR/needless_late_init.rs:74:5
|
LL | let f;
| ^^^^^^
@@ -167,7 +168,7 @@ LL + 1 => "three",
|
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:81:5
+ --> $DIR/needless_late_init.rs:80:5
|
LL | let g: usize;
| ^^^^^^^^^^^^^
@@ -187,7 +188,7 @@ LL | };
| +
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:89:5
+ --> $DIR/needless_late_init.rs:88:5
|
LL | let x;
| ^^^^^^ created here
@@ -201,7 +202,7 @@ LL | let x = 1;
| ~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:93:5
+ --> $DIR/needless_late_init.rs:92:5
|
LL | let x;
| ^^^^^^ created here
@@ -215,7 +216,7 @@ LL | let x = SignificantDrop;
| ~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:97:5
+ --> $DIR/needless_late_init.rs:96:5
|
LL | let x;
| ^^^^^^ created here
@@ -229,7 +230,7 @@ LL | let x = SignificantDrop;
| ~~~~~
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:116:5
+ --> $DIR/needless_late_init.rs:115:5
|
LL | let a;
| ^^^^^^
@@ -250,7 +251,7 @@ LL | };
| +
error: unneeded late initialization
- --> $DIR/needless_late_init.rs:133:5
+ --> $DIR/needless_late_init.rs:132:5
|
LL | let a;
| ^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
index 302a3f9ed..d1787b35a 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::needless_lifetimes)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index b15477c92..03d6f2013 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::needless_lifetimes)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index 0da67b600..7051a2604 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -1,10 +1,11 @@
error: the following explicit lifetimes could be elided: 'a, 'b
- --> $DIR/needless_lifetimes.rs:18:23
+ --> $DIR/needless_lifetimes.rs:17:23
|
LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
| ^^ ^^ ^^ ^^
|
= note: `-D clippy::needless-lifetimes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]`
help: elide the lifetimes
|
LL - fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
@@ -12,7 +13,7 @@ LL + fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {}
|
error: the following explicit lifetimes could be elided: 'a, 'b
- --> $DIR/needless_lifetimes.rs:20:24
+ --> $DIR/needless_lifetimes.rs:19:24
|
LL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}
| ^^ ^^ ^^ ^^
@@ -24,7 +25,7 @@ LL + fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {}
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:30:15
+ --> $DIR/needless_lifetimes.rs:29:15
|
LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
| ^^ ^^ ^^
@@ -36,7 +37,7 @@ LL + fn in_and_out(x: &u8, _y: u8) -> &u8 {
|
error: the following explicit lifetimes could be elided: 'b
- --> $DIR/needless_lifetimes.rs:42:31
+ --> $DIR/needless_lifetimes.rs:41:31
|
LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
| ^^ ^^
@@ -48,7 +49,7 @@ LL + fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:49:27
+ --> $DIR/needless_lifetimes.rs:48:27
|
LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {
| ^^ ^^
@@ -60,7 +61,7 @@ LL + fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 {
|
error: the following explicit lifetimes could be elided: 'b
- --> $DIR/needless_lifetimes.rs:66:26
+ --> $DIR/needless_lifetimes.rs:65:26
|
LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
| ^^ ^^
@@ -72,7 +73,7 @@ LL + fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:73:22
+ --> $DIR/needless_lifetimes.rs:72:22
|
LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {
| ^^ ^^
@@ -84,7 +85,7 @@ LL + fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:82:21
+ --> $DIR/needless_lifetimes.rs:81:21
|
LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
| ^^ ^^ ^^
@@ -96,7 +97,7 @@ LL + fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:87:28
+ --> $DIR/needless_lifetimes.rs:86:28
|
LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
| ^^ ^^ ^^
@@ -108,7 +109,7 @@ LL + fn where_clause_without_lt<T>(x: &u8, _y: u8) -> Result<&u8, ()>
|
error: the following explicit lifetimes could be elided: 'a, 'b
- --> $DIR/needless_lifetimes.rs:99:21
+ --> $DIR/needless_lifetimes.rs:98:21
|
LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
| ^^ ^^ ^^ ^^
@@ -120,7 +121,7 @@ LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:123:15
+ --> $DIR/needless_lifetimes.rs:122:15
|
LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
| ^^ ^^ ^^
@@ -132,7 +133,7 @@ LL + fn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>
|
error: the following explicit lifetimes could be elided: 's
- --> $DIR/needless_lifetimes.rs:153:21
+ --> $DIR/needless_lifetimes.rs:152:21
|
LL | fn self_and_out<'s>(&'s self) -> &'s u8 {
| ^^ ^^ ^^
@@ -144,7 +145,7 @@ LL + fn self_and_out(&self) -> &u8 {
|
error: the following explicit lifetimes could be elided: 't
- --> $DIR/needless_lifetimes.rs:160:30
+ --> $DIR/needless_lifetimes.rs:159:30
|
LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
| ^^ ^^
@@ -156,7 +157,7 @@ LL + fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 {
|
error: the following explicit lifetimes could be elided: 's
- --> $DIR/needless_lifetimes.rs:167:26
+ --> $DIR/needless_lifetimes.rs:166:26
|
LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
| ^^ ^^
@@ -168,7 +169,7 @@ LL + fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 {
|
error: the following explicit lifetimes could be elided: 's, 't
- --> $DIR/needless_lifetimes.rs:171:29
+ --> $DIR/needless_lifetimes.rs:170:29
|
LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
| ^^ ^^ ^^ ^^
@@ -180,7 +181,7 @@ LL + fn distinct_self_and_in(&self, _x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:190:19
+ --> $DIR/needless_lifetimes.rs:189:19
|
LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
| ^^ ^^ ^^
@@ -192,7 +193,7 @@ LL + fn struct_with_lt(_foo: Foo<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
- --> $DIR/needless_lifetimes.rs:208:25
+ --> $DIR/needless_lifetimes.rs:207:25
|
LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
| ^^ ^^
@@ -204,7 +205,7 @@ LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:216:21
+ --> $DIR/needless_lifetimes.rs:215:21
|
LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
| ^^ ^^
@@ -216,7 +217,7 @@ LL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:231:22
+ --> $DIR/needless_lifetimes.rs:230:22
|
LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {
| ^^ ^^ ^^
@@ -228,7 +229,7 @@ LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:237:18
+ --> $DIR/needless_lifetimes.rs:236:18
|
LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
| ^^ ^^ ^^
@@ -240,7 +241,7 @@ LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str {
|
error: the following explicit lifetimes could be elided: 'b
- --> $DIR/needless_lifetimes.rs:255:24
+ --> $DIR/needless_lifetimes.rs:254:24
|
LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
| ^^ ^^
@@ -252,7 +253,7 @@ LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:263:20
+ --> $DIR/needless_lifetimes.rs:262:20
|
LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
| ^^ ^^
@@ -264,7 +265,7 @@ LL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:267:30
+ --> $DIR/needless_lifetimes.rs:266:30
|
LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
| ^^ ^^ ^
@@ -276,7 +277,7 @@ LL + fn named_input_elided_output(_arg: &str) -> &str {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:275:19
+ --> $DIR/needless_lifetimes.rs:274:19
|
LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {
| ^^ ^^
@@ -288,7 +289,7 @@ LL + fn trait_bound_ok<T: WithLifetime<'static>>(_: &u8, _: T) {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:311:24
+ --> $DIR/needless_lifetimes.rs:310:24
|
LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
| ^^ ^^ ^^
@@ -300,7 +301,7 @@ LL + fn out_return_type_lts(e: &str) -> Cow<'_> {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:318:24
+ --> $DIR/needless_lifetimes.rs:317:24
|
LL | fn needless_lt<'a>(x: &'a u8) {}
| ^^ ^^
@@ -312,7 +313,7 @@ LL + fn needless_lt(x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:322:24
+ --> $DIR/needless_lifetimes.rs:321:24
|
LL | fn needless_lt<'a>(_x: &'a u8) {}
| ^^ ^^
@@ -324,7 +325,7 @@ LL + fn needless_lt(_x: &u8) {}
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:335:16
+ --> $DIR/needless_lifetimes.rs:334:16
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
| ^^ ^^ ^^
@@ -336,7 +337,7 @@ LL + fn baz(&self) -> impl Foo + '_ {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:367:55
+ --> $DIR/needless_lifetimes.rs:366:55
|
LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
| ^^ ^^ ^^
@@ -348,7 +349,7 @@ LL + fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:376:26
+ --> $DIR/needless_lifetimes.rs:375:26
|
LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
| ^^ ^^ ^^
@@ -360,7 +361,7 @@ LL + fn generics_elidable<T: Fn(&i32) -> &i32>(i: &i32, f: T) -> &i32 {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:388:32
+ --> $DIR/needless_lifetimes.rs:387:32
|
LL | fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
| ^^ ^^ ^^
@@ -372,7 +373,7 @@ LL + fn where_clause_elidadable<T>(i: &i32, f: T) -> &i32
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:403:28
+ --> $DIR/needless_lifetimes.rs:402:28
|
LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
| ^^ ^^ ^^
@@ -384,7 +385,7 @@ LL + fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:416:28
+ --> $DIR/needless_lifetimes.rs:415:28
|
LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
| ^^ ^^
@@ -396,7 +397,7 @@ LL + fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:419:28
+ --> $DIR/needless_lifetimes.rs:418:28
|
LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
| ^^ ^^
@@ -408,7 +409,7 @@ LL + fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:441:21
+ --> $DIR/needless_lifetimes.rs:440:21
|
LL | fn implicit<'a>(&'a self) -> &'a () {
| ^^ ^^ ^^
@@ -420,7 +421,7 @@ LL + fn implicit(&self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:444:25
+ --> $DIR/needless_lifetimes.rs:443:25
|
LL | fn implicit_mut<'a>(&'a mut self) -> &'a () {
| ^^ ^^ ^^
@@ -432,7 +433,7 @@ LL + fn implicit_mut(&mut self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:455:31
+ --> $DIR/needless_lifetimes.rs:454:31
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^ ^^ ^^
@@ -444,7 +445,7 @@ LL + fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:461:21
+ --> $DIR/needless_lifetimes.rs:460:21
|
LL | fn implicit<'a>(&'a self) -> &'a ();
| ^^ ^^ ^^
@@ -456,7 +457,7 @@ LL + fn implicit(&self) -> &();
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:462:30
+ --> $DIR/needless_lifetimes.rs:461:30
|
LL | fn implicit_provided<'a>(&'a self) -> &'a () {
| ^^ ^^ ^^
@@ -468,7 +469,7 @@ LL + fn implicit_provided(&self) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:471:31
+ --> $DIR/needless_lifetimes.rs:470:31
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
| ^^ ^^ ^^
@@ -480,7 +481,7 @@ LL + fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &();
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:472:40
+ --> $DIR/needless_lifetimes.rs:471:40
|
LL | fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^ ^^ ^^
@@ -492,7 +493,7 @@ LL + fn lifetime_elsewhere_provided(self: Box<Self>, here: &()) -> &() {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:481:12
+ --> $DIR/needless_lifetimes.rs:480:12
|
LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {}
| ^^ ^^
@@ -504,7 +505,7 @@ LL + fn foo(x: &u8, y: &'_ u8) {}
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:483:12
+ --> $DIR/needless_lifetimes.rs:482:12
|
LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
| ^^ ^^
@@ -516,7 +517,7 @@ LL + fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {}
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:490:18
+ --> $DIR/needless_lifetimes.rs:489:18
|
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^ ^^ ^^
@@ -528,7 +529,7 @@ LL + fn one_input(x: &u8) -> &u8 {
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:495:42
+ --> $DIR/needless_lifetimes.rs:494:42
|
LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
| ^^ ^^
@@ -540,7 +541,7 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8)
|
error: the following explicit lifetimes could be elided: 'a
- --> $DIR/needless_lifetimes.rs:511:22
+ --> $DIR/needless_lifetimes.rs:510:22
|
LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
| ^^ ^^ ^^
diff --git a/src/tools/clippy/tests/ui/needless_match.fixed b/src/tools/clippy/tests/ui/needless_match.fixed
index d8a0400a4..a936eb463 100644
--- a/src/tools/clippy/tests/ui/needless_match.fixed
+++ b/src/tools/clippy/tests/ui/needless_match.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::needless_match)]
#![allow(clippy::manual_map)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/needless_match.rs b/src/tools/clippy/tests/ui/needless_match.rs
index 3de9bd6d7..b1dd6ff07 100644
--- a/src/tools/clippy/tests/ui/needless_match.rs
+++ b/src/tools/clippy/tests/ui/needless_match.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::needless_match)]
#![allow(clippy::manual_map)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/needless_match.stderr b/src/tools/clippy/tests/ui/needless_match.stderr
index 28e78441c..736926b44 100644
--- a/src/tools/clippy/tests/ui/needless_match.stderr
+++ b/src/tools/clippy/tests/ui/needless_match.stderr
@@ -1,5 +1,5 @@
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:16:18
+ --> $DIR/needless_match.rs:15:18
|
LL | let _: i32 = match i {
| __________________^
@@ -11,9 +11,10 @@ LL | | };
| |_____^ help: replace it with: `i`
|
= note: `-D clippy::needless-match` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_match)]`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:23:19
+ --> $DIR/needless_match.rs:22:19
|
LL | let _: &str = match s {
| ___________________^
@@ -24,7 +25,7 @@ LL | | };
| |_____^ help: replace it with: `s`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:32:21
+ --> $DIR/needless_match.rs:31:21
|
LL | let _: Simple = match se {
| _____________________^
@@ -36,7 +37,7 @@ LL | | };
| |_____^ help: replace it with: `se`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:54:26
+ --> $DIR/needless_match.rs:53:26
|
LL | let _: Option<i32> = match x {
| __________________________^
@@ -46,7 +47,7 @@ LL | | };
| |_____^ help: replace it with: `x`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:70:31
+ --> $DIR/needless_match.rs:69:31
|
LL | let _: Result<i32, i32> = match Ok(1) {
| _______________________________^
@@ -56,7 +57,7 @@ LL | | };
| |_____^ help: replace it with: `Ok(1)`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:74:31
+ --> $DIR/needless_match.rs:73:31
|
LL | let _: Result<i32, i32> = match func_ret_err(0_i32) {
| _______________________________^
@@ -66,25 +67,25 @@ LL | | };
| |_____^ help: replace it with: `func_ret_err(0_i32)`
error: this if-let expression is unnecessary
- --> $DIR/needless_match.rs:87:13
+ --> $DIR/needless_match.rs:86:13
|
LL | let _ = if let Some(a) = Some(1) { Some(a) } else { None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
error: this if-let expression is unnecessary
- --> $DIR/needless_match.rs:122:31
+ --> $DIR/needless_match.rs:121:31
|
LL | let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
error: this if-let expression is unnecessary
- --> $DIR/needless_match.rs:123:31
+ --> $DIR/needless_match.rs:122:31
|
LL | let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
error: this if-let expression is unnecessary
- --> $DIR/needless_match.rs:130:21
+ --> $DIR/needless_match.rs:129:21
|
LL | let _: Simple = if let Simple::A = x {
| _____________________^
@@ -97,7 +98,7 @@ LL | | };
| |_____^ help: replace it with: `x`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:169:26
+ --> $DIR/needless_match.rs:168:26
|
LL | let _: Complex = match ce {
| __________________________^
@@ -110,7 +111,7 @@ LL | | };
| |_________^ help: replace it with: `ce`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:253:17
+ --> $DIR/needless_match.rs:252:17
|
LL | let _ = match e {
| _________________^
@@ -120,7 +121,7 @@ LL | | };
| |_________^ help: replace it with: `e`
error: this match expression is unnecessary
- --> $DIR/needless_match.rs:259:17
+ --> $DIR/needless_match.rs:258:17
|
LL | let _ = match e {
| _________________^
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
index ec981ad97..58f56eba0 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::needless_option_as_deref)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.rs b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
index 6360874f6..842e025f6 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.rs
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::needless_option_as_deref)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.stderr b/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
index 4c0d502a2..024d30c17 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
@@ -1,19 +1,20 @@
error: derefed type is same as origin
- --> $DIR/needless_option_as_deref.rs:9:29
+ --> $DIR/needless_option_as_deref.rs:7:29
|
LL | let _: Option<&usize> = Some(&1).as_deref();
| ^^^^^^^^^^^^^^^^^^^ help: try: `Some(&1)`
|
= note: `-D clippy::needless-option-as-deref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_option_as_deref)]`
error: derefed type is same as origin
- --> $DIR/needless_option_as_deref.rs:10:33
+ --> $DIR/needless_option_as_deref.rs:8:33
|
LL | let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&mut 1)`
error: derefed type is same as origin
- --> $DIR/needless_option_as_deref.rs:14:13
+ --> $DIR/needless_option_as_deref.rs:12:13
|
LL | let _ = x.as_deref_mut();
| ^^^^^^^^^^^^^^^^ help: try: `x`
diff --git a/src/tools/clippy/tests/ui/needless_option_take.fixed b/src/tools/clippy/tests/ui/needless_option_take.fixed
index bfc6d20d5..d732a2686 100644
--- a/src/tools/clippy/tests/ui/needless_option_take.fixed
+++ b/src/tools/clippy/tests/ui/needless_option_take.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
fn main() {
println!("Testing non erroneous option_take_on_temporary");
let mut option = Some(1);
diff --git a/src/tools/clippy/tests/ui/needless_option_take.rs b/src/tools/clippy/tests/ui/needless_option_take.rs
index 697eeab42..f947d874e 100644
--- a/src/tools/clippy/tests/ui/needless_option_take.rs
+++ b/src/tools/clippy/tests/ui/needless_option_take.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
fn main() {
println!("Testing non erroneous option_take_on_temporary");
let mut option = Some(1);
diff --git a/src/tools/clippy/tests/ui/needless_option_take.stderr b/src/tools/clippy/tests/ui/needless_option_take.stderr
index cb3bf015b..d3c22441d 100644
--- a/src/tools/clippy/tests/ui/needless_option_take.stderr
+++ b/src/tools/clippy/tests/ui/needless_option_take.stderr
@@ -1,10 +1,11 @@
error: called `Option::take()` on a temporary value
- --> $DIR/needless_option_take.rs:14:5
+ --> $DIR/needless_option_take.rs:12:5
|
LL | x.as_ref().take();
| ^^^^^^^^^^^^^^^^^ help: try: `x.as_ref()`
|
= note: `-D clippy::needless-option-take` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_option_take)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed
index 9b98f6ea7..b4d9e3297 100644
--- a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed
+++ b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@edition:2018
#![warn(clippy::needless_parens_on_range_literals)]
diff --git a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs
index 088e7b2b9..2f0e54f80 100644
--- a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs
+++ b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@edition:2018
#![warn(clippy::needless_parens_on_range_literals)]
diff --git a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.stderr b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.stderr
index 505f7ac91..c73564e21 100644
--- a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.stderr
+++ b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.stderr
@@ -1,37 +1,38 @@
error: needless parenthesis on range literals can be removed
- --> $DIR/needless_parens_on_range_literals.rs:8:13
+ --> $DIR/needless_parens_on_range_literals.rs:7:13
|
LL | let _ = ('a')..=('z');
| ^^^^^ help: try: `'a'`
|
= note: `-D clippy::needless-parens-on-range-literals` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_parens_on_range_literals)]`
error: needless parenthesis on range literals can be removed
- --> $DIR/needless_parens_on_range_literals.rs:8:21
+ --> $DIR/needless_parens_on_range_literals.rs:7:21
|
LL | let _ = ('a')..=('z');
| ^^^^^ help: try: `'z'`
error: needless parenthesis on range literals can be removed
- --> $DIR/needless_parens_on_range_literals.rs:9:18
+ --> $DIR/needless_parens_on_range_literals.rs:8:18
|
LL | let _ = 'a'..('z');
| ^^^^^ help: try: `'z'`
error: needless parenthesis on range literals can be removed
- --> $DIR/needless_parens_on_range_literals.rs:11:19
+ --> $DIR/needless_parens_on_range_literals.rs:10:19
|
LL | let _ = (1.)..(2.);
| ^^^^ help: try: `2.`
error: needless parenthesis on range literals can be removed
- --> $DIR/needless_parens_on_range_literals.rs:12:13
+ --> $DIR/needless_parens_on_range_literals.rs:11:13
|
LL | let _ = ('a')..;
| ^^^^^ help: try: `'a'`
error: needless parenthesis on range literals can be removed
- --> $DIR/needless_parens_on_range_literals.rs:13:15
+ --> $DIR/needless_parens_on_range_literals.rs:12:15
|
LL | let _ = ..('z');
| ^^^^^ help: try: `'z'`
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
index 4e79e5f53..39d76f999 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
@@ -1,10 +1,7 @@
-#![allow(clippy::if_same_then_else, clippy::no_effect)]
+#![allow(clippy::if_same_then_else, clippy::no_effect, clippy::redundant_closure_call)]
+#![warn(clippy::needless_pass_by_ref_mut)]
#![feature(lint_reasons)]
-
-// just ignore everywhere for now
-//@ignore-32bit
-//@ignore-64bit
-
+//@no-rustfix
use std::ptr::NonNull;
fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
@@ -234,6 +231,44 @@ async fn async_vec(b: &mut Vec<bool>) {
async fn async_vec2(b: &mut Vec<bool>) {
b.push(true);
}
+fn non_mut(n: &str) {}
+//Should warn
+pub async fn call_in_closure1(n: &mut str) {
+ (|| non_mut(n))()
+}
+fn str_mut(str: &mut String) -> bool {
+ str.pop().is_some()
+}
+//Should not warn
+pub async fn call_in_closure2(str: &mut String) {
+ (|| str_mut(str))();
+}
+
+// Should not warn.
+pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
+ || {
+ *n += 1;
+ }
+}
+
+// Should warn.
+pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
+ //~^ ERROR: this argument is a mutable reference, but not used mutably
+ || *n + 1
+}
+
+// Should not warn.
+pub async fn closure3(n: &mut usize) {
+ (|| *n += 1)();
+}
+
+// Should warn.
+pub async fn closure4(n: &mut usize) {
+ //~^ ERROR: this argument is a mutable reference, but not used mutably
+ (|| {
+ let _x = *n + 1;
+ })();
+}
fn main() {
let mut u = 0;
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
index 2e06e7252..aa937c3f6 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
@@ -1,85 +1,86 @@
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:6:11
+ --> $DIR/needless_pass_by_ref_mut.rs:7:11
|
LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
|
= note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:31:12
+ --> $DIR/needless_pass_by_ref_mut.rs:32:12
|
LL | fn foo6(s: &mut Vec<u32>) {
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:44:29
+ --> $DIR/needless_pass_by_ref_mut.rs:45:29
|
LL | fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:49:31
+ --> $DIR/needless_pass_by_ref_mut.rs:50:31
|
LL | fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
| ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:126:16
+ --> $DIR/needless_pass_by_ref_mut.rs:127:16
|
LL | async fn a1(x: &mut i32) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:130:16
+ --> $DIR/needless_pass_by_ref_mut.rs:131:16
|
LL | async fn a2(x: &mut i32, y: String) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:134:16
+ --> $DIR/needless_pass_by_ref_mut.rs:135:16
|
LL | async fn a3(x: &mut i32, y: String, z: String) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:138:16
+ --> $DIR/needless_pass_by_ref_mut.rs:139:16
|
LL | async fn a4(x: &mut i32, y: i32) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:142:24
+ --> $DIR/needless_pass_by_ref_mut.rs:143:24
|
LL | async fn a5(x: i32, y: &mut i32) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:146:24
+ --> $DIR/needless_pass_by_ref_mut.rs:147:24
|
LL | async fn a6(x: i32, y: &mut i32) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:150:32
+ --> $DIR/needless_pass_by_ref_mut.rs:151:32
|
LL | async fn a7(x: i32, y: i32, z: &mut i32) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:154:24
+ --> $DIR/needless_pass_by_ref_mut.rs:155:24
|
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:154:45
+ --> $DIR/needless_pass_by_ref_mut.rs:155:45
|
LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:188:16
+ --> $DIR/needless_pass_by_ref_mut.rs:189:16
|
LL | fn cfg_warn(s: &mut u32) {}
| ^^^^^^^^ help: consider changing to: `&u32`
@@ -87,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {}
= note: this is cfg-gated and may require further changes
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:194:20
+ --> $DIR/needless_pass_by_ref_mut.rs:195:20
|
LL | fn cfg_warn(s: &mut u32) {}
| ^^^^^^^^ help: consider changing to: `&u32`
@@ -95,16 +96,48 @@ LL | fn cfg_warn(s: &mut u32) {}
= note: this is cfg-gated and may require further changes
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:208:39
+ --> $DIR/needless_pass_by_ref_mut.rs:209:39
|
LL | async fn inner_async2(x: &mut i32, y: &mut u32) {
| ^^^^^^^^ help: consider changing to: `&u32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:216:26
+ --> $DIR/needless_pass_by_ref_mut.rs:217:26
|
LL | async fn inner_async3(x: &mut i32, y: &mut u32) {
| ^^^^^^^^ help: consider changing to: `&i32`
-error: aborting due to 17 previous errors
+error: this argument is a mutable reference, but not used mutably
+ --> $DIR/needless_pass_by_ref_mut.rs:236:34
+ |
+LL | pub async fn call_in_closure1(n: &mut str) {
+ | ^^^^^^^^ help: consider changing to: `&str`
+ |
+ = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+ --> $DIR/needless_pass_by_ref_mut.rs:248:25
+ |
+LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
+ | ^^^^^^^^^^ help: consider changing to: `&usize`
+ |
+ = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+ --> $DIR/needless_pass_by_ref_mut.rs:255:20
+ |
+LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
+ | ^^^^^^^^^^ help: consider changing to: `&usize`
+ |
+ = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+ --> $DIR/needless_pass_by_ref_mut.rs:266:26
+ |
+LL | pub async fn closure4(n: &mut usize) {
+ | ^^^^^^^^^^ help: consider changing to: `&usize`
+ |
+ = warning: changing this function will impact semver compatibility
+
+error: aborting due to 21 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.rs b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
index d79ad86b1..14cba5a7e 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
@@ -7,7 +7,7 @@
clippy::single_match,
clippy::uninlined_format_args
)]
-
+//@no-rustfix
use std::borrow::Borrow;
use std::collections::HashSet;
use std::convert::AsRef;
@@ -16,6 +16,8 @@ use std::mem::MaybeUninit;
// `v` should be warned
// `w`, `x` and `y` are allowed (moved or mutated)
fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
+ //~| NOTE: `-D clippy::needless-pass-by-value` implied by `-D warnings`
assert_eq!(v.len(), 42);
consume(w);
@@ -30,12 +32,15 @@ fn consume<T>(_: T) {}
struct Wrapper(String);
fn bar(x: String, y: Wrapper) {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
assert_eq!(x.len(), 42);
assert_eq!(y.0.len(), 42);
}
// V implements `Borrow<V>`, but should be warned correctly
fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
println!("{}", t.borrow());
println!("{}", u.as_ref());
consume(&v);
@@ -48,6 +53,7 @@ fn test_fn<F: Fn(i32) -> i32>(f: F) {
// x should be warned, but y is ok
fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
match x {
Some(Some(_)) => 1, // not moved
_ => 0,
@@ -61,6 +67,8 @@ fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
// x and y should be warned, but z is ok
fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
let Wrapper(s) = z; // moved
let Wrapper(ref t) = y; // not moved
let Wrapper(_) = y; // still not moved
@@ -77,8 +85,13 @@ impl<'a, T> Serialize for &'a T where T: Serialize {}
impl Serialize for i32 {}
fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
+//~^ ERROR: this argument is passed by value, but not consumed in the function body
fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
s.capacity();
let _ = t.clone();
u.capacity();
@@ -92,7 +105,9 @@ impl<T: Serialize, U> S<T, U> {
self,
// taking `self` by value is always allowed
s: String,
+ //~^ ERROR: this argument is passed by value, but not consumed in the function bod
t: String,
+ //~^ ERROR: this argument is passed by value, but not consumed in the function bod
) -> usize {
s.len() + t.capacity()
}
@@ -102,6 +117,8 @@ impl<T: Serialize, U> S<T, U> {
}
fn baz(&self, _u: U, _s: Self) {}
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
}
trait FalsePositive {
@@ -124,12 +141,16 @@ fn range<T: ::std::ops::RangeBounds<usize>>(range: T) {
struct CopyWrapper(u32);
fn bar_copy(x: u32, y: CopyWrapper) {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
assert_eq!(x, 42);
assert_eq!(y.0, 42);
}
// x and y should be warned, but z is ok
fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
+ //~^ ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
+ //~| ERROR: this argument is passed by value, but not consumed in the function body
let CopyWrapper(s) = z; // moved
let CopyWrapper(ref t) = y; // not moved
let CopyWrapper(_) = y; // still not moved
@@ -142,11 +163,13 @@ fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
trait Bar<'a, A> {}
impl<'b, T> Bar<'b, T> for T {}
fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {}
+//~^ ERROR: this argument is passed by value, but not consumed in the function body
// Also this should not cause an ICE. See #2831
trait Club<'a, A> {}
impl<T> Club<'static, T> for T {}
fn more_fun(_item: impl Club<'static, i32>) {}
+//~^ ERROR: this argument is passed by value, but not consumed in the function body
fn is_sync<T>(_: T)
where
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
index 0e660a77d..1c3a63d66 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
@@ -5,57 +5,58 @@ LL | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T
| ^^^^^^ help: consider changing the type to: `&[T]`
|
= note: `-D clippy::needless-pass-by-value` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:32:11
+ --> $DIR/needless_pass_by_value.rs:34:11
|
LL | fn bar(x: String, y: Wrapper) {
| ^^^^^^ help: consider changing the type to: `&str`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:32:22
+ --> $DIR/needless_pass_by_value.rs:34:22
|
LL | fn bar(x: String, y: Wrapper) {
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:38:71
+ --> $DIR/needless_pass_by_value.rs:42:71
|
LL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
| ^ help: consider taking a reference instead: `&V`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:50:18
+ --> $DIR/needless_pass_by_value.rs:55:18
|
LL | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&Option<Option<String>>`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:63:24
+ --> $DIR/needless_pass_by_value.rs:69:24
|
LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:63:36
+ --> $DIR/needless_pass_by_value.rs:69:36
|
LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:79:49
+ --> $DIR/needless_pass_by_value.rs:87:49
|
LL | fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
| ^ help: consider taking a reference instead: `&T`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:81:18
+ --> $DIR/needless_pass_by_value.rs:90:18
|
LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
| ^^^^^^ help: consider taking a reference instead: `&String`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:81:29
+ --> $DIR/needless_pass_by_value.rs:90:29
|
LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
| ^^^^^^
@@ -70,13 +71,13 @@ LL | let _ = t.to_string();
| ~~~~~~~~~~~~~
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:81:40
+ --> $DIR/needless_pass_by_value.rs:90:40
|
LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
| ^^^^^^^^ help: consider taking a reference instead: `&Vec<i32>`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:81:53
+ --> $DIR/needless_pass_by_value.rs:90:53
|
LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
| ^^^^^^^^
@@ -91,85 +92,85 @@ LL | let _ = v.to_owned();
| ~~~~~~~~~~~~
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:94:12
+ --> $DIR/needless_pass_by_value.rs:107:12
|
LL | s: String,
| ^^^^^^ help: consider changing the type to: `&str`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:95:12
+ --> $DIR/needless_pass_by_value.rs:109:12
|
LL | t: String,
| ^^^^^^ help: consider taking a reference instead: `&String`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:104:23
+ --> $DIR/needless_pass_by_value.rs:119:23
|
LL | fn baz(&self, _u: U, _s: Self) {}
| ^ help: consider taking a reference instead: `&U`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:104:30
+ --> $DIR/needless_pass_by_value.rs:119:30
|
LL | fn baz(&self, _u: U, _s: Self) {}
| ^^^^ help: consider taking a reference instead: `&Self`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:126:24
+ --> $DIR/needless_pass_by_value.rs:143:24
|
LL | fn bar_copy(x: u32, y: CopyWrapper) {
| ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
|
help: consider marking this type as `Copy`
- --> $DIR/needless_pass_by_value.rs:124:1
+ --> $DIR/needless_pass_by_value.rs:141:1
|
LL | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:132:29
+ --> $DIR/needless_pass_by_value.rs:150:29
|
LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
| ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
|
help: consider marking this type as `Copy`
- --> $DIR/needless_pass_by_value.rs:124:1
+ --> $DIR/needless_pass_by_value.rs:141:1
|
LL | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:132:45
+ --> $DIR/needless_pass_by_value.rs:150:45
|
LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
| ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
|
help: consider marking this type as `Copy`
- --> $DIR/needless_pass_by_value.rs:124:1
+ --> $DIR/needless_pass_by_value.rs:141:1
|
LL | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:132:61
+ --> $DIR/needless_pass_by_value.rs:150:61
|
LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
| ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
|
help: consider marking this type as `Copy`
- --> $DIR/needless_pass_by_value.rs:124:1
+ --> $DIR/needless_pass_by_value.rs:141:1
|
LL | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:144:40
+ --> $DIR/needless_pass_by_value.rs:165:40
|
LL | fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {}
| ^ help: consider taking a reference instead: `&S`
error: this argument is passed by value, but not consumed in the function body
- --> $DIR/needless_pass_by_value.rs:149:20
+ --> $DIR/needless_pass_by_value.rs:171:20
|
LL | fn more_fun(_item: impl Club<'static, i32>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>`
diff --git a/src/tools/clippy/tests/ui/needless_pub_self.fixed b/src/tools/clippy/tests/ui/needless_pub_self.fixed
index 672b4c318..d9f7b92d0 100644
--- a/src/tools/clippy/tests/ui/needless_pub_self.fixed
+++ b/src/tools/clippy/tests/ui/needless_pub_self.fixed
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(unused)]
#![warn(clippy::needless_pub_self)]
diff --git a/src/tools/clippy/tests/ui/needless_pub_self.rs b/src/tools/clippy/tests/ui/needless_pub_self.rs
index 5ac1edf8e..9f0ec7647 100644
--- a/src/tools/clippy/tests/ui/needless_pub_self.rs
+++ b/src/tools/clippy/tests/ui/needless_pub_self.rs
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(unused)]
#![warn(clippy::needless_pub_self)]
diff --git a/src/tools/clippy/tests/ui/needless_pub_self.stderr b/src/tools/clippy/tests/ui/needless_pub_self.stderr
index 3aa2feb5e..c1f6b908b 100644
--- a/src/tools/clippy/tests/ui/needless_pub_self.stderr
+++ b/src/tools/clippy/tests/ui/needless_pub_self.stderr
@@ -5,6 +5,7 @@ LL | pub(self) fn a() {}
| ^^^^^^^^^ help: remove it
|
= note: `-D clippy::needless-pub-self` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_pub_self)]`
error: unnecessary `pub(in self)`
--> $DIR/needless_pub_self.rs:14:1
diff --git a/src/tools/clippy/tests/ui/needless_question_mark.fixed b/src/tools/clippy/tests/ui/needless_question_mark.fixed
index 679b73d40..07bd6b6f3 100644
--- a/src/tools/clippy/tests/ui/needless_question_mark.fixed
+++ b/src/tools/clippy/tests/ui/needless_question_mark.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_question_mark)]
#![allow(
clippy::needless_return,
diff --git a/src/tools/clippy/tests/ui/needless_question_mark.rs b/src/tools/clippy/tests/ui/needless_question_mark.rs
index a993d3ec3..fbf8a12fd 100644
--- a/src/tools/clippy/tests/ui/needless_question_mark.rs
+++ b/src/tools/clippy/tests/ui/needless_question_mark.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::needless_question_mark)]
#![allow(
clippy::needless_return,
diff --git a/src/tools/clippy/tests/ui/needless_question_mark.stderr b/src/tools/clippy/tests/ui/needless_question_mark.stderr
index d1f89e326..cd961a49f 100644
--- a/src/tools/clippy/tests/ui/needless_question_mark.stderr
+++ b/src/tools/clippy/tests/ui/needless_question_mark.stderr
@@ -1,73 +1,74 @@
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:22:12
+ --> $DIR/needless_question_mark.rs:20:12
|
LL | return Some(to.magic?);
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
|
= note: `-D clippy::needless-question-mark` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_question_mark)]`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:30:12
+ --> $DIR/needless_question_mark.rs:28:12
|
LL | return Some(to.magic?)
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:35:5
+ --> $DIR/needless_question_mark.rs:33:5
|
LL | Some(to.magic?)
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:40:21
+ --> $DIR/needless_question_mark.rs:38:21
|
LL | to.and_then(|t| Some(t.magic?))
| ^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `t.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:49:9
+ --> $DIR/needless_question_mark.rs:47:9
|
LL | Some(t.magic?)
| ^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `t.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:54:12
+ --> $DIR/needless_question_mark.rs:52:12
|
LL | return Ok(tr.magic?);
| ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:61:12
+ --> $DIR/needless_question_mark.rs:59:12
|
LL | return Ok(tr.magic?)
| ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:65:5
+ --> $DIR/needless_question_mark.rs:63:5
|
LL | Ok(tr.magic?)
| ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:69:21
+ --> $DIR/needless_question_mark.rs:67:21
|
LL | tr.and_then(|t| Ok(t.magic?))
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:77:9
+ --> $DIR/needless_question_mark.rs:75:9
|
LL | Ok(t.magic?)
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:84:16
+ --> $DIR/needless_question_mark.rs:82:16
|
LL | return Ok(t.magic?);
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:119:27
+ --> $DIR/needless_question_mark.rs:117:27
|
LL | || -> Option<_> { Some(Some($expr)?) }()
| ^^^^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `Some($expr)`
@@ -78,13 +79,13 @@ LL | let _x = some_and_qmark_in_macro!(x?);
= note: this error originates in the macro `some_and_qmark_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:130:5
+ --> $DIR/needless_question_mark.rs:128:5
|
LL | Some(to.magic?)
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:138:5
+ --> $DIR/needless_question_mark.rs:136:5
|
LL | Ok(s.magic?)
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `s.magic`
diff --git a/src/tools/clippy/tests/ui/needless_range_loop.rs b/src/tools/clippy/tests/ui/needless_range_loop.rs
index a16ef5a5b..3f2421953 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop.rs
+++ b/src/tools/clippy/tests/ui/needless_range_loop.rs
@@ -4,7 +4,7 @@
clippy::unnecessary_literal_unwrap,
clippy::useless_vec
)]
-
+//@no-rustfix
static STATIC: [usize; 4] = [0, 1, 8, 16];
const CONST: [usize; 4] = [0, 1, 8, 16];
const MAX_LEN: usize = 42;
@@ -13,6 +13,8 @@ fn main() {
let mut vec = vec![1, 2, 3, 4];
let vec2 = vec![1, 2, 3, 4];
for i in 0..vec.len() {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
+ //~| NOTE: `-D clippy::needless-range-loop` implied by `-D warnings`
println!("{}", vec[i]);
}
@@ -22,19 +24,23 @@ fn main() {
}
for i in 0..vec.len() {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
let _ = vec[i];
}
// ICE #746
for j in 0..4 {
+ //~^ ERROR: the loop variable `j` is only used to index `STATIC`
println!("{:?}", STATIC[j]);
}
for j in 0..4 {
+ //~^ ERROR: the loop variable `j` is only used to index `CONST`
println!("{:?}", CONST[j]);
}
for i in 0..vec.len() {
+ //~^ ERROR: the loop variable `i` is used to index `vec`
println!("{} {}", vec[i], i);
}
for i in 0..vec.len() {
@@ -43,39 +49,48 @@ fn main() {
}
for i in 0..vec.len() {
+ //~^ ERROR: the loop variable `i` is only used to index `vec2`
println!("{}", vec2[i]);
}
for i in 5..vec.len() {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
println!("{}", vec[i]);
}
for i in 0..MAX_LEN {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
println!("{}", vec[i]);
}
for i in 0..=MAX_LEN {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
println!("{}", vec[i]);
}
for i in 5..10 {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
println!("{}", vec[i]);
}
for i in 5..=10 {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
println!("{}", vec[i]);
}
for i in 5..vec.len() {
+ //~^ ERROR: the loop variable `i` is used to index `vec`
println!("{} {}", vec[i], i);
}
for i in 5..10 {
+ //~^ ERROR: the loop variable `i` is used to index `vec`
println!("{} {}", vec[i], i);
}
// #2542
for i in 0..vec.len() {
+ //~^ ERROR: the loop variable `i` is used to index `vec`
vec[i] = Some(1).unwrap_or_else(|| panic!("error on {}", i));
}
diff --git a/src/tools/clippy/tests/ui/needless_range_loop.stderr b/src/tools/clippy/tests/ui/needless_range_loop.stderr
index 8ca6b880c..0d8893c26 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop.stderr
+++ b/src/tools/clippy/tests/ui/needless_range_loop.stderr
@@ -5,13 +5,14 @@ LL | for i in 0..vec.len() {
| ^^^^^^^^^^^^
|
= note: `-D clippy::needless-range-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]`
help: consider using an iterator
|
LL | for <item> in &vec {
| ~~~~~~ ~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop.rs:24:14
+ --> $DIR/needless_range_loop.rs:26:14
|
LL | for i in 0..vec.len() {
| ^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | for <item> in &vec {
| ~~~~~~ ~~~~
error: the loop variable `j` is only used to index `STATIC`
- --> $DIR/needless_range_loop.rs:29:14
+ --> $DIR/needless_range_loop.rs:32:14
|
LL | for j in 0..4 {
| ^^^^
@@ -33,7 +34,7 @@ LL | for <item> in &STATIC {
| ~~~~~~ ~~~~~~~
error: the loop variable `j` is only used to index `CONST`
- --> $DIR/needless_range_loop.rs:33:14
+ --> $DIR/needless_range_loop.rs:37:14
|
LL | for j in 0..4 {
| ^^^^
@@ -44,7 +45,7 @@ LL | for <item> in &CONST {
| ~~~~~~ ~~~~~~
error: the loop variable `i` is used to index `vec`
- --> $DIR/needless_range_loop.rs:37:14
+ --> $DIR/needless_range_loop.rs:42:14
|
LL | for i in 0..vec.len() {
| ^^^^^^^^^^^^
@@ -55,7 +56,7 @@ LL | for (i, <item>) in vec.iter().enumerate() {
| ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `vec2`
- --> $DIR/needless_range_loop.rs:45:14
+ --> $DIR/needless_range_loop.rs:51:14
|
LL | for i in 0..vec.len() {
| ^^^^^^^^^^^^
@@ -66,7 +67,7 @@ LL | for <item> in vec2.iter().take(vec.len()) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop.rs:49:14
+ --> $DIR/needless_range_loop.rs:56:14
|
LL | for i in 5..vec.len() {
| ^^^^^^^^^^^^
@@ -77,7 +78,7 @@ LL | for <item> in vec.iter().skip(5) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop.rs:53:14
+ --> $DIR/needless_range_loop.rs:61:14
|
LL | for i in 0..MAX_LEN {
| ^^^^^^^^^^
@@ -88,7 +89,7 @@ LL | for <item> in vec.iter().take(MAX_LEN) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop.rs:57:14
+ --> $DIR/needless_range_loop.rs:66:14
|
LL | for i in 0..=MAX_LEN {
| ^^^^^^^^^^^
@@ -99,7 +100,7 @@ LL | for <item> in vec.iter().take(MAX_LEN + 1) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop.rs:61:14
+ --> $DIR/needless_range_loop.rs:71:14
|
LL | for i in 5..10 {
| ^^^^^
@@ -110,7 +111,7 @@ LL | for <item> in vec.iter().take(10).skip(5) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop.rs:65:14
+ --> $DIR/needless_range_loop.rs:76:14
|
LL | for i in 5..=10 {
| ^^^^^^
@@ -121,7 +122,7 @@ LL | for <item> in vec.iter().take(10 + 1).skip(5) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is used to index `vec`
- --> $DIR/needless_range_loop.rs:69:14
+ --> $DIR/needless_range_loop.rs:81:14
|
LL | for i in 5..vec.len() {
| ^^^^^^^^^^^^
@@ -132,7 +133,7 @@ LL | for (i, <item>) in vec.iter().enumerate().skip(5) {
| ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is used to index `vec`
- --> $DIR/needless_range_loop.rs:73:14
+ --> $DIR/needless_range_loop.rs:86:14
|
LL | for i in 5..10 {
| ^^^^^
@@ -143,7 +144,7 @@ LL | for (i, <item>) in vec.iter().enumerate().take(10).skip(5) {
| ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is used to index `vec`
- --> $DIR/needless_range_loop.rs:78:14
+ --> $DIR/needless_range_loop.rs:92:14
|
LL | for i in 0..vec.len() {
| ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_range_loop2.rs b/src/tools/clippy/tests/ui/needless_range_loop2.rs
index 516d99a35..787ff18f3 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop2.rs
+++ b/src/tools/clippy/tests/ui/needless_range_loop2.rs
@@ -1,6 +1,6 @@
#![warn(clippy::needless_range_loop)]
#![allow(clippy::useless_vec)]
-
+//@no-rustfix
fn calc_idx(i: usize) -> usize {
(i + i + 20) % 4
}
@@ -9,6 +9,8 @@ fn main() {
let ns = vec![2, 3, 5, 7];
for i in 3..10 {
+ //~^ ERROR: the loop variable `i` is only used to index `ns`
+ //~| NOTE: `-D clippy::needless-range-loop` implied by `-D warnings`
println!("{}", ns[i]);
}
@@ -30,12 +32,14 @@ fn main() {
let mut ms = vec![1, 2, 3, 4, 5, 6];
for i in 0..ms.len() {
+ //~^ ERROR: the loop variable `i` is only used to index `ms`
ms[i] *= 2;
}
assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);
let mut ms = vec![1, 2, 3, 4, 5, 6];
for i in 0..ms.len() {
+ //~^ ERROR: the loop variable `i` is only used to index `ms`
let x = &mut ms[i];
*x *= 2;
}
@@ -60,6 +64,7 @@ fn main() {
let mut vec = vec![0; 9];
for i in x..x + 4 {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
vec[i] += 1;
}
@@ -67,20 +72,24 @@ fn main() {
let mut vec = vec![0; 10];
for i in x..=x + 4 {
+ //~^ ERROR: the loop variable `i` is only used to index `vec`
vec[i] += 1;
}
let arr = [1, 2, 3];
for i in 0..3 {
+ //~^ ERROR: the loop variable `i` is only used to index `arr`
println!("{}", arr[i]);
}
for i in 0..2 {
+ //~^ ERROR: the loop variable `i` is only used to index `arr`
println!("{}", arr[i]);
}
for i in 1..3 {
+ //~^ ERROR: the loop variable `i` is only used to index `arr`
println!("{}", arr[i]);
}
diff --git a/src/tools/clippy/tests/ui/needless_range_loop2.stderr b/src/tools/clippy/tests/ui/needless_range_loop2.stderr
index 8c4f5d954..3d1d9e1bf 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop2.stderr
+++ b/src/tools/clippy/tests/ui/needless_range_loop2.stderr
@@ -5,13 +5,14 @@ LL | for i in 3..10 {
| ^^^^^
|
= note: `-D clippy::needless-range-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]`
help: consider using an iterator
|
LL | for <item> in ns.iter().take(10).skip(3) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `ms`
- --> $DIR/needless_range_loop2.rs:32:14
+ --> $DIR/needless_range_loop2.rs:34:14
|
LL | for i in 0..ms.len() {
| ^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | for <item> in &mut ms {
| ~~~~~~ ~~~~~~~
error: the loop variable `i` is only used to index `ms`
- --> $DIR/needless_range_loop2.rs:38:14
+ --> $DIR/needless_range_loop2.rs:41:14
|
LL | for i in 0..ms.len() {
| ^^^^^^^^^^^
@@ -33,7 +34,7 @@ LL | for <item> in &mut ms {
| ~~~~~~ ~~~~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop2.rs:62:14
+ --> $DIR/needless_range_loop2.rs:66:14
|
LL | for i in x..x + 4 {
| ^^^^^^^^
@@ -44,7 +45,7 @@ LL | for <item> in vec.iter_mut().skip(x).take(4) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `vec`
- --> $DIR/needless_range_loop2.rs:69:14
+ --> $DIR/needless_range_loop2.rs:74:14
|
LL | for i in x..=x + 4 {
| ^^^^^^^^^
@@ -55,7 +56,7 @@ LL | for <item> in vec.iter_mut().skip(x).take(4 + 1) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `arr`
- --> $DIR/needless_range_loop2.rs:75:14
+ --> $DIR/needless_range_loop2.rs:81:14
|
LL | for i in 0..3 {
| ^^^^
@@ -66,7 +67,7 @@ LL | for <item> in &arr {
| ~~~~~~ ~~~~
error: the loop variable `i` is only used to index `arr`
- --> $DIR/needless_range_loop2.rs:79:14
+ --> $DIR/needless_range_loop2.rs:86:14
|
LL | for i in 0..2 {
| ^^^^
@@ -77,7 +78,7 @@ LL | for <item> in arr.iter().take(2) {
| ~~~~~~ ~~~~~~~~~~~~~~~~~~
error: the loop variable `i` is only used to index `arr`
- --> $DIR/needless_range_loop2.rs:83:14
+ --> $DIR/needless_range_loop2.rs:91:14
|
LL | for i in 1..3 {
| ^^^^
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.fixed b/src/tools/clippy/tests/ui/needless_raw_string.fixed
index b36912efb..855498105 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.fixed
+++ b/src/tools/clippy/tests/ui/needless_raw_string.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
#![warn(clippy::needless_raw_strings)]
#![feature(c_str_literals)]
@@ -10,8 +9,13 @@ fn main() {
b"aaa";
br#""aaa""#;
br#"\s"#;
- // currently disabled: https://github.com/rust-lang/rust/issues/113333
- // cr#"aaa"#;
- // cr#""aaa""#;
- // cr#"\s"#;
+ c"aaa";
+ cr#""aaa""#;
+ cr#"\s"#;
+
+ "
+ a
+ multiline
+ string
+ ";
}
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.rs b/src/tools/clippy/tests/ui/needless_raw_string.rs
index 8f48e7dab..06d497303 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.rs
+++ b/src/tools/clippy/tests/ui/needless_raw_string.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
#![warn(clippy::needless_raw_strings)]
#![feature(c_str_literals)]
@@ -10,8 +9,13 @@ fn main() {
br#"aaa"#;
br#""aaa""#;
br#"\s"#;
- // currently disabled: https://github.com/rust-lang/rust/issues/113333
- // cr#"aaa"#;
- // cr#""aaa""#;
- // cr#"\s"#;
+ cr#"aaa"#;
+ cr#""aaa""#;
+ cr#"\s"#;
+
+ r#"
+ a
+ multiline
+ string
+ "#;
}
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.stderr b/src/tools/clippy/tests/ui/needless_raw_string.stderr
index cfb07b647..e6806b31b 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string.stderr
@@ -1,16 +1,59 @@
error: unnecessary raw string literal
- --> $DIR/needless_raw_string.rs:7:5
+ --> $DIR/needless_raw_string.rs:6:5
|
LL | r#"aaa"#;
- | ^^^^^^^^ help: try: `"aaa"`
+ | ^^^^^^^^
|
= note: `-D clippy::needless-raw-strings` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]`
+help: try
+ |
+LL - r#"aaa"#;
+LL + "aaa";
+ |
error: unnecessary raw string literal
- --> $DIR/needless_raw_string.rs:10:5
+ --> $DIR/needless_raw_string.rs:9:5
|
LL | br#"aaa"#;
- | ^^^^^^^^^ help: try: `b"aaa"`
+ | ^^^^^^^^^
+ |
+help: try
+ |
+LL - br#"aaa"#;
+LL + b"aaa";
+ |
+
+error: unnecessary raw string literal
+ --> $DIR/needless_raw_string.rs:12:5
+ |
+LL | cr#"aaa"#;
+ | ^^^^^^^^^
+ |
+help: try
+ |
+LL - cr#"aaa"#;
+LL + c"aaa";
+ |
+
+error: unnecessary raw string literal
+ --> $DIR/needless_raw_string.rs:16:5
+ |
+LL | / r#"
+LL | | a
+LL | | multiline
+LL | | string
+LL | | "#;
+ | |______^
+ |
+help: try
+ |
+LL ~ "
+LL | a
+LL | multiline
+LL | string
+LL ~ ";
+ |
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
index c8507c727..c99c2f465 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
@@ -1,20 +1,27 @@
-//@run-rustfix
#![allow(clippy::no_effect, unused)]
#![warn(clippy::needless_raw_string_hashes)]
#![feature(c_str_literals)]
fn main() {
- r#"aaa"#;
+ r"\aaa";
r#"Hello "world"!"#;
r####" "### "## "# "####;
r###" "aa" "# "## "###;
- br#"aaa"#;
+ br"\aaa";
br#"Hello "world"!"#;
br####" "### "## "# "####;
br###" "aa" "# "## "###;
- // currently disabled: https://github.com/rust-lang/rust/issues/113333
- // cr#"aaa"#;
- // cr##"Hello "world"!"##;
- // cr######" "### "## "# "######;
- // cr######" "aa" "# "## "######;
+ cr"\aaa";
+ cr#"Hello "world"!"#;
+ cr####" "### "## "# "####;
+ cr###" "aa" "# "## "###;
+
+ r"
+ \a
+ multiline
+ string
+ ";
+
+ r"rust";
+ r"hello world";
}
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
index 912fbde16..dcc2af69f 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
@@ -1,20 +1,27 @@
-//@run-rustfix
#![allow(clippy::no_effect, unused)]
#![warn(clippy::needless_raw_string_hashes)]
#![feature(c_str_literals)]
fn main() {
- r#"aaa"#;
+ r#"\aaa"#;
r##"Hello "world"!"##;
r######" "### "## "# "######;
r######" "aa" "# "## "######;
- br#"aaa"#;
+ br#"\aaa"#;
br##"Hello "world"!"##;
br######" "### "## "# "######;
br######" "aa" "# "## "######;
- // currently disabled: https://github.com/rust-lang/rust/issues/113333
- // cr#"aaa"#;
- // cr##"Hello "world"!"##;
- // cr######" "### "## "# "######;
- // cr######" "aa" "# "## "######;
+ cr#"\aaa"#;
+ cr##"Hello "world"!"##;
+ cr######" "### "## "# "######;
+ cr######" "aa" "# "## "######;
+
+ r#"
+ \a
+ multiline
+ string
+ "#;
+
+ r###"rust"###;
+ r#"hello world"#;
}
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
index 30e6783a3..4399c6555 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
@@ -1,40 +1,191 @@
error: unnecessary hashes around raw string literal
- --> $DIR/needless_raw_string_hashes.rs:8:5
+ --> $DIR/needless_raw_string_hashes.rs:6:5
|
-LL | r##"Hello "world"!"##;
- | ^^^^^^^^^^^^^^^^^^^^^ help: try: `r#"Hello "world"!"#`
+LL | r#"\aaa"#;
+ | ^^^^^^^^^
|
= note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_raw_string_hashes)]`
+help: remove all the hashes around the literal
+ |
+LL - r#"\aaa"#;
+LL + r"\aaa";
+ |
error: unnecessary hashes around raw string literal
- --> $DIR/needless_raw_string_hashes.rs:9:5
+ --> $DIR/needless_raw_string_hashes.rs:7:5
+ |
+LL | r##"Hello "world"!"##;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove one hash from both sides of the literal
+ |
+LL - r##"Hello "world"!"##;
+LL + r#"Hello "world"!"#;
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:8:5
|
LL | r######" "### "## "# "######;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r####" "### "## "# "####`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove 2 hashes from both sides of the literal
+ |
+LL - r######" "### "## "# "######;
+LL + r####" "### "## "# "####;
+ |
error: unnecessary hashes around raw string literal
- --> $DIR/needless_raw_string_hashes.rs:10:5
+ --> $DIR/needless_raw_string_hashes.rs:9:5
|
LL | r######" "aa" "# "## "######;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r###" "aa" "# "## "###`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove 3 hashes from both sides of the literal
+ |
+LL - r######" "aa" "# "## "######;
+LL + r###" "aa" "# "## "###;
+ |
error: unnecessary hashes around raw string literal
- --> $DIR/needless_raw_string_hashes.rs:12:5
+ --> $DIR/needless_raw_string_hashes.rs:10:5
+ |
+LL | br#"\aaa"#;
+ | ^^^^^^^^^^
+ |
+help: remove all the hashes around the literal
+ |
+LL - br#"\aaa"#;
+LL + br"\aaa";
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:11:5
|
LL | br##"Hello "world"!"##;
- | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `br#"Hello "world"!"#`
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove one hash from both sides of the literal
+ |
+LL - br##"Hello "world"!"##;
+LL + br#"Hello "world"!"#;
+ |
error: unnecessary hashes around raw string literal
- --> $DIR/needless_raw_string_hashes.rs:13:5
+ --> $DIR/needless_raw_string_hashes.rs:12:5
|
LL | br######" "### "## "# "######;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `br####" "### "## "# "####`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove 2 hashes from both sides of the literal
+ |
+LL - br######" "### "## "# "######;
+LL + br####" "### "## "# "####;
+ |
error: unnecessary hashes around raw string literal
- --> $DIR/needless_raw_string_hashes.rs:14:5
+ --> $DIR/needless_raw_string_hashes.rs:13:5
|
LL | br######" "aa" "# "## "######;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `br###" "aa" "# "## "###`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove 3 hashes from both sides of the literal
+ |
+LL - br######" "aa" "# "## "######;
+LL + br###" "aa" "# "## "###;
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:14:5
+ |
+LL | cr#"\aaa"#;
+ | ^^^^^^^^^^
+ |
+help: remove all the hashes around the literal
+ |
+LL - cr#"\aaa"#;
+LL + cr"\aaa";
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:15:5
+ |
+LL | cr##"Hello "world"!"##;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove one hash from both sides of the literal
+ |
+LL - cr##"Hello "world"!"##;
+LL + cr#"Hello "world"!"#;
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:16:5
+ |
+LL | cr######" "### "## "# "######;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove 2 hashes from both sides of the literal
+ |
+LL - cr######" "### "## "# "######;
+LL + cr####" "### "## "# "####;
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:17:5
+ |
+LL | cr######" "aa" "# "## "######;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: remove 3 hashes from both sides of the literal
+ |
+LL - cr######" "aa" "# "## "######;
+LL + cr###" "aa" "# "## "###;
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:19:5
+ |
+LL | / r#"
+LL | | \a
+LL | | multiline
+LL | | string
+LL | | "#;
+ | |______^
+ |
+help: remove all the hashes around the literal
+ |
+LL ~ r"
+LL | \a
+LL | multiline
+LL | string
+LL ~ ";
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:25:5
+ |
+LL | r###"rust"###;
+ | ^^^^^^^^^^^^^
+ |
+help: remove all the hashes around the literal
+ |
+LL - r###"rust"###;
+LL + r"rust";
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:26:5
+ |
+LL | r#"hello world"#;
+ | ^^^^^^^^^^^^^^^^
+ |
+help: remove all the hashes around the literal
+ |
+LL - r#"hello world"#;
+LL + r"hello world";
+ |
-error: aborting due to 6 previous errors
+error: aborting due to 15 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed
index 4dabf3139..f9eb39d49 100644
--- a/src/tools/clippy/tests/ui/needless_return.fixed
+++ b/src/tools/clippy/tests/ui/needless_return.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(lint_reasons)]
#![feature(yeet_expr)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs
index 542f562b3..4dd2e22ea 100644
--- a/src/tools/clippy/tests/ui/needless_return.rs
+++ b/src/tools/clippy/tests/ui/needless_return.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(lint_reasons)]
#![feature(yeet_expr)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index 1d9d23d30..cc4883111 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -1,10 +1,11 @@
error: unneeded `return` statement
- --> $DIR/needless_return.rs:28:5
+ --> $DIR/needless_return.rs:26:5
|
LL | return true;
| ^^^^^^^^^^^
|
= note: `-D clippy::needless-return` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_return)]`
help: remove `return`
|
LL - return true;
@@ -12,7 +13,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:32:5
+ --> $DIR/needless_return.rs:30:5
|
LL | return true;
| ^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:37:5
+ --> $DIR/needless_return.rs:35:5
|
LL | return true;;;
| ^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:42:5
+ --> $DIR/needless_return.rs:40:5
|
LL | return true;; ; ;
| ^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:47:9
+ --> $DIR/needless_return.rs:45:9
|
LL | return true;
| ^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:49:9
+ --> $DIR/needless_return.rs:47:9
|
LL | return false;
| ^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL + false
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:55:17
+ --> $DIR/needless_return.rs:53:17
|
LL | true => return false,
| ^^^^^^^^^^^^
@@ -83,7 +84,7 @@ LL | true => false,
| ~~~~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:57:13
+ --> $DIR/needless_return.rs:55:13
|
LL | return true;
| ^^^^^^^^^^^
@@ -95,7 +96,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:64:9
+ --> $DIR/needless_return.rs:62:9
|
LL | return true;
| ^^^^^^^^^^^
@@ -107,7 +108,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:66:16
+ --> $DIR/needless_return.rs:64:16
|
LL | let _ = || return true;
| ^^^^^^^^^^^
@@ -118,7 +119,7 @@ LL | let _ = || true;
| ~~~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:70:5
+ --> $DIR/needless_return.rs:68:5
|
LL | return the_answer!();
| ^^^^^^^^^^^^^^^^^^^^
@@ -130,7 +131,7 @@ LL + the_answer!()
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:73:21
+ --> $DIR/needless_return.rs:71:21
|
LL | fn test_void_fun() {
| _____________________^
@@ -145,7 +146,7 @@ LL + fn test_void_fun() {
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:78:11
+ --> $DIR/needless_return.rs:76:11
|
LL | if b {
| ___________^
@@ -160,7 +161,7 @@ LL + if b {
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:80:13
+ --> $DIR/needless_return.rs:78:13
|
LL | } else {
| _____________^
@@ -175,7 +176,7 @@ LL + } else {
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:88:14
+ --> $DIR/needless_return.rs:86:14
|
LL | _ => return,
| ^^^^^^
@@ -186,7 +187,7 @@ LL | _ => (),
| ~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:96:24
+ --> $DIR/needless_return.rs:94:24
|
LL | let _ = 42;
| ________________________^
@@ -201,7 +202,7 @@ LL + let _ = 42;
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:99:14
+ --> $DIR/needless_return.rs:97:14
|
LL | _ => return,
| ^^^^^^
@@ -212,7 +213,7 @@ LL | _ => (),
| ~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:112:9
+ --> $DIR/needless_return.rs:110:9
|
LL | return String::from("test");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -224,7 +225,7 @@ LL + String::from("test")
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:114:9
+ --> $DIR/needless_return.rs:112:9
|
LL | return String::new();
| ^^^^^^^^^^^^^^^^^^^^
@@ -236,7 +237,7 @@ LL + String::new()
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:136:32
+ --> $DIR/needless_return.rs:134:32
|
LL | bar.unwrap_or_else(|_| return)
| ^^^^^^
@@ -247,7 +248,7 @@ LL | bar.unwrap_or_else(|_| {})
| ~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:140:21
+ --> $DIR/needless_return.rs:138:21
|
LL | let _ = || {
| _____________________^
@@ -262,7 +263,7 @@ LL + let _ = || {
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:143:20
+ --> $DIR/needless_return.rs:141:20
|
LL | let _ = || return;
| ^^^^^^
@@ -273,7 +274,7 @@ LL | let _ = || {};
| ~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:149:32
+ --> $DIR/needless_return.rs:147:32
|
LL | res.unwrap_or_else(|_| return Foo)
| ^^^^^^^^^^
@@ -284,7 +285,7 @@ LL | res.unwrap_or_else(|_| Foo)
| ~~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:158:5
+ --> $DIR/needless_return.rs:156:5
|
LL | return true;
| ^^^^^^^^^^^
@@ -296,7 +297,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:162:5
+ --> $DIR/needless_return.rs:160:5
|
LL | return true;
| ^^^^^^^^^^^
@@ -308,7 +309,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:167:9
+ --> $DIR/needless_return.rs:165:9
|
LL | return true;
| ^^^^^^^^^^^
@@ -320,7 +321,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:169:9
+ --> $DIR/needless_return.rs:167:9
|
LL | return false;
| ^^^^^^^^^^^^
@@ -332,7 +333,7 @@ LL + false
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:175:17
+ --> $DIR/needless_return.rs:173:17
|
LL | true => return false,
| ^^^^^^^^^^^^
@@ -343,7 +344,7 @@ LL | true => false,
| ~~~~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:177:13
+ --> $DIR/needless_return.rs:175:13
|
LL | return true;
| ^^^^^^^^^^^
@@ -355,7 +356,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:184:9
+ --> $DIR/needless_return.rs:182:9
|
LL | return true;
| ^^^^^^^^^^^
@@ -367,7 +368,7 @@ LL + true
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:186:16
+ --> $DIR/needless_return.rs:184:16
|
LL | let _ = || return true;
| ^^^^^^^^^^^
@@ -378,7 +379,7 @@ LL | let _ = || true;
| ~~~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:190:5
+ --> $DIR/needless_return.rs:188:5
|
LL | return the_answer!();
| ^^^^^^^^^^^^^^^^^^^^
@@ -390,7 +391,7 @@ LL + the_answer!()
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:193:33
+ --> $DIR/needless_return.rs:191:33
|
LL | async fn async_test_void_fun() {
| _________________________________^
@@ -405,7 +406,7 @@ LL + async fn async_test_void_fun() {
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:198:11
+ --> $DIR/needless_return.rs:196:11
|
LL | if b {
| ___________^
@@ -420,7 +421,7 @@ LL + if b {
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:200:13
+ --> $DIR/needless_return.rs:198:13
|
LL | } else {
| _____________^
@@ -435,7 +436,7 @@ LL + } else {
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:208:14
+ --> $DIR/needless_return.rs:206:14
|
LL | _ => return,
| ^^^^^^
@@ -446,7 +447,7 @@ LL | _ => (),
| ~~
error: unneeded `return` statement
- --> $DIR/needless_return.rs:221:9
+ --> $DIR/needless_return.rs:219:9
|
LL | return String::from("test");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -458,7 +459,7 @@ LL + String::from("test")
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:223:9
+ --> $DIR/needless_return.rs:221:9
|
LL | return String::new();
| ^^^^^^^^^^^^^^^^^^^^
@@ -470,7 +471,7 @@ LL + String::new()
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:239:5
+ --> $DIR/needless_return.rs:237:5
|
LL | return format!("Hello {}", "world!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -482,7 +483,7 @@ LL + format!("Hello {}", "world!")
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:251:9
+ --> $DIR/needless_return.rs:249:9
|
LL | return true;
| ^^^^^^^^^^^
@@ -496,7 +497,7 @@ LL ~ }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:253:9
+ --> $DIR/needless_return.rs:251:9
|
LL | return false;
| ^^^^^^^^^^^^
@@ -508,7 +509,7 @@ LL ~ }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:260:13
+ --> $DIR/needless_return.rs:258:13
|
LL | return 10;
| ^^^^^^^^^
@@ -523,7 +524,7 @@ LL ~ }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:263:13
+ --> $DIR/needless_return.rs:261:13
|
LL | return 100;
| ^^^^^^^^^^
@@ -536,7 +537,7 @@ LL ~ }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:271:9
+ --> $DIR/needless_return.rs:269:9
|
LL | return 0;
| ^^^^^^^^
@@ -548,7 +549,7 @@ LL ~ }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:278:13
+ --> $DIR/needless_return.rs:276:13
|
LL | return *(x as *const isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -563,7 +564,7 @@ LL ~ }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:280:13
+ --> $DIR/needless_return.rs:278:13
|
LL | return !*(x as *const isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -576,7 +577,7 @@ LL ~ }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:287:20
+ --> $DIR/needless_return.rs:285:20
|
LL | let _ = 42;
| ____________________^
@@ -593,7 +594,7 @@ LL + let _ = 42;
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:294:20
+ --> $DIR/needless_return.rs:292:20
|
LL | let _ = 42; return;
| ^^^^^^^
@@ -605,7 +606,7 @@ LL + let _ = 42;
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:306:9
+ --> $DIR/needless_return.rs:304:9
|
LL | return Ok(format!("ok!"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -617,7 +618,7 @@ LL + Ok(format!("ok!"))
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:308:9
+ --> $DIR/needless_return.rs:306:9
|
LL | return Err(format!("err!"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -629,7 +630,7 @@ LL + Err(format!("err!"))
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:314:9
+ --> $DIR/needless_return.rs:312:9
|
LL | return if true { 1 } else { 2 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -641,7 +642,7 @@ LL + if true { 1 } else { 2 }
|
error: unneeded `return` statement
- --> $DIR/needless_return.rs:318:9
+ --> $DIR/needless_return.rs:316:9
|
LL | return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed
index d6e47d07b..52d541809 100644
--- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed
+++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(
clippy::needless_return,
clippy::no_effect,
diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs
index 4fc04d363..d253cae4d 100644
--- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs
+++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(
clippy::needless_return,
clippy::no_effect,
diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr b/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr
index e1d91638d..0de063380 100644
--- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr
+++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.stderr
@@ -1,10 +1,11 @@
error: unneeded `return` statement with `?` operator
- --> $DIR/needless_return_with_question_mark.rs:28:5
+ --> $DIR/needless_return_with_question_mark.rs:27:5
|
LL | return Err(())?;
| ^^^^^^^ help: remove it
|
= note: `-D clippy::needless-return-with-question-mark` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_return_with_question_mark)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/needless_splitn.fixed b/src/tools/clippy/tests/ui/needless_splitn.fixed
index 30a038312..efc47533e 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.fixed
+++ b/src/tools/clippy/tests/ui/needless_splitn.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@edition:2018
#![warn(clippy::needless_splitn)]
diff --git a/src/tools/clippy/tests/ui/needless_splitn.rs b/src/tools/clippy/tests/ui/needless_splitn.rs
index 1b0b9a598..a4a3736ee 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.rs
+++ b/src/tools/clippy/tests/ui/needless_splitn.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@edition:2018
#![warn(clippy::needless_splitn)]
diff --git a/src/tools/clippy/tests/ui/needless_splitn.stderr b/src/tools/clippy/tests/ui/needless_splitn.stderr
index 0005f7581..f347ca760 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.stderr
+++ b/src/tools/clippy/tests/ui/needless_splitn.stderr
@@ -1,79 +1,80 @@
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:14:13
+ --> $DIR/needless_splitn.rs:13:13
|
LL | let _ = str.splitn(2, '=').next();
| ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`
|
= note: `-D clippy::needless-splitn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_splitn)]`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:15:13
+ --> $DIR/needless_splitn.rs:14:13
|
LL | let _ = str.splitn(2, '=').nth(0);
| ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:18:18
+ --> $DIR/needless_splitn.rs:17:18
|
LL | let (_, _) = str.splitn(3, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:21:13
+ --> $DIR/needless_splitn.rs:20:13
|
LL | let _ = str.rsplitn(2, '=').next();
| ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:22:13
+ --> $DIR/needless_splitn.rs:21:13
|
LL | let _ = str.rsplitn(2, '=').nth(0);
| ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:25:18
+ --> $DIR/needless_splitn.rs:24:18
|
LL | let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:27:13
+ --> $DIR/needless_splitn.rs:26:13
|
LL | let _ = str.splitn(5, '=').next();
| ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:28:13
+ --> $DIR/needless_splitn.rs:27:13
|
LL | let _ = str.splitn(5, '=').nth(3);
| ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:34:13
+ --> $DIR/needless_splitn.rs:33:13
|
LL | let _ = s.splitn(2, '=').next()?;
| ^^^^^^^^^^^^^^^^ help: try: `s.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:35:13
+ --> $DIR/needless_splitn.rs:34:13
|
LL | let _ = s.splitn(2, '=').nth(0)?;
| ^^^^^^^^^^^^^^^^ help: try: `s.split('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:36:13
+ --> $DIR/needless_splitn.rs:35:13
|
LL | let _ = s.rsplitn(2, '=').next()?;
| ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:37:13
+ --> $DIR/needless_splitn.rs:36:13
|
LL | let _ = s.rsplitn(2, '=').nth(0)?;
| ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:45:13
+ --> $DIR/needless_splitn.rs:44:13
|
LL | let _ = "key=value".splitn(2, '=').nth(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split('=')`
diff --git a/src/tools/clippy/tests/ui/needless_update.rs b/src/tools/clippy/tests/ui/needless_update.rs
index 4e8517cad..7c59abf07 100644
--- a/src/tools/clippy/tests/ui/needless_update.rs
+++ b/src/tools/clippy/tests/ui/needless_update.rs
@@ -17,6 +17,8 @@ fn main() {
S { ..base }; // no error
S { a: 1, ..base }; // no error
S { a: 1, b: 1, ..base };
+ //~^ ERROR: struct update has no effect, all the fields in the struct have already bee
+ //~| NOTE: `-D clippy::needless-update` implied by `-D warnings`
let base = T { x: 0, y: 0 };
T { ..base }; // no error
diff --git a/src/tools/clippy/tests/ui/needless_update.stderr b/src/tools/clippy/tests/ui/needless_update.stderr
index b154b3b30..3e9e2941a 100644
--- a/src/tools/clippy/tests/ui/needless_update.stderr
+++ b/src/tools/clippy/tests/ui/needless_update.stderr
@@ -5,6 +5,7 @@ LL | S { a: 1, b: 1, ..base };
| ^^^^
|
= note: `-D clippy::needless-update` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_update)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.rs b/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.rs
index 2d392c593..c79fd2665 100644
--- a/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.rs
+++ b/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.rs
@@ -14,15 +14,20 @@ fn main() {
// Not Less but potentially Greater, Equal or Uncomparable.
let _not_less = !(a_value < another_value);
+ //~^ ERROR: the use of negated comparison operators on partially ordered types produce
+ //~| NOTE: `-D clippy::neg-cmp-op-on-partial-ord` implied by `-D warnings`
// Not Less or Equal but potentially Greater or Uncomparable.
let _not_less_or_equal = !(a_value <= another_value);
+ //~^ ERROR: the use of negated comparison operators on partially ordered types produce
// Not Greater but potentially Less, Equal or Uncomparable.
let _not_greater = !(a_value > another_value);
+ //~^ ERROR: the use of negated comparison operators on partially ordered types produce
// Not Greater or Equal but potentially Less or Uncomparable.
let _not_greater_or_equal = !(a_value >= another_value);
+ //~^ ERROR: the use of negated comparison operators on partially ordered types produce
// --- Good ---
diff --git a/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.stderr b/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.stderr
index c78560007..c64d96b4b 100644
--- a/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.stderr
+++ b/src/tools/clippy/tests/ui/neg_cmp_op_on_partial_ord.stderr
@@ -5,21 +5,22 @@ LL | let _not_less = !(a_value < another_value);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::neg-cmp-op-on-partial-ord` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::neg_cmp_op_on_partial_ord)]`
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
- --> $DIR/neg_cmp_op_on_partial_ord.rs:19:30
+ --> $DIR/neg_cmp_op_on_partial_ord.rs:21:30
|
LL | let _not_less_or_equal = !(a_value <= another_value);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
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
- --> $DIR/neg_cmp_op_on_partial_ord.rs:22:24
+ --> $DIR/neg_cmp_op_on_partial_ord.rs:25:24
|
LL | let _not_greater = !(a_value > another_value);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
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
- --> $DIR/neg_cmp_op_on_partial_ord.rs:25:33
+ --> $DIR/neg_cmp_op_on_partial_ord.rs:29:33
|
LL | let _not_greater_or_equal = !(a_value >= another_value);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/neg_multiply.fixed b/src/tools/clippy/tests/ui/neg_multiply.fixed
index e07e7c88d..52edea73a 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.fixed
+++ b/src/tools/clippy/tests/ui/neg_multiply.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::neg_multiply)]
#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/neg_multiply.rs b/src/tools/clippy/tests/ui/neg_multiply.rs
index 2887af7b4..23092a35e 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.rs
+++ b/src/tools/clippy/tests/ui/neg_multiply.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::neg_multiply)]
#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/neg_multiply.stderr b/src/tools/clippy/tests/ui/neg_multiply.stderr
index 388ef29eb..abfc94f97 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.stderr
+++ b/src/tools/clippy/tests/ui/neg_multiply.stderr
@@ -1,49 +1,50 @@
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:29:5
+ --> $DIR/neg_multiply.rs:28:5
|
LL | x * -1;
| ^^^^^^ help: consider using: `-x`
|
= note: `-D clippy::neg-multiply` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::neg_multiply)]`
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:31:5
+ --> $DIR/neg_multiply.rs:30:5
|
LL | -1 * x;
| ^^^^^^ help: consider using: `-x`
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:33:11
+ --> $DIR/neg_multiply.rs:32:11
|
LL | 100 + x * -1;
| ^^^^^^ help: consider using: `-x`
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:35:5
+ --> $DIR/neg_multiply.rs:34:5
|
LL | (100 + x) * -1;
| ^^^^^^^^^^^^^^ help: consider using: `-(100 + x)`
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:37:5
+ --> $DIR/neg_multiply.rs:36:5
|
LL | -1 * 17;
| ^^^^^^^ help: consider using: `-17`
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:39:14
+ --> $DIR/neg_multiply.rs:38:14
|
LL | 0xcafe | 0xff00 * -1;
| ^^^^^^^^^^^ help: consider using: `-0xff00`
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:41:5
+ --> $DIR/neg_multiply.rs:40:5
|
LL | 3_usize as i32 * -1;
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3_usize as i32)`
error: this multiplication by -1 can be written more succinctly
- --> $DIR/neg_multiply.rs:42:5
+ --> $DIR/neg_multiply.rs:41:5
|
LL | (3_usize as i32) * -1;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3_usize as i32)`
diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs
index eb179f30e..c67a6d449 100644
--- a/src/tools/clippy/tests/ui/never_loop.rs
+++ b/src/tools/clippy/tests/ui/never_loop.rs
@@ -6,10 +6,12 @@
unused_variables,
clippy::while_immutable_condition
)]
-
+//@no-rustfix
fn test1() {
let mut x = 0;
loop {
+ //~^ ERROR: this loop never actually loops
+ //~| NOTE: `#[deny(clippy::never_loop)]` on by default
// clippy::never_loop
x += 1;
if x == 1 {
@@ -32,6 +34,7 @@ fn test2() {
fn test3() {
let mut x = 0;
loop {
+ //~^ ERROR: this loop never actually loops
// never loops
x += 1;
break;
@@ -52,8 +55,10 @@ fn test4() {
fn test5() {
let i = 0;
loop {
+ //~^ ERROR: this loop never actually loops
// never loops
while i == 0 {
+ //~^ ERROR: this loop never actually loops
// never loops
break;
}
@@ -66,6 +71,7 @@ fn test6() {
'outer: loop {
x += 1;
loop {
+ //~^ ERROR: this loop never actually loops
// never loops
if x == 5 {
break;
@@ -102,6 +108,7 @@ fn test8() {
fn test9() {
let x = Some(1);
while let Some(y) = x {
+ //~^ ERROR: this loop never actually loops
// never loops
return;
}
@@ -109,6 +116,7 @@ fn test9() {
fn test10() {
for x in 0..10 {
+ //~^ ERROR: this loop never actually loops
// never loops
match x {
1 => break,
@@ -157,6 +165,7 @@ pub fn test13() {
pub fn test14() {
let mut a = true;
'outer: while a {
+ //~^ ERROR: this loop never actually loops
// never loops
while a {
if a {
@@ -172,6 +181,7 @@ pub fn test14() {
pub fn test15() {
'label: loop {
while false {
+ //~^ ERROR: this loop never actually loops
break 'label;
}
}
@@ -223,6 +233,7 @@ pub fn test18() {
};
// never loops
let _ = loop {
+ //~^ ERROR: this loop never actually loops
let Some(x) = x else {
return;
};
@@ -244,9 +255,12 @@ pub fn test19() {
pub fn test20() {
'a: loop {
+ //~^ ERROR: this loop never actually loops
'b: {
break 'b 'c: {
break 'a;
+ //~^ ERROR: sub-expression diverges
+ //~| NOTE: `-D clippy::diverging-sub-expression` implied by `-D warnings`
};
}
}
@@ -278,6 +292,7 @@ pub fn test23() {
for _ in 0..10 {
'block: {
for _ in 0..20 {
+ //~^ ERROR: this loop never actually loops
break 'block;
}
}
@@ -324,7 +339,6 @@ pub fn test27() {
loop {
'label: {
let x = true;
- // Lints because we cannot prove it's always `true`
if x {
break 'label;
}
@@ -333,6 +347,59 @@ pub fn test27() {
}
}
+// issue 11004
+pub fn test29() {
+ loop {
+ 'label: {
+ if true {
+ break 'label;
+ }
+ return;
+ }
+ }
+}
+
+pub fn test30() {
+ 'a: loop {
+ 'b: {
+ for j in 0..2 {
+ if j == 1 {
+ break 'b;
+ }
+ }
+ break 'a;
+ }
+ }
+}
+
+pub fn test31(b: bool) {
+ 'a: loop {
+ 'b: {
+ 'c: loop {
+ //~^ ERROR: this loop never actually loops
+ if b { break 'c } else { break 'b }
+ }
+ continue 'a;
+ }
+ break 'a;
+ }
+}
+
+pub fn test32() {
+ loop {
+ //~^ ERROR: this loop never actually loops
+ panic!("oh no");
+ }
+ loop {
+ //~^ ERROR: this loop never actually loops
+ unimplemented!("not yet");
+ }
+ loop {
+ // no error
+ todo!("maybe later");
+ }
+}
+
fn main() {
test1();
test2();
diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr
index 0446c09cd..3982f36ce 100644
--- a/src/tools/clippy/tests/ui/never_loop.stderr
+++ b/src/tools/clippy/tests/ui/never_loop.stderr
@@ -2,9 +2,9 @@ error: this loop never actually loops
--> $DIR/never_loop.rs:12:5
|
LL | / loop {
+LL | |
+LL | |
LL | | // clippy::never_loop
-LL | | x += 1;
-LL | | if x == 1 {
... |
LL | | break;
LL | | }
@@ -13,9 +13,10 @@ LL | | }
= note: `#[deny(clippy::never_loop)]` on by default
error: this loop never actually loops
- --> $DIR/never_loop.rs:34:5
+ --> $DIR/never_loop.rs:36:5
|
LL | / loop {
+LL | |
LL | | // never loops
LL | | x += 1;
LL | | break;
@@ -23,55 +24,57 @@ LL | | }
| |_____^
error: this loop never actually loops
- --> $DIR/never_loop.rs:54:5
+ --> $DIR/never_loop.rs:57:5
|
LL | / loop {
+LL | |
LL | | // never loops
LL | | while i == 0 {
-LL | | // never loops
... |
LL | | return;
LL | | }
| |_____^
error: this loop never actually loops
- --> $DIR/never_loop.rs:56:9
+ --> $DIR/never_loop.rs:60:9
|
LL | / while i == 0 {
+LL | |
LL | | // never loops
LL | | break;
LL | | }
| |_________^
error: this loop never actually loops
- --> $DIR/never_loop.rs:68:9
+ --> $DIR/never_loop.rs:73:9
|
LL | / loop {
+LL | |
LL | | // never loops
LL | | if x == 5 {
-LL | | break;
-LL | | }
+... |
LL | | continue 'outer;
LL | | }
| |_________^
error: this loop never actually loops
- --> $DIR/never_loop.rs:104:5
+ --> $DIR/never_loop.rs:110:5
|
LL | / while let Some(y) = x {
+LL | |
LL | | // never loops
LL | | return;
LL | | }
| |_____^
error: this loop never actually loops
- --> $DIR/never_loop.rs:111:5
+ --> $DIR/never_loop.rs:118:5
|
LL | / for x in 0..10 {
+LL | |
LL | | // never loops
LL | | match x {
-LL | | 1 => break,
-LL | | _ => return,
+... |
LL | | }
LL | | }
| |_____^
@@ -82,62 +85,65 @@ LL | if let Some(x) = (0..10).next() {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: this loop never actually loops
- --> $DIR/never_loop.rs:159:5
+ --> $DIR/never_loop.rs:167:5
|
LL | / 'outer: while a {
+LL | |
LL | | // never loops
LL | | while a {
-LL | | if a {
... |
LL | | break 'outer;
LL | | }
| |_____^
error: this loop never actually loops
- --> $DIR/never_loop.rs:174:9
+ --> $DIR/never_loop.rs:183:9
|
LL | / while false {
+LL | |
LL | | break 'label;
LL | | }
| |_________^
error: this loop never actually loops
- --> $DIR/never_loop.rs:225:13
+ --> $DIR/never_loop.rs:235:13
|
LL | let _ = loop {
| _____________^
+LL | |
LL | | let Some(x) = x else {
LL | | return;
-LL | | };
-LL | |
+... |
LL | | break x;
LL | | };
| |_____^
error: this loop never actually loops
- --> $DIR/never_loop.rs:246:5
+ --> $DIR/never_loop.rs:257:5
|
LL | / 'a: loop {
+LL | |
LL | | 'b: {
LL | | break 'b 'c: {
-LL | | break 'a;
-LL | | };
+... |
LL | | }
LL | | }
| |_____^
error: sub-expression diverges
- --> $DIR/never_loop.rs:249:17
+ --> $DIR/never_loop.rs:261:17
|
LL | break 'a;
| ^^^^^^^^
|
= note: `-D clippy::diverging-sub-expression` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]`
error: this loop never actually loops
- --> $DIR/never_loop.rs:280:13
+ --> $DIR/never_loop.rs:294:13
|
LL | / for _ in 0..20 {
+LL | |
LL | | break 'block;
LL | | }
| |_____________^
@@ -148,16 +154,31 @@ LL | if let Some(_) = (0..20).next() {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: this loop never actually loops
- --> $DIR/never_loop.rs:324:5
+ --> $DIR/never_loop.rs:378:13
+ |
+LL | / 'c: loop {
+LL | |
+LL | | if b { break 'c } else { break 'b }
+LL | | }
+ | |_____________^
+
+error: this loop never actually loops
+ --> $DIR/never_loop.rs:389:5
|
LL | / loop {
-LL | | 'label: {
-LL | | let x = true;
-LL | | // Lints because we cannot prove it's always `true`
-... |
-LL | | }
+LL | |
+LL | | panic!("oh no");
+LL | | }
+ | |_____^
+
+error: this loop never actually loops
+ --> $DIR/never_loop.rs:393:5
+ |
+LL | / loop {
+LL | |
+LL | | unimplemented!("not yet");
LL | | }
| |_____^
-error: aborting due to 14 previous errors
+error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self.rs b/src/tools/clippy/tests/ui/new_ret_no_self.rs
index 4eff62b85..b944f531e 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self.rs
+++ b/src/tools/clippy/tests/ui/new_ret_no_self.rs
@@ -48,6 +48,8 @@ impl R for S3 {
impl S3 {
// should trigger the lint
pub fn new(_: String) -> impl R<Item = u32> {
+ //~^ ERROR: methods called `new` usually return `Self`
+ //~| NOTE: `-D clippy::new-ret-no-self` implied by `-D warnings`
S3
}
}
@@ -80,6 +82,7 @@ struct U;
impl U {
// should trigger lint
pub fn new() -> u32 {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!();
}
}
@@ -89,6 +92,7 @@ struct V;
impl V {
// should trigger lint
pub fn new(_: String) -> u32 {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!();
}
}
@@ -125,6 +129,7 @@ struct TupleReturnerBad;
impl TupleReturnerBad {
// should trigger lint
pub fn new() -> (u32, u32) {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!();
}
}
@@ -152,6 +157,7 @@ struct MutPointerReturnerBad;
impl MutPointerReturnerBad {
// should trigger lint
pub fn new() -> *mut V {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!();
}
}
@@ -170,6 +176,7 @@ struct GenericReturnerBad;
impl GenericReturnerBad {
// should trigger lint
pub fn new() -> Option<u32> {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!();
}
}
@@ -223,6 +230,7 @@ mod issue5435 {
pub trait TraitRet {
// should trigger lint as we are in trait definition
fn new() -> String;
+ //~^ ERROR: methods called `new` usually return `Self`
}
pub struct StructRet;
impl TraitRet for StructRet {
@@ -235,6 +243,7 @@ mod issue5435 {
pub trait TraitRet2 {
// should trigger lint
fn new(_: String) -> String;
+ //~^ ERROR: methods called `new` usually return `Self`
}
trait TupleReturnerOk {
@@ -270,6 +279,7 @@ mod issue5435 {
trait TupleReturnerBad {
// should trigger lint
fn new() -> (u32, u32) {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!();
}
}
@@ -297,6 +307,7 @@ mod issue5435 {
trait MutPointerReturnerBad {
// should trigger lint
fn new() -> *mut V {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!();
}
}
@@ -367,6 +378,7 @@ mod issue7344 {
impl<T> RetImplTraitNoSelf<T> {
// should trigger lint
fn new(t: T) -> impl Into<i32> {
+ //~^ ERROR: methods called `new` usually return `Self`
1
}
}
@@ -388,6 +400,7 @@ mod issue7344 {
impl<T> RetImplTraitNoSelf2<T> {
// should trigger lint
fn new(t: T) -> impl Trait2<(), i32> {
+ //~^ ERROR: methods called `new` usually return `Self`
unimplemented!()
}
}
diff --git a/src/tools/clippy/tests/ui/new_ret_no_self.stderr b/src/tools/clippy/tests/ui/new_ret_no_self.stderr
index 2b053b462..8436e101f 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self.stderr
+++ b/src/tools/clippy/tests/ui/new_ret_no_self.stderr
@@ -2,92 +2,104 @@ error: methods called `new` usually return `Self`
--> $DIR/new_ret_no_self.rs:50:5
|
LL | / pub fn new(_: String) -> impl R<Item = u32> {
+LL | |
+LL | |
LL | | S3
LL | | }
| |_____^
|
= note: `-D clippy::new-ret-no-self` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]`
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:82:5
+ --> $DIR/new_ret_no_self.rs:84:5
|
LL | / pub fn new() -> u32 {
+LL | |
LL | | unimplemented!();
LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:91:5
+ --> $DIR/new_ret_no_self.rs:94:5
|
LL | / pub fn new(_: String) -> u32 {
+LL | |
LL | | unimplemented!();
LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:127:5
+ --> $DIR/new_ret_no_self.rs:131:5
|
LL | / pub fn new() -> (u32, u32) {
+LL | |
LL | | unimplemented!();
LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:154:5
+ --> $DIR/new_ret_no_self.rs:159:5
|
LL | / pub fn new() -> *mut V {
+LL | |
LL | | unimplemented!();
LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:172:5
+ --> $DIR/new_ret_no_self.rs:178:5
|
LL | / pub fn new() -> Option<u32> {
+LL | |
LL | | unimplemented!();
LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:225:9
+ --> $DIR/new_ret_no_self.rs:232:9
|
LL | fn new() -> String;
| ^^^^^^^^^^^^^^^^^^^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:237:9
+ --> $DIR/new_ret_no_self.rs:245:9
|
LL | fn new(_: String) -> String;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:272:9
+ --> $DIR/new_ret_no_self.rs:281:9
|
LL | / fn new() -> (u32, u32) {
+LL | |
LL | | unimplemented!();
LL | | }
| |_________^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:299:9
+ --> $DIR/new_ret_no_self.rs:309:9
|
LL | / fn new() -> *mut V {
+LL | |
LL | | unimplemented!();
LL | | }
| |_________^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:369:9
+ --> $DIR/new_ret_no_self.rs:380:9
|
LL | / fn new(t: T) -> impl Into<i32> {
+LL | |
LL | | 1
LL | | }
| |_________^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:390:9
+ --> $DIR/new_ret_no_self.rs:402:9
|
LL | / fn new(t: T) -> impl Trait2<(), i32> {
+LL | |
LL | | unimplemented!()
LL | | }
| |_________^
diff --git a/src/tools/clippy/tests/ui/new_without_default.fixed b/src/tools/clippy/tests/ui/new_without_default.fixed
new file mode 100644
index 000000000..1c7ba1a48
--- /dev/null
+++ b/src/tools/clippy/tests/ui/new_without_default.fixed
@@ -0,0 +1,309 @@
+#![allow(
+ dead_code,
+ clippy::missing_safety_doc,
+ clippy::extra_unused_lifetimes,
+ clippy::extra_unused_type_parameters
+)]
+#![warn(clippy::new_without_default)]
+
+pub struct Foo;
+
+impl Default for Foo {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl Foo {
+ pub fn new() -> Foo {
+ //~^ ERROR: you should consider adding a `Default` implementation for `Foo`
+ //~| NOTE: `-D clippy::new-without-default` implied by `-D warnings`
+ Foo
+ }
+}
+
+pub struct Bar;
+
+impl Default for Bar {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl Bar {
+ pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `Bar`
+ Bar
+ }
+}
+
+pub struct Ok;
+
+impl Ok {
+ pub fn new() -> Self {
+ Ok
+ }
+}
+
+impl Default for Ok {
+ fn default() -> Self {
+ Ok
+ }
+}
+
+pub struct Params;
+
+impl Params {
+ pub fn new(_: u32) -> Self {
+ Params
+ }
+}
+
+pub struct GenericsOk<T> {
+ bar: T,
+}
+
+impl<U> Default for GenericsOk<U> {
+ fn default() -> Self {
+ unimplemented!();
+ }
+}
+
+impl<'c, V> GenericsOk<V> {
+ pub fn new() -> GenericsOk<V> {
+ unimplemented!()
+ }
+}
+
+pub struct LtOk<'a> {
+ foo: &'a bool,
+}
+
+impl<'b> Default for LtOk<'b> {
+ fn default() -> Self {
+ unimplemented!();
+ }
+}
+
+impl<'c> LtOk<'c> {
+ pub fn new() -> LtOk<'c> {
+ unimplemented!()
+ }
+}
+
+pub struct LtKo<'a> {
+ foo: &'a bool,
+}
+
+impl<'c> Default for LtKo<'c> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<'c> LtKo<'c> {
+ pub fn new() -> LtKo<'c> {
+ //~^ ERROR: you should consider adding a `Default` implementation for `LtKo<'c>`
+ unimplemented!()
+ }
+}
+
+struct Private;
+
+impl Private {
+ fn new() -> Private {
+ unimplemented!()
+ } // We don't lint private items
+}
+
+struct PrivateStruct;
+
+impl PrivateStruct {
+ pub fn new() -> PrivateStruct {
+ unimplemented!()
+ } // We don't lint public items on private structs
+}
+
+pub struct PrivateItem;
+
+impl PrivateItem {
+ fn new() -> PrivateItem {
+ unimplemented!()
+ } // We don't lint private items on public structs
+}
+
+struct Const;
+
+impl Const {
+ pub const fn new() -> Const {
+ Const
+ } // const fns can't be implemented via Default
+}
+
+pub struct IgnoreGenericNew;
+
+impl IgnoreGenericNew {
+ pub fn new<T>() -> Self {
+ IgnoreGenericNew
+ } // the derived Default does not make sense here as the result depends on T
+}
+
+pub trait TraitWithNew: Sized {
+ fn new() -> Self {
+ panic!()
+ }
+}
+
+pub struct IgnoreUnsafeNew;
+
+impl IgnoreUnsafeNew {
+ pub unsafe fn new() -> Self {
+ IgnoreUnsafeNew
+ }
+}
+
+#[derive(Default)]
+pub struct OptionRefWrapper<'a, T>(Option<&'a T>);
+
+impl<'a, T> OptionRefWrapper<'a, T> {
+ pub fn new() -> Self {
+ OptionRefWrapper(None)
+ }
+}
+
+pub struct Allow(Foo);
+
+impl Allow {
+ #[allow(clippy::new_without_default)]
+ pub fn new() -> Self {
+ unimplemented!()
+ }
+}
+
+pub struct AllowDerive;
+
+impl AllowDerive {
+ #[allow(clippy::new_without_default)]
+ pub fn new() -> Self {
+ unimplemented!()
+ }
+}
+
+pub struct NewNotEqualToDerive {
+ foo: i32,
+}
+
+impl Default for NewNotEqualToDerive {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl NewNotEqualToDerive {
+ // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving.
+ pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `NewNotEqualToDe
+ NewNotEqualToDerive { foo: 1 }
+ }
+}
+
+// see #6933
+pub struct FooGenerics<T>(std::marker::PhantomData<T>);
+impl<T> Default for FooGenerics<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<T> FooGenerics<T> {
+ pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `FooGenerics<T>`
+ Self(Default::default())
+ }
+}
+
+pub struct BarGenerics<T>(std::marker::PhantomData<T>);
+impl<T: Copy> Default for BarGenerics<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<T: Copy> BarGenerics<T> {
+ pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `BarGenerics<T>`
+ Self(Default::default())
+ }
+}
+
+pub mod issue7220 {
+ pub struct Foo<T> {
+ _bar: *mut T,
+ }
+
+ impl<T> Default for Foo<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+ }
+
+ impl<T> Foo<T> {
+ pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `Foo<T>`
+ todo!()
+ }
+ }
+}
+
+// see issue #8152
+// This should not create any lints
+pub struct DocHidden;
+impl DocHidden {
+ #[doc(hidden)]
+ pub fn new() -> Self {
+ DocHidden
+ }
+}
+
+fn main() {}
+
+pub struct IgnoreConstGenericNew(usize);
+impl IgnoreConstGenericNew {
+ pub fn new<const N: usize>() -> Self {
+ Self(N)
+ }
+}
+
+pub struct IgnoreLifetimeNew;
+impl IgnoreLifetimeNew {
+ pub fn new<'a>() -> Self {
+ Self
+ }
+}
+
+// From issue #11267
+
+pub struct MyStruct<K, V>
+where
+ K: std::hash::Hash + Eq + PartialEq,
+{
+ _kv: Option<(K, V)>,
+}
+
+impl<K, V> Default for MyStruct<K, V>
+where
+ K: std::hash::Hash + Eq + PartialEq,
+ {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl<K, V> MyStruct<K, V>
+where
+ K: std::hash::Hash + Eq + PartialEq,
+{
+ pub fn new() -> Self {
+ Self { _kv: None }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/new_without_default.rs b/src/tools/clippy/tests/ui/new_without_default.rs
index 7803418cb..964aa0f63 100644
--- a/src/tools/clippy/tests/ui/new_without_default.rs
+++ b/src/tools/clippy/tests/ui/new_without_default.rs
@@ -10,6 +10,8 @@ pub struct Foo;
impl Foo {
pub fn new() -> Foo {
+ //~^ ERROR: you should consider adding a `Default` implementation for `Foo`
+ //~| NOTE: `-D clippy::new-without-default` implied by `-D warnings`
Foo
}
}
@@ -18,6 +20,7 @@ pub struct Bar;
impl Bar {
pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `Bar`
Bar
}
}
@@ -82,9 +85,9 @@ pub struct LtKo<'a> {
impl<'c> LtKo<'c> {
pub fn new() -> LtKo<'c> {
+ //~^ ERROR: you should consider adding a `Default` implementation for `LtKo<'c>`
unimplemented!()
}
- // FIXME: that suggestion is missing lifetimes
}
struct Private;
@@ -175,6 +178,7 @@ pub struct NewNotEqualToDerive {
impl NewNotEqualToDerive {
// This `new` implementation is not equal to a derived `Default`, so do not suggest deriving.
pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `NewNotEqualToDe
NewNotEqualToDerive { foo: 1 }
}
}
@@ -183,6 +187,7 @@ impl NewNotEqualToDerive {
pub struct FooGenerics<T>(std::marker::PhantomData<T>);
impl<T> FooGenerics<T> {
pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `FooGenerics<T>`
Self(Default::default())
}
}
@@ -190,6 +195,7 @@ impl<T> FooGenerics<T> {
pub struct BarGenerics<T>(std::marker::PhantomData<T>);
impl<T: Copy> BarGenerics<T> {
pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `BarGenerics<T>`
Self(Default::default())
}
}
@@ -201,6 +207,7 @@ pub mod issue7220 {
impl<T> Foo<T> {
pub fn new() -> Self {
+ //~^ ERROR: you should consider adding a `Default` implementation for `Foo<T>`
todo!()
}
}
@@ -231,3 +238,21 @@ impl IgnoreLifetimeNew {
Self
}
}
+
+// From issue #11267
+
+pub struct MyStruct<K, V>
+where
+ K: std::hash::Hash + Eq + PartialEq,
+{
+ _kv: Option<(K, V)>,
+}
+
+impl<K, V> MyStruct<K, V>
+where
+ K: std::hash::Hash + Eq + PartialEq,
+{
+ pub fn new() -> Self {
+ Self { _kv: None }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr
index 583dd327d..acba5b0d7 100644
--- a/src/tools/clippy/tests/ui/new_without_default.stderr
+++ b/src/tools/clippy/tests/ui/new_without_default.stderr
@@ -2,11 +2,14 @@ error: you should consider adding a `Default` implementation for `Foo`
--> $DIR/new_without_default.rs:12:5
|
LL | / pub fn new() -> Foo {
+LL | |
+LL | |
LL | | Foo
LL | | }
| |_____^
|
= note: `-D clippy::new-without-default` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::new_without_default)]`
help: try adding this
|
LL + impl Default for Foo {
@@ -17,9 +20,10 @@ LL + }
|
error: you should consider adding a `Default` implementation for `Bar`
- --> $DIR/new_without_default.rs:20:5
+ --> $DIR/new_without_default.rs:22:5
|
LL | / pub fn new() -> Self {
+LL | |
LL | | Bar
LL | | }
| |_____^
@@ -34,9 +38,10 @@ LL + }
|
error: you should consider adding a `Default` implementation for `LtKo<'c>`
- --> $DIR/new_without_default.rs:84:5
+ --> $DIR/new_without_default.rs:87:5
|
LL | / pub fn new() -> LtKo<'c> {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -51,9 +56,10 @@ LL + }
|
error: you should consider adding a `Default` implementation for `NewNotEqualToDerive`
- --> $DIR/new_without_default.rs:177:5
+ --> $DIR/new_without_default.rs:180:5
|
LL | / pub fn new() -> Self {
+LL | |
LL | | NewNotEqualToDerive { foo: 1 }
LL | | }
| |_____^
@@ -68,9 +74,10 @@ LL + }
|
error: you should consider adding a `Default` implementation for `FooGenerics<T>`
- --> $DIR/new_without_default.rs:185:5
+ --> $DIR/new_without_default.rs:189:5
|
LL | / pub fn new() -> Self {
+LL | |
LL | | Self(Default::default())
LL | | }
| |_____^
@@ -85,9 +92,10 @@ LL + }
|
error: you should consider adding a `Default` implementation for `BarGenerics<T>`
- --> $DIR/new_without_default.rs:192:5
+ --> $DIR/new_without_default.rs:197:5
|
LL | / pub fn new() -> Self {
+LL | |
LL | | Self(Default::default())
LL | | }
| |_____^
@@ -102,9 +110,10 @@ LL + }
|
error: you should consider adding a `Default` implementation for `Foo<T>`
- --> $DIR/new_without_default.rs:203:9
+ --> $DIR/new_without_default.rs:209:9
|
LL | / pub fn new() -> Self {
+LL | |
LL | | todo!()
LL | | }
| |_________^
@@ -120,5 +129,25 @@ LL +
LL ~ impl<T> Foo<T> {
|
-error: aborting due to 7 previous errors
+error: you should consider adding a `Default` implementation for `MyStruct<K, V>`
+ --> $DIR/new_without_default.rs:255:5
+ |
+LL | / pub fn new() -> Self {
+LL | | Self { _kv: None }
+LL | | }
+ | |_____^
+ |
+help: try adding this
+ |
+LL + impl<K, V> Default for MyStruct<K, V>
+LL + where
+LL + K: std::hash::Hash + Eq + PartialEq,
+LL + {
+LL + fn default() -> Self {
+LL + Self::new()
+LL + }
+LL + }
+ |
+
+error: aborting due to 8 previous errors
diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs
index 6a726941b..c52f43891 100644
--- a/src/tools/clippy/tests/ui/no_effect.rs
+++ b/src/tools/clippy/tests/ui/no_effect.rs
@@ -96,36 +96,67 @@ fn main() {
let s2 = get_struct();
0;
+ //~^ ERROR: statement with no effect
+ //~| NOTE: `-D clippy::no-effect` implied by `-D warnings`
s2;
+ //~^ ERROR: statement with no effect
Unit;
+ //~^ ERROR: statement with no effect
Tuple(0);
+ //~^ ERROR: statement with no effect
Struct { field: 0 };
+ //~^ ERROR: statement with no effect
Struct { ..s };
+ //~^ ERROR: statement with no effect
Union { a: 0 };
+ //~^ ERROR: statement with no effect
Enum::Tuple(0);
+ //~^ ERROR: statement with no effect
Enum::Struct { field: 0 };
+ //~^ ERROR: statement with no effect
5 + 6;
+ //~^ ERROR: statement with no effect
*&42;
+ //~^ ERROR: statement with no effect
&6;
+ //~^ ERROR: statement with no effect
(5, 6, 7);
+ //~^ ERROR: statement with no effect
..;
+ //~^ ERROR: statement with no effect
5..;
+ //~^ ERROR: statement with no effect
..5;
+ //~^ ERROR: statement with no effect
5..6;
+ //~^ ERROR: statement with no effect
5..=6;
+ //~^ ERROR: statement with no effect
[42, 55];
+ //~^ ERROR: statement with no effect
[42, 55][1];
+ //~^ ERROR: statement with no effect
(42, 55).1;
+ //~^ ERROR: statement with no effect
[42; 55];
+ //~^ ERROR: statement with no effect
[42; 55][13];
+ //~^ ERROR: statement with no effect
let mut x = 0;
|| x += 5;
+ //~^ ERROR: statement with no effect
let s: String = "foo".into();
FooString { s: s };
+ //~^ ERROR: statement with no effect
let _unused = 1;
+ //~^ ERROR: binding to `_` prefixed variable with no side-effect
+ //~| NOTE: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`
let _penguin = || println!("Some helpful closure");
+ //~^ ERROR: binding to `_` prefixed variable with no side-effect
let _duck = Struct { field: 0 };
+ //~^ ERROR: binding to `_` prefixed variable with no side-effect
let _cat = [2, 4, 6, 8][2];
+ //~^ ERROR: binding to `_` prefixed variable with no side-effect
#[allow(clippy::no_effect)]
0;
diff --git a/src/tools/clippy/tests/ui/no_effect.stderr b/src/tools/clippy/tests/ui/no_effect.stderr
index 64edfc325..feba35697 100644
--- a/src/tools/clippy/tests/ui/no_effect.stderr
+++ b/src/tools/clippy/tests/ui/no_effect.stderr
@@ -5,173 +5,175 @@ LL | 0;
| ^^
|
= note: `-D clippy::no-effect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::no_effect)]`
error: statement with no effect
- --> $DIR/no_effect.rs:99:5
+ --> $DIR/no_effect.rs:101:5
|
LL | s2;
| ^^^
error: statement with no effect
- --> $DIR/no_effect.rs:100:5
+ --> $DIR/no_effect.rs:103:5
|
LL | Unit;
| ^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:101:5
+ --> $DIR/no_effect.rs:105:5
|
LL | Tuple(0);
| ^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:102:5
+ --> $DIR/no_effect.rs:107:5
|
LL | Struct { field: 0 };
| ^^^^^^^^^^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:103:5
+ --> $DIR/no_effect.rs:109:5
|
LL | Struct { ..s };
| ^^^^^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:104:5
+ --> $DIR/no_effect.rs:111:5
|
LL | Union { a: 0 };
| ^^^^^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:105:5
+ --> $DIR/no_effect.rs:113:5
|
LL | Enum::Tuple(0);
| ^^^^^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:106:5
+ --> $DIR/no_effect.rs:115:5
|
LL | Enum::Struct { field: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:107:5
+ --> $DIR/no_effect.rs:117:5
|
LL | 5 + 6;
| ^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:108:5
+ --> $DIR/no_effect.rs:119:5
|
LL | *&42;
| ^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:109:5
+ --> $DIR/no_effect.rs:121:5
|
LL | &6;
| ^^^
error: statement with no effect
- --> $DIR/no_effect.rs:110:5
+ --> $DIR/no_effect.rs:123:5
|
LL | (5, 6, 7);
| ^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:111:5
+ --> $DIR/no_effect.rs:125:5
|
LL | ..;
| ^^^
error: statement with no effect
- --> $DIR/no_effect.rs:112:5
+ --> $DIR/no_effect.rs:127:5
|
LL | 5..;
| ^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:113:5
+ --> $DIR/no_effect.rs:129:5
|
LL | ..5;
| ^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:114:5
+ --> $DIR/no_effect.rs:131:5
|
LL | 5..6;
| ^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:115:5
+ --> $DIR/no_effect.rs:133:5
|
LL | 5..=6;
| ^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:116:5
+ --> $DIR/no_effect.rs:135:5
|
LL | [42, 55];
| ^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:117:5
+ --> $DIR/no_effect.rs:137:5
|
LL | [42, 55][1];
| ^^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:118:5
+ --> $DIR/no_effect.rs:139:5
|
LL | (42, 55).1;
| ^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:119:5
+ --> $DIR/no_effect.rs:141:5
|
LL | [42; 55];
| ^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:120:5
+ --> $DIR/no_effect.rs:143:5
|
LL | [42; 55][13];
| ^^^^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:122:5
+ --> $DIR/no_effect.rs:146:5
|
LL | || x += 5;
| ^^^^^^^^^^
error: statement with no effect
- --> $DIR/no_effect.rs:124:5
+ --> $DIR/no_effect.rs:149:5
|
LL | FooString { s: s };
| ^^^^^^^^^^^^^^^^^^^
error: binding to `_` prefixed variable with no side-effect
- --> $DIR/no_effect.rs:125:5
+ --> $DIR/no_effect.rs:151:5
|
LL | let _unused = 1;
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]`
error: binding to `_` prefixed variable with no side-effect
- --> $DIR/no_effect.rs:126:5
+ --> $DIR/no_effect.rs:154:5
|
LL | let _penguin = || println!("Some helpful closure");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: binding to `_` prefixed variable with no side-effect
- --> $DIR/no_effect.rs:127:5
+ --> $DIR/no_effect.rs:156:5
|
LL | let _duck = Struct { field: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: binding to `_` prefixed variable with no side-effect
- --> $DIR/no_effect.rs:128:5
+ --> $DIR/no_effect.rs:158:5
|
LL | let _cat = [2, 4, 6, 8][2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/no_effect_replace.rs b/src/tools/clippy/tests/ui/no_effect_replace.rs
index ad17d53f7..e4fd5caae 100644
--- a/src/tools/clippy/tests/ui/no_effect_replace.rs
+++ b/src/tools/clippy/tests/ui/no_effect_replace.rs
@@ -2,21 +2,30 @@
fn main() {
let _ = "12345".replace('1', "1");
+ //~^ ERROR: replacing text with itself
+ //~| NOTE: `-D clippy::no-effect-replace` implied by `-D warnings`
let _ = "12345".replace("12", "12");
+ //~^ ERROR: replacing text with itself
let _ = String::new().replace("12", "12");
+ //~^ ERROR: replacing text with itself
let _ = "12345".replacen('1', "1", 1);
+ //~^ ERROR: replacing text with itself
let _ = "12345".replacen("12", "12", 1);
+ //~^ ERROR: replacing text with itself
let _ = String::new().replacen("12", "12", 1);
+ //~^ ERROR: replacing text with itself
let _ = "12345".replace("12", "22");
let _ = "12345".replacen("12", "22", 1);
let mut x = X::default();
let _ = "hello".replace(&x.f(), &x.f());
+ //~^ ERROR: replacing text with itself
let _ = "hello".replace(&x.f(), &x.ff());
let _ = "hello".replace(&y(), &y());
+ //~^ ERROR: replacing text with itself
let _ = "hello".replace(&y(), &z());
let _ = Replaceme.replace("a", "a");
diff --git a/src/tools/clippy/tests/ui/no_effect_replace.stderr b/src/tools/clippy/tests/ui/no_effect_replace.stderr
index 53a28aa73..e1162f04f 100644
--- a/src/tools/clippy/tests/ui/no_effect_replace.stderr
+++ b/src/tools/clippy/tests/ui/no_effect_replace.stderr
@@ -5,45 +5,46 @@ LL | let _ = "12345".replace('1', "1");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::no-effect-replace` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::no_effect_replace)]`
error: replacing text with itself
- --> $DIR/no_effect_replace.rs:5:13
+ --> $DIR/no_effect_replace.rs:7:13
|
LL | let _ = "12345".replace("12", "12");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: replacing text with itself
- --> $DIR/no_effect_replace.rs:6:13
+ --> $DIR/no_effect_replace.rs:9:13
|
LL | let _ = String::new().replace("12", "12");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: replacing text with itself
- --> $DIR/no_effect_replace.rs:8:13
+ --> $DIR/no_effect_replace.rs:12:13
|
LL | let _ = "12345".replacen('1', "1", 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: replacing text with itself
- --> $DIR/no_effect_replace.rs:9:13
+ --> $DIR/no_effect_replace.rs:14:13
|
LL | let _ = "12345".replacen("12", "12", 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: replacing text with itself
- --> $DIR/no_effect_replace.rs:10:13
+ --> $DIR/no_effect_replace.rs:16:13
|
LL | let _ = String::new().replacen("12", "12", 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: replacing text with itself
- --> $DIR/no_effect_replace.rs:16:13
+ --> $DIR/no_effect_replace.rs:23:13
|
LL | let _ = "hello".replace(&x.f(), &x.f());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: replacing text with itself
- --> $DIR/no_effect_replace.rs:19:13
+ --> $DIR/no_effect_replace.rs:27:13
|
LL | let _ = "hello".replace(&y(), &y());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/no_effect_return.rs b/src/tools/clippy/tests/ui/no_effect_return.rs
index 231dd063a..e46c0d735 100644
--- a/src/tools/clippy/tests/ui/no_effect_return.rs
+++ b/src/tools/clippy/tests/ui/no_effect_return.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![allow(clippy::unused_unit, dead_code, unused)]
#![no_main]
@@ -6,6 +7,8 @@ use std::ops::ControlFlow;
fn a() -> u32 {
{
0u32;
+ //~^ ERROR: statement with no effect
+ //~| NOTE: `-D clippy::no-effect` implied by `-D warnings`
}
0
}
@@ -13,6 +16,7 @@ fn a() -> u32 {
async fn b() -> u32 {
{
0u32;
+ //~^ ERROR: statement with no effect
}
0
}
@@ -21,6 +25,7 @@ type C = i32;
async fn c() -> C {
{
0i32 as C;
+ //~^ ERROR: statement with no effect
}
0
}
@@ -29,6 +34,7 @@ fn d() -> u128 {
{
// not last stmt
0u128;
+ //~^ ERROR: statement with no effect
println!("lol");
}
0
@@ -38,6 +44,7 @@ fn e() -> u32 {
{
// mismatched types
0u16;
+ //~^ ERROR: statement with no effect
}
0
}
@@ -45,6 +52,7 @@ fn e() -> u32 {
fn f() -> [u16; 1] {
{
[1u16];
+ //~^ ERROR: statement with no effect
}
[1]
}
@@ -52,6 +60,7 @@ fn f() -> [u16; 1] {
fn g() -> ControlFlow<()> {
{
ControlFlow::Break::<()>(());
+ //~^ ERROR: statement with no effect
}
ControlFlow::Continue(())
}
@@ -67,7 +76,9 @@ fn h() -> Vec<u16> {
fn i() -> () {
{
+ // does not suggest on function with explicit unit return type
();
+ //~^ ERROR: statement with no effect
}
()
}
@@ -76,6 +87,7 @@ fn j() {
{
// does not suggest on function without explicit return type
();
+ //~^ ERROR: statement with no effect
}
()
}
diff --git a/src/tools/clippy/tests/ui/no_effect_return.stderr b/src/tools/clippy/tests/ui/no_effect_return.stderr
index 779900e18..aed079f09 100644
--- a/src/tools/clippy/tests/ui/no_effect_return.stderr
+++ b/src/tools/clippy/tests/ui/no_effect_return.stderr
@@ -1,5 +1,5 @@
error: statement with no effect
- --> $DIR/no_effect_return.rs:8:9
+ --> $DIR/no_effect_return.rs:9:9
|
LL | 0u32;
| -^^^^
@@ -7,9 +7,10 @@ LL | 0u32;
| help: did you mean to return it?: `return`
|
= note: `-D clippy::no-effect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::no_effect)]`
error: statement with no effect
- --> $DIR/no_effect_return.rs:15:9
+ --> $DIR/no_effect_return.rs:18:9
|
LL | 0u32;
| -^^^^
@@ -17,7 +18,7 @@ LL | 0u32;
| help: did you mean to return it?: `return`
error: statement with no effect
- --> $DIR/no_effect_return.rs:23:9
+ --> $DIR/no_effect_return.rs:27:9
|
LL | 0i32 as C;
| -^^^^^^^^^
@@ -25,19 +26,19 @@ LL | 0i32 as C;
| help: did you mean to return it?: `return`
error: statement with no effect
- --> $DIR/no_effect_return.rs:31:9
+ --> $DIR/no_effect_return.rs:36:9
|
LL | 0u128;
| ^^^^^^
error: statement with no effect
- --> $DIR/no_effect_return.rs:40:9
+ --> $DIR/no_effect_return.rs:46:9
|
LL | 0u16;
| ^^^^^
error: statement with no effect
- --> $DIR/no_effect_return.rs:47:9
+ --> $DIR/no_effect_return.rs:54:9
|
LL | [1u16];
| -^^^^^^
@@ -45,7 +46,7 @@ LL | [1u16];
| help: did you mean to return it?: `return`
error: statement with no effect
- --> $DIR/no_effect_return.rs:54:9
+ --> $DIR/no_effect_return.rs:62:9
|
LL | ControlFlow::Break::<()>(());
| -^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -53,15 +54,13 @@ LL | ControlFlow::Break::<()>(());
| help: did you mean to return it?: `return`
error: statement with no effect
- --> $DIR/no_effect_return.rs:70:9
+ --> $DIR/no_effect_return.rs:80:9
|
LL | ();
- | -^^
- | |
- | help: did you mean to return it?: `return`
+ | ^^^
error: statement with no effect
- --> $DIR/no_effect_return.rs:78:9
+ --> $DIR/no_effect_return.rs:89:9
|
LL | ();
| ^^^
diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs
index 818119f7b..8c1ea81d2 100644
--- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs
+++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs
@@ -1,24 +1,31 @@
+//@no-rustfix: overlapping suggestions
#![allow(unused)]
#![warn(clippy::no_mangle_with_rust_abi)]
#[no_mangle]
fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+//~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
#[no_mangle]
pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
/// # Safety
/// This function shouldn't be called unless the horsemen are ready
#[no_mangle]
pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
/// # Safety
/// This function shouldn't be called unless the horsemen are ready
#[no_mangle]
unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
#[no_mangle]
fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
+ //~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
arg_one: u32,
arg_two: usize,
) -> u32 {
diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr
index da5d31d8f..62d53c839 100644
--- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr
+++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr
@@ -1,10 +1,11 @@
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
- --> $DIR/no_mangle_with_rust_abi.rs:5:1
+ --> $DIR/no_mangle_with_rust_abi.rs:6:1
|
LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::no_mangle_with_rust_abi)]`
help: set an ABI
|
LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
@@ -15,7 +16,7 @@ LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
| +++++++++++++
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
- --> $DIR/no_mangle_with_rust_abi.rs:8:1
+ --> $DIR/no_mangle_with_rust_abi.rs:11:1
|
LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,7 +31,7 @@ LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
| +++++++++++++
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
- --> $DIR/no_mangle_with_rust_abi.rs:13:1
+ --> $DIR/no_mangle_with_rust_abi.rs:17:1
|
LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize)
| +++++++++++++
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
- --> $DIR/no_mangle_with_rust_abi.rs:18:1
+ --> $DIR/no_mangle_with_rust_abi.rs:23:1
|
LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,9 +61,10 @@ LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
| +++++++++++++
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
- --> $DIR/no_mangle_with_rust_abi.rs:21:1
+ --> $DIR/no_mangle_with_rust_abi.rs:27:1
|
LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
+LL | |
LL | | arg_one: u32,
LL | | arg_two: usize,
LL | | ) -> u32 {
diff --git a/src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.fixed b/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
index ac482dcda..165702b30 100644
--- a/src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.fixed
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::clone_on_copy, unused)]
#![no_main]
diff --git a/src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.rs b/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
index 00775874f..3b07dd5ce 100644
--- a/src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.rs
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::clone_on_copy, unused)]
#![no_main]
diff --git a/src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.stderr b/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
index 7bcba8ba4..44196751b 100644
--- a/src/tools/clippy/tests/ui/incorrect_clone_impl_on_copy_type.stderr
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
@@ -1,5 +1,5 @@
-error: incorrect implementation of `clone` on a `Copy` type
- --> $DIR/incorrect_clone_impl_on_copy_type.rs:10:29
+error: non-canonical implementation of `clone` on a `Copy` type
+ --> $DIR/non_canonical_clone_impl.rs:9:29
|
LL | fn clone(&self) -> Self {
| _____________________________^
@@ -7,10 +7,11 @@ LL | | Self(self.0)
LL | | }
| |_____^ help: change this to: `{ *self }`
|
- = note: `#[deny(clippy::incorrect_clone_impl_on_copy_type)]` on by default
+ = note: `-D clippy::non-canonical-clone-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]`
-error: incorrect implementation of `clone_from` on a `Copy` type
- --> $DIR/incorrect_clone_impl_on_copy_type.rs:14:5
+error: unnecessary implementation of `clone_from` on a `Copy` type
+ --> $DIR/non_canonical_clone_impl.rs:13:5
|
LL | / fn clone_from(&mut self, source: &Self) {
LL | | source.clone();
@@ -18,8 +19,8 @@ LL | | *self = source.clone();
LL | | }
| |_____^ help: remove it
-error: incorrect implementation of `clone` on a `Copy` type
- --> $DIR/incorrect_clone_impl_on_copy_type.rs:81:29
+error: non-canonical implementation of `clone` on a `Copy` type
+ --> $DIR/non_canonical_clone_impl.rs:80:29
|
LL | fn clone(&self) -> Self {
| _____________________________^
@@ -27,8 +28,8 @@ LL | | Self(self.0)
LL | | }
| |_____^ help: change this to: `{ *self }`
-error: incorrect implementation of `clone_from` on a `Copy` type
- --> $DIR/incorrect_clone_impl_on_copy_type.rs:85:5
+error: unnecessary implementation of `clone_from` on a `Copy` type
+ --> $DIR/non_canonical_clone_impl.rs:84:5
|
LL | / fn clone_from(&mut self, source: &Self) {
LL | | source.clone();
diff --git a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.fixed b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed
index 2f51bf274..db55cc094 100644
--- a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.fixed
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![no_main]
use std::cmp::Ordering;
diff --git a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.rs b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs
index 47127bdae..52f4b85b9 100644
--- a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.rs
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![no_main]
use std::cmp::Ordering;
diff --git a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.stderr b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr
index 66048fc90..05cc717b9 100644
--- a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type.stderr
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr
@@ -1,5 +1,5 @@
-error: incorrect implementation of `partial_cmp` on an `Ord` type
- --> $DIR/incorrect_partial_ord_impl_on_ord_type.rs:17:1
+error: non-canonical implementation of `partial_cmp` on an `Ord` type
+ --> $DIR/non_canonical_partial_ord_impl.rs:16:1
|
LL | / impl PartialOrd for A {
LL | | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
@@ -10,10 +10,11 @@ LL | || }
LL | | }
| |__^
|
- = note: `#[deny(clippy::incorrect_partial_ord_impl_on_ord_type)]` on by default
+ = note: `-D clippy::non-canonical-partial-ord-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_canonical_partial_ord_impl)]`
-error: incorrect implementation of `partial_cmp` on an `Ord` type
- --> $DIR/incorrect_partial_ord_impl_on_ord_type.rs:51:1
+error: non-canonical implementation of `partial_cmp` on an `Ord` type
+ --> $DIR/non_canonical_partial_ord_impl.rs:50:1
|
LL | / impl PartialOrd for C {
LL | | fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
diff --git a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type_fully_qual.rs b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs
index 3a3b84f93..2f8d5cf30 100644
--- a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type_fully_qual.rs
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl_fully_qual.rs
@@ -2,7 +2,7 @@
// is not in scope.
#![no_main]
#![no_implicit_prelude]
-
+//@no-rustfix
extern crate std;
use std::cmp::{self, Eq, Ordering, PartialEq, PartialOrd};
diff --git a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type_fully_qual.stderr b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr
index f4374c281..4978d7a87 100644
--- a/src/tools/clippy/tests/ui/incorrect_partial_ord_impl_on_ord_type_fully_qual.stderr
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr
@@ -1,5 +1,5 @@
-error: incorrect implementation of `partial_cmp` on an `Ord` type
- --> $DIR/incorrect_partial_ord_impl_on_ord_type_fully_qual.rs:23:1
+error: non-canonical implementation of `partial_cmp` on an `Ord` type
+ --> $DIR/non_canonical_partial_ord_impl_fully_qual.rs:23:1
|
LL | / impl PartialOrd for A {
LL | | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
@@ -12,10 +12,11 @@ LL | || }
LL | | }
| |__^
|
- = note: `#[deny(clippy::incorrect_partial_ord_impl_on_ord_type)]` on by default
+ = note: `-D clippy::non-canonical-partial-ord-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_canonical_partial_ord_impl)]`
-error: incorrect implementation of `partial_cmp` on an `Ord` type
- --> $DIR/incorrect_partial_ord_impl_on_ord_type_fully_qual.rs:46:1
+error: non-canonical implementation of `partial_cmp` on an `Ord` type
+ --> $DIR/non_canonical_partial_ord_impl_fully_qual.rs:46:1
|
LL | / impl PartialOrd for B {
LL | | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
diff --git a/src/tools/clippy/tests/ui/non_expressive_names.stderr b/src/tools/clippy/tests/ui/non_expressive_names.stderr
index b62748d49..1b78124a9 100644
--- a/src/tools/clippy/tests/ui/non_expressive_names.stderr
+++ b/src/tools/clippy/tests/ui/non_expressive_names.stderr
@@ -5,6 +5,7 @@ LL | let _1 = 1;
| ^^
|
= note: `-D clippy::just-underscores-and-digits` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::just_underscores_and_digits)]`
error: consider choosing a more descriptive name
--> $DIR/non_expressive_names.rs:29:9
diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg.fixed b/src/tools/clippy/tests/ui/non_minimal_cfg.fixed
index 430caafb3..2fcecab45 100644
--- a/src/tools/clippy/tests/ui/non_minimal_cfg.fixed
+++ b/src/tools/clippy/tests/ui/non_minimal_cfg.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#[cfg(windows)]
diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg.rs b/src/tools/clippy/tests/ui/non_minimal_cfg.rs
index a38ce1c21..e3ce11b73 100644
--- a/src/tools/clippy/tests/ui/non_minimal_cfg.rs
+++ b/src/tools/clippy/tests/ui/non_minimal_cfg.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#[cfg(all(windows))]
diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg.stderr b/src/tools/clippy/tests/ui/non_minimal_cfg.stderr
index cdfd728aa..c33c35ed8 100644
--- a/src/tools/clippy/tests/ui/non_minimal_cfg.stderr
+++ b/src/tools/clippy/tests/ui/non_minimal_cfg.stderr
@@ -1,25 +1,26 @@
error: unneeded sub `cfg` when there is only one condition
- --> $DIR/non_minimal_cfg.rs:5:7
+ --> $DIR/non_minimal_cfg.rs:3:7
|
LL | #[cfg(all(windows))]
| ^^^^^^^^^^^^ help: try: `windows`
|
= note: `-D clippy::non-minimal-cfg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_minimal_cfg)]`
error: unneeded sub `cfg` when there is only one condition
- --> $DIR/non_minimal_cfg.rs:8:7
+ --> $DIR/non_minimal_cfg.rs:6:7
|
LL | #[cfg(any(windows))]
| ^^^^^^^^^^^^ help: try: `windows`
error: unneeded sub `cfg` when there is only one condition
- --> $DIR/non_minimal_cfg.rs:11:11
+ --> $DIR/non_minimal_cfg.rs:9:11
|
LL | #[cfg(all(any(unix), all(not(windows))))]
| ^^^^^^^^^ help: try: `unix`
error: unneeded sub `cfg` when there is only one condition
- --> $DIR/non_minimal_cfg.rs:11:22
+ --> $DIR/non_minimal_cfg.rs:9:22
|
LL | #[cfg(all(any(unix), all(not(windows))))]
| ^^^^^^^^^^^^^^^^^ help: try: `not(windows)`
diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg2.rs b/src/tools/clippy/tests/ui/non_minimal_cfg2.rs
index a4c6abce3..f9e3ba4da 100644
--- a/src/tools/clippy/tests/ui/non_minimal_cfg2.rs
+++ b/src/tools/clippy/tests/ui/non_minimal_cfg2.rs
@@ -1,6 +1,8 @@
#![allow(unused)]
#[cfg(all())]
+//~^ ERROR: unneeded sub `cfg` when there is no condition
+//~| NOTE: `-D clippy::non-minimal-cfg` implied by `-D warnings`
fn all() {}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr b/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr
index 2a9a36fbc..001fcddd9 100644
--- a/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr
+++ b/src/tools/clippy/tests/ui/non_minimal_cfg2.stderr
@@ -5,6 +5,7 @@ LL | #[cfg(all())]
| ^^^^^
|
= note: `-D clippy::non-minimal-cfg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_minimal_cfg)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed b/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed
index 5d0da8dce..245d36cb7 100644
--- a/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed
+++ b/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed
@@ -1,5 +1,5 @@
//@ignore-target-windows
-//@run-rustfix
+
#![warn(clippy::non_octal_unix_permissions)]
use std::fs::{DirBuilder, File, OpenOptions, Permissions};
use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt};
diff --git a/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs b/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs
index 04a364305..d1559cba5 100644
--- a/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs
+++ b/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs
@@ -1,5 +1,5 @@
//@ignore-target-windows
-//@run-rustfix
+
#![warn(clippy::non_octal_unix_permissions)]
use std::fs::{DirBuilder, File, OpenOptions, Permissions};
use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt};
diff --git a/src/tools/clippy/tests/ui/non_octal_unix_permissions.stderr b/src/tools/clippy/tests/ui/non_octal_unix_permissions.stderr
index 32845d065..78c8f1a2f 100644
--- a/src/tools/clippy/tests/ui/non_octal_unix_permissions.stderr
+++ b/src/tools/clippy/tests/ui/non_octal_unix_permissions.stderr
@@ -5,6 +5,7 @@ LL | options.mode(440);
| ^^^ help: consider using an octal literal instead: `0o440`
|
= note: `-D clippy::non-octal-unix-permissions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_octal_unix_permissions)]`
error: using a non-octal value to set unix file permissions
--> $DIR/non_octal_unix_permissions.rs:17:47
diff --git a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
index 514fb25c8..c6855a096 100644
--- a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
@@ -15,6 +15,7 @@ pub struct RingBuffer<T> {
}
unsafe impl<T> Send for RingBuffer<T> {}
+//~^ ERROR: some fields in `RingBuffer<T>` are not safe to be sent to another thread
// noise_search / RUSTSEC-2020-0141
pub struct MvccRwLock<T> {
@@ -23,6 +24,7 @@ pub struct MvccRwLock<T> {
}
unsafe impl<T> Send for MvccRwLock<T> {}
+//~^ ERROR: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
// async-coap / RUSTSEC-2020-0124
pub struct ArcGuard<RC, T> {
@@ -31,6 +33,7 @@ pub struct ArcGuard<RC, T> {
}
unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
+//~^ ERROR: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread
// rusb / RUSTSEC-2020-0098
extern "C" {
@@ -47,6 +50,7 @@ pub struct DeviceHandle<T: UsbContext> {
}
unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
+//~^ ERROR: some fields in `DeviceHandle<T>` are not safe to be sent to another thread
// Other basic tests
pub struct NoGeneric {
@@ -54,6 +58,7 @@ pub struct NoGeneric {
}
unsafe impl Send for NoGeneric {}
+//~^ ERROR: some fields in `NoGeneric` are not safe to be sent to another thread
pub struct MultiField<T> {
field1: T,
@@ -62,6 +67,7 @@ pub struct MultiField<T> {
}
unsafe impl<T> Send for MultiField<T> {}
+//~^ ERROR: some fields in `MultiField<T>` are not safe to be sent to another thread
pub enum MyOption<T> {
MySome(T),
@@ -69,6 +75,7 @@ pub enum MyOption<T> {
}
unsafe impl<T> Send for MyOption<T> {}
+//~^ ERROR: some fields in `MyOption<T>` are not safe to be sent to another thread
// Test types that contain `NonNull` instead of raw pointers (#8045)
pub struct WrappedNonNull(UnsafeCell<NonNull<()>>);
@@ -81,6 +88,7 @@ pub struct MultiParam<A, B> {
}
unsafe impl<A, B> Send for MultiParam<A, B> {}
+//~^ ERROR: some fields in `MultiParam<A, B>` are not safe to be sent to another thread
// Tests for raw pointer heuristic
extern "C" {
@@ -99,6 +107,7 @@ pub struct HeuristicTest {
}
unsafe impl Send for HeuristicTest {}
+//~^ ERROR: some fields in `HeuristicTest` are not safe to be sent to another thread
// Test attributes
#[allow(clippy::non_send_fields_in_send_ty)]
@@ -118,6 +127,7 @@ pub enum AttrTest3<T> {
unsafe impl<T> Send for AttrTest1<T> {}
unsafe impl<T> Send for AttrTest2<T> {}
unsafe impl<T> Send for AttrTest3<T> {}
+//~^ ERROR: some fields in `AttrTest3<T>` are not safe to be sent to another thread
// Multiple non-overlapping `Send` for a single type
pub struct Complex<A, B> {
@@ -126,8 +136,10 @@ pub struct Complex<A, B> {
}
unsafe impl<P> Send for Complex<P, u32> {}
+//~^ ERROR: some fields in `Complex<P, u32>` are not safe to be sent to another thread
// `MutexGuard` is non-Send
unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
+//~^ ERROR: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent
fn main() {}
diff --git a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
index e912b59a6..1ea76196a 100644
--- a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
+++ b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
@@ -11,157 +11,158 @@ LL | data: Vec<UnsafeCell<T>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send`
= note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::non_send_fields_in_send_ty)]`
error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:25:1
+ --> $DIR/non_send_fields_in_send_ty.rs:26:1
|
LL | unsafe impl<T> Send for MvccRwLock<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `lock` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:22:5
+ --> $DIR/non_send_fields_in_send_ty.rs:23:5
|
LL | lock: Mutex<Box<T>>,
| ^^^^^^^^^^^^^^^^^^^
= help: add bounds on type parameter `T` that satisfy `Mutex<Box<T>>: Send`
error: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:33:1
+ --> $DIR/non_send_fields_in_send_ty.rs:35:1
|
LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `head` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:30:5
+ --> $DIR/non_send_fields_in_send_ty.rs:32:5
|
LL | head: Arc<RC>,
| ^^^^^^^^^^^^^
= help: add bounds on type parameter `RC` that satisfy `Arc<RC>: Send`
error: some fields in `DeviceHandle<T>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:49:1
+ --> $DIR/non_send_fields_in_send_ty.rs:52:1
|
LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `context` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:45:5
+ --> $DIR/non_send_fields_in_send_ty.rs:48:5
|
LL | context: T,
| ^^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
error: some fields in `NoGeneric` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:56:1
+ --> $DIR/non_send_fields_in_send_ty.rs:60:1
|
LL | unsafe impl Send for NoGeneric {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `rc_is_not_send` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:53:5
+ --> $DIR/non_send_fields_in_send_ty.rs:57:5
|
LL | rc_is_not_send: Rc<String>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use a thread-safe type that implements `Send`
error: some fields in `MultiField<T>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:64:1
+ --> $DIR/non_send_fields_in_send_ty.rs:69:1
|
LL | unsafe impl<T> Send for MultiField<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field1` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:59:5
+ --> $DIR/non_send_fields_in_send_ty.rs:64:5
|
LL | field1: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
note: it is not safe to send field `field2` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:60:5
+ --> $DIR/non_send_fields_in_send_ty.rs:65:5
|
LL | field2: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
note: it is not safe to send field `field3` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:61:5
+ --> $DIR/non_send_fields_in_send_ty.rs:66:5
|
LL | field3: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
error: some fields in `MyOption<T>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:71:1
+ --> $DIR/non_send_fields_in_send_ty.rs:77:1
|
LL | unsafe impl<T> Send for MyOption<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `0` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:67:12
+ --> $DIR/non_send_fields_in_send_ty.rs:73:12
|
LL | MySome(T),
| ^
= help: add `T: Send` bound in `Send` impl
error: some fields in `MultiParam<A, B>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:83:1
+ --> $DIR/non_send_fields_in_send_ty.rs:90:1
|
LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `vec` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:80:5
+ --> $DIR/non_send_fields_in_send_ty.rs:87:5
|
LL | vec: Vec<(A, B)>,
| ^^^^^^^^^^^^^^^^
= help: add bounds on type parameters `A, B` that satisfy `Vec<(A, B)>: Send`
error: some fields in `HeuristicTest` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:101:1
+ --> $DIR/non_send_fields_in_send_ty.rs:109:1
|
LL | unsafe impl Send for HeuristicTest {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field4` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:96:5
+ --> $DIR/non_send_fields_in_send_ty.rs:104:5
|
LL | field4: (*const NonSend, Rc<u8>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use a thread-safe type that implements `Send`
error: some fields in `AttrTest3<T>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:120:1
+ --> $DIR/non_send_fields_in_send_ty.rs:129:1
|
LL | unsafe impl<T> Send for AttrTest3<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `0` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:115:11
+ --> $DIR/non_send_fields_in_send_ty.rs:124:11
|
LL | Enum2(T),
| ^
= help: add `T: Send` bound in `Send` impl
error: some fields in `Complex<P, u32>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:128:1
+ --> $DIR/non_send_fields_in_send_ty.rs:138:1
|
LL | unsafe impl<P> Send for Complex<P, u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field1` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:124:5
+ --> $DIR/non_send_fields_in_send_ty.rs:134:5
|
LL | field1: A,
| ^^^^^^^^^
= help: add `P: Send` bound in `Send` impl
error: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:131:1
+ --> $DIR/non_send_fields_in_send_ty.rs:142:1
|
LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field2` to another thread
- --> $DIR/non_send_fields_in_send_ty.rs:125:5
+ --> $DIR/non_send_fields_in_send_ty.rs:135:5
|
LL | field2: B,
| ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs
index e4aa0937b..da7876e77 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![feature(lint_reasons)]
#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
#![warn(clippy::nonminimal_bool)]
@@ -10,15 +11,23 @@ fn main() {
let d: bool = unimplemented!();
let e: bool = unimplemented!();
let _ = !true;
+ //~^ ERROR: this boolean expression can be simplified
+ //~| NOTE: `-D clippy::nonminimal-bool` implied by `-D warnings`
let _ = !false;
+ //~^ ERROR: this boolean expression can be simplified
let _ = !!a;
+ //~^ ERROR: this boolean expression can be simplified
let _ = false || a;
+ //~^ ERROR: this boolean expression can be simplified
// don't lint on cfgs
let _ = cfg!(you_shall_not_not_pass) && a;
let _ = a || !b || !c || !d || !e;
let _ = !(!a && b);
+ //~^ ERROR: this boolean expression can be simplified
let _ = !(!a || b);
+ //~^ ERROR: this boolean expression can be simplified
let _ = !a && !(b && c);
+ //~^ ERROR: this boolean expression can be simplified
}
fn equality_stuff() {
@@ -27,10 +36,15 @@ fn equality_stuff() {
let c: i32 = unimplemented!();
let d: i32 = unimplemented!();
let _ = a == b && c == 5 && a == b;
+ //~^ ERROR: this boolean expression can be simplified
let _ = a == b || c == 5 || a == b;
+ //~^ ERROR: this boolean expression can be simplified
let _ = a == b && c == 5 && b == a;
+ //~^ ERROR: this boolean expression can be simplified
let _ = a != b || !(a != b || c == d);
+ //~^ ERROR: this boolean expression can be simplified
let _ = a != b && !(a != b && c == d);
+ //~^ ERROR: this boolean expression can be simplified
}
fn issue3847(a: u32, b: u32) -> bool {
@@ -61,6 +75,7 @@ fn check_expect() {
fn issue9428() {
if matches!(true, true) && true {
+ //~^ ERROR: this boolean expression can be simplified
println!("foo");
}
}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
index e2e4d6477..deae389db 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
@@ -1,49 +1,50 @@
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:12:13
+ --> $DIR/nonminimal_bool.rs:13:13
|
LL | let _ = !true;
| ^^^^^ help: try: `false`
|
= note: `-D clippy::nonminimal-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:13:13
+ --> $DIR/nonminimal_bool.rs:16:13
|
LL | let _ = !false;
| ^^^^^^ help: try: `true`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:14:13
+ --> $DIR/nonminimal_bool.rs:18:13
|
LL | let _ = !!a;
| ^^^ help: try: `a`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:15:13
+ --> $DIR/nonminimal_bool.rs:20:13
|
LL | let _ = false || a;
| ^^^^^^^^^^ help: try: `a`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:19:13
+ --> $DIR/nonminimal_bool.rs:25:13
|
LL | let _ = !(!a && b);
| ^^^^^^^^^^ help: try: `a || !b`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:20:13
+ --> $DIR/nonminimal_bool.rs:27:13
|
LL | let _ = !(!a || b);
| ^^^^^^^^^^ help: try: `a && !b`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:21:13
+ --> $DIR/nonminimal_bool.rs:29:13
|
LL | let _ = !a && !(b && c);
| ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:29:13
+ --> $DIR/nonminimal_bool.rs:38:13
|
LL | let _ = a == b && c == 5 && a == b;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | let _ = a == b && c == 5;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:30:13
+ --> $DIR/nonminimal_bool.rs:40:13
|
LL | let _ = a == b || c == 5 || a == b;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,7 +70,7 @@ LL | let _ = a == b || c == 5;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:31:13
+ --> $DIR/nonminimal_bool.rs:42:13
|
LL | let _ = a == b && c == 5 && b == a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -82,7 +83,7 @@ LL | let _ = a == b && c == 5;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:32:13
+ --> $DIR/nonminimal_bool.rs:44:13
|
LL | let _ = a != b || !(a != b || c == d);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -95,7 +96,7 @@ LL | let _ = a != b || c != d;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:33:13
+ --> $DIR/nonminimal_bool.rs:46:13
|
LL | let _ = a != b && !(a != b && c == d);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -108,7 +109,7 @@ LL | let _ = a != b && c != d;
| ~~~~~~~~~~~~~~~~
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool.rs:63:8
+ --> $DIR/nonminimal_bool.rs:77:8
|
LL | if matches!(true, true) && true {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)`
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
index 294f2aa48..e27c0350d 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
#![warn(clippy::nonminimal_bool)]
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
index a165368ab..040a6e920 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
#![warn(clippy::nonminimal_bool)]
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
index 21b84db85..d47bbf7e0 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
@@ -1,79 +1,80 @@
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:9:13
+ --> $DIR/nonminimal_bool_methods.rs:8:13
|
LL | let _ = !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
|
= note: `-D clippy::nonminimal-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:11:13
+ --> $DIR/nonminimal_bool_methods.rs:10:13
|
LL | let _ = !a.is_none();
| ^^^^^^^^^^^^ help: try: `a.is_some()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:13:13
+ --> $DIR/nonminimal_bool_methods.rs:12:13
|
LL | let _ = !b.is_err();
| ^^^^^^^^^^^ help: try: `b.is_ok()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:15:13
+ --> $DIR/nonminimal_bool_methods.rs:14:13
|
LL | let _ = !b.is_ok();
| ^^^^^^^^^^ help: try: `b.is_err()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:17:13
+ --> $DIR/nonminimal_bool_methods.rs:16:13
|
LL | let _ = !(a.is_some() && !c);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:18:13
+ --> $DIR/nonminimal_bool_methods.rs:17:13
|
LL | let _ = !(a.is_some() || !c);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:19:26
+ --> $DIR/nonminimal_bool_methods.rs:18:26
|
LL | let _ = !(!c ^ c) || !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:20:25
+ --> $DIR/nonminimal_bool_methods.rs:19:25
|
LL | let _ = (!c ^ c) || !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:21:23
+ --> $DIR/nonminimal_bool_methods.rs:20:23
|
LL | let _ = !c ^ c || !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:93:8
+ --> $DIR/nonminimal_bool_methods.rs:92:8
|
LL | if !res.is_ok() {}
| ^^^^^^^^^^^^ help: try: `res.is_err()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:94:8
+ --> $DIR/nonminimal_bool_methods.rs:93:8
|
LL | if !res.is_err() {}
| ^^^^^^^^^^^^^ help: try: `res.is_ok()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:97:8
+ --> $DIR/nonminimal_bool_methods.rs:96:8
|
LL | if !res.is_some() {}
| ^^^^^^^^^^^^^^ help: try: `res.is_none()`
error: this boolean expression can be simplified
- --> $DIR/nonminimal_bool_methods.rs:98:8
+ --> $DIR/nonminimal_bool_methods.rs:97:8
|
LL | if !res.is_none() {}
| ^^^^^^^^^^^^^^ help: try: `res.is_some()`
diff --git a/src/tools/clippy/tests/ui/numbered_fields.fixed b/src/tools/clippy/tests/ui/numbered_fields.fixed
index a52845e53..7f0a6f8e5 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.fixed
+++ b/src/tools/clippy/tests/ui/numbered_fields.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::init_numbered_fields)]
#![allow(unused_tuple_struct_fields)]
diff --git a/src/tools/clippy/tests/ui/numbered_fields.rs b/src/tools/clippy/tests/ui/numbered_fields.rs
index ca93f7dce..38f3b36ec 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.rs
+++ b/src/tools/clippy/tests/ui/numbered_fields.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::init_numbered_fields)]
#![allow(unused_tuple_struct_fields)]
diff --git a/src/tools/clippy/tests/ui/numbered_fields.stderr b/src/tools/clippy/tests/ui/numbered_fields.stderr
index 26f7ad904..d52a0cf15 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.stderr
+++ b/src/tools/clippy/tests/ui/numbered_fields.stderr
@@ -1,5 +1,5 @@
error: used a field initializer for a tuple struct
- --> $DIR/numbered_fields.rs:19:13
+ --> $DIR/numbered_fields.rs:18:13
|
LL | let _ = TupleStruct {
| _____________^
@@ -10,9 +10,10 @@ LL | | };
| |_____^ help: try: `TupleStruct(1u32, 42, 23u8)`
|
= note: `-D clippy::init-numbered-fields` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::init_numbered_fields)]`
error: used a field initializer for a tuple struct
- --> $DIR/numbered_fields.rs:26:13
+ --> $DIR/numbered_fields.rs:25:13
|
LL | let _ = TupleStruct {
| _____________^
diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.fixed b/src/tools/clippy/tests/ui/obfuscated_if_else.fixed
index 9e4f97253..c5ee56980 100644
--- a/src/tools/clippy/tests/ui/obfuscated_if_else.fixed
+++ b/src/tools/clippy/tests/ui/obfuscated_if_else.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::obfuscated_if_else)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.rs b/src/tools/clippy/tests/ui/obfuscated_if_else.rs
index c2351d64c..2b60c855a 100644
--- a/src/tools/clippy/tests/ui/obfuscated_if_else.rs
+++ b/src/tools/clippy/tests/ui/obfuscated_if_else.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::obfuscated_if_else)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.stderr b/src/tools/clippy/tests/ui/obfuscated_if_else.stderr
index e4180c288..ca9f5e1e3 100644
--- a/src/tools/clippy/tests/ui/obfuscated_if_else.stderr
+++ b/src/tools/clippy/tests/ui/obfuscated_if_else.stderr
@@ -1,10 +1,11 @@
error: use of `.then_some(..).unwrap_or(..)` can be written more clearly with `if .. else ..`
- --> $DIR/obfuscated_if_else.rs:6:5
+ --> $DIR/obfuscated_if_else.rs:4:5
|
LL | true.then_some("a").unwrap_or("b");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }`
|
= note: `-D clippy::obfuscated-if-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::obfuscated_if_else)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/octal_escapes.rs b/src/tools/clippy/tests/ui/octal_escapes.rs
index 61ea96604..3915dfdb8 100644
--- a/src/tools/clippy/tests/ui/octal_escapes.rs
+++ b/src/tools/clippy/tests/ui/octal_escapes.rs
@@ -1,16 +1,26 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::octal_escapes)]
fn main() {
let _bad1 = "\033[0m";
+ //~^ ERROR: octal-looking escape in string literal
let _bad2 = b"\033[0m";
+ //~^ ERROR: octal-looking escape in byte string literal
let _bad3 = "\\\033[0m";
+ //~^ ERROR: octal-looking escape in string literal
// maximum 3 digits (\012 is the escape)
let _bad4 = "\01234567";
+ //~^ ERROR: octal-looking escape in string literal
let _bad5 = "\0\03";
+ //~^ ERROR: octal-looking escape in string literal
let _bad6 = "Text-\055\077-MoreText";
+ //~^ ERROR: octal-looking escape in string literal
let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
+ //~^ ERROR: octal-looking escape in string literal
let _bad8 = "锈\01锈";
+ //~^ ERROR: octal-looking escape in string literal
let _bad9 = "锈\011锈";
+ //~^ ERROR: octal-looking escape in string literal
let _good1 = "\\033[0m";
let _good2 = "\0\\0";
diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr
index 63fdfe486..d2161582b 100644
--- a/src/tools/clippy/tests/ui/octal_escapes.stderr
+++ b/src/tools/clippy/tests/ui/octal_escapes.stderr
@@ -1,146 +1,147 @@
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:4:17
+ --> $DIR/octal_escapes.rs:5:17
|
-LL | let _bad1 = "/033[0m";
+LL | let _bad1 = "\033[0m";
| ^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
= note: `-D clippy::octal-escapes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]`
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad1 = "/x1b[0m";
+LL | let _bad1 = "\x1b[0m";
| ~~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad1 = "/x0033[0m";
+LL | let _bad1 = "\x0033[0m";
| ~~~~~~~~~~~
error: octal-looking escape in byte string literal
- --> $DIR/octal_escapes.rs:5:17
+ --> $DIR/octal_escapes.rs:7:17
|
-LL | let _bad2 = b"/033[0m";
+LL | let _bad2 = b"\033[0m";
| ^^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null byte
+ = help: octal escapes are not supported, `\0` is always a null byte
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad2 = b"/x1b[0m";
+LL | let _bad2 = b"\x1b[0m";
| ~~~~~~~~~~
help: if the null byte is intended, disambiguate using
|
-LL | let _bad2 = b"/x0033[0m";
+LL | let _bad2 = b"\x0033[0m";
| ~~~~~~~~~~~~
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:6:17
+ --> $DIR/octal_escapes.rs:9:17
|
-LL | let _bad3 = "///033[0m";
+LL | let _bad3 = "\\\033[0m";
| ^^^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad3 = "///x1b[0m";
+LL | let _bad3 = "\\\x1b[0m";
| ~~~~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad3 = "///x0033[0m";
+LL | let _bad3 = "\\\x0033[0m";
| ~~~~~~~~~~~~~
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:8:17
+ --> $DIR/octal_escapes.rs:12:17
|
-LL | let _bad4 = "/01234567";
+LL | let _bad4 = "\01234567";
| ^^^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad4 = "/x0a34567";
+LL | let _bad4 = "\x0a34567";
| ~~~~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad4 = "/x001234567";
+LL | let _bad4 = "\x001234567";
| ~~~~~~~~~~~~~
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:9:17
+ --> $DIR/octal_escapes.rs:14:17
|
-LL | let _bad5 = "/0/03";
+LL | let _bad5 = "\0\03";
| ^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad5 = "/0/x03";
+LL | let _bad5 = "\0\x03";
| ~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad5 = "/0/x003";
+LL | let _bad5 = "\0\x003";
| ~~~~~~~~~
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:10:17
+ --> $DIR/octal_escapes.rs:16:17
|
-LL | let _bad6 = "Text-/055/077-MoreText";
+LL | let _bad6 = "Text-\055\077-MoreText";
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad6 = "Text-/x2d/x3f-MoreText";
+LL | let _bad6 = "Text-\x2d\x3f-MoreText";
| ~~~~~~~~~~~~~~~~~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad6 = "Text-/x0055/x0077-MoreText";
+LL | let _bad6 = "Text-\x0055\x0077-MoreText";
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:11:17
+ --> $DIR/octal_escapes.rs:18:17
|
-LL | let _bad7 = "EvenMoreText-/01/02-ShortEscapes";
+LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad7 = "EvenMoreText-/x01/x02-ShortEscapes";
+LL | let _bad7 = "EvenMoreText-\x01\x02-ShortEscapes";
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad7 = "EvenMoreText-/x001/x002-ShortEscapes";
+LL | let _bad7 = "EvenMoreText-\x001\x002-ShortEscapes";
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:12:17
+ --> $DIR/octal_escapes.rs:20:17
|
-LL | let _bad8 = "锈/01锈";
+LL | let _bad8 = "锈\01锈";
| ^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad8 = "锈/x01锈";
+LL | let _bad8 = "锈\x01锈";
| ~~~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad8 = "锈/x001锈";
+LL | let _bad8 = "锈\x001锈";
| ~~~~~~~~~~~
error: octal-looking escape in string literal
- --> $DIR/octal_escapes.rs:13:17
+ --> $DIR/octal_escapes.rs:22:17
|
-LL | let _bad9 = "锈/011锈";
+LL | let _bad9 = "锈\011锈";
| ^^^^^^^^^^
|
- = help: octal escapes are not supported, `/0` is always a null character
+ = help: octal escapes are not supported, `\0` is always a null character
help: if an octal escape was intended, use the hexadecimal representation instead
|
-LL | let _bad9 = "锈/x09锈";
+LL | let _bad9 = "锈\x09锈";
| ~~~~~~~~~~
help: if the null character is intended, disambiguate using
|
-LL | let _bad9 = "锈/x0011锈";
+LL | let _bad9 = "锈\x0011锈";
| ~~~~~~~~~~~~
error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/ok_expect.rs b/src/tools/clippy/tests/ui/ok_expect.rs
index 2047ee689..c2ad21e22 100644
--- a/src/tools/clippy/tests/ui/ok_expect.rs
+++ b/src/tools/clippy/tests/ui/ok_expect.rs
@@ -14,16 +14,21 @@ fn main() {
let _ = res.unwrap();
res.ok().expect("disaster!");
+ //~^ ERROR: called `ok().expect()` on a `Result` value
// the following should not warn, since `expect` isn't implemented unless
// the error type implements `Debug`
let res2: Result<i32, MyError> = Ok(0);
res2.ok().expect("oh noes!");
let res3: Result<u32, MyErrorWithParam<u8>> = Ok(0);
res3.ok().expect("whoof");
+ //~^ ERROR: called `ok().expect()` on a `Result` value
let res4: Result<u32, io::Error> = Ok(0);
res4.ok().expect("argh");
+ //~^ ERROR: called `ok().expect()` on a `Result` value
let res5: io::Result<u32> = Ok(0);
res5.ok().expect("oops");
+ //~^ ERROR: called `ok().expect()` on a `Result` value
let res6: Result<u32, &str> = Ok(0);
res6.ok().expect("meh");
+ //~^ ERROR: called `ok().expect()` on a `Result` value
}
diff --git a/src/tools/clippy/tests/ui/ok_expect.stderr b/src/tools/clippy/tests/ui/ok_expect.stderr
index ab9df26eb..ac2b6dcc8 100644
--- a/src/tools/clippy/tests/ui/ok_expect.stderr
+++ b/src/tools/clippy/tests/ui/ok_expect.stderr
@@ -6,9 +6,10 @@ LL | res.ok().expect("disaster!");
|
= help: you can call `expect()` directly on the `Result`
= note: `-D clippy::ok-expect` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ok_expect)]`
error: called `ok().expect()` on a `Result` value
- --> $DIR/ok_expect.rs:22:5
+ --> $DIR/ok_expect.rs:23:5
|
LL | res3.ok().expect("whoof");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | res3.ok().expect("whoof");
= help: you can call `expect()` directly on the `Result`
error: called `ok().expect()` on a `Result` value
- --> $DIR/ok_expect.rs:24:5
+ --> $DIR/ok_expect.rs:26:5
|
LL | res4.ok().expect("argh");
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | res4.ok().expect("argh");
= help: you can call `expect()` directly on the `Result`
error: called `ok().expect()` on a `Result` value
- --> $DIR/ok_expect.rs:26:5
+ --> $DIR/ok_expect.rs:29:5
|
LL | res5.ok().expect("oops");
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | res5.ok().expect("oops");
= help: you can call `expect()` directly on the `Result`
error: called `ok().expect()` on a `Result` value
- --> $DIR/ok_expect.rs:28:5
+ --> $DIR/ok_expect.rs:32:5
|
LL | res6.ok().expect("meh");
| ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.rs b/src/tools/clippy/tests/ui/only_used_in_recursion.rs
index f71e8ead5..169fb790f 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion.rs
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion.rs
@@ -1,5 +1,5 @@
#![warn(clippy::only_used_in_recursion)]
-
+//@no-rustfix
fn _simple(x: u32) -> u32 {
x
}
@@ -9,14 +9,18 @@ fn _simple2(x: u32) -> u32 {
}
fn _one_unused(flag: u32, a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { _one_unused(flag - 1, a) }
}
fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
+ //~^ ERROR: parameter is only used in recursion
+ //~| ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
}
fn _with_calc(flag: u32, a: i64) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 {
0
} else {
@@ -30,6 +34,8 @@ fn _used_with_flag(flag: u32, a: u32) -> usize {
}
fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
+ //~^ ERROR: parameter is only used in recursion
+ //~| ERROR: parameter is only used in recursion
if flag == 0 {
0
} else {
@@ -38,6 +44,8 @@ fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
}
fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
+ //~^ ERROR: parameter is only used in recursion
+ //~| ERROR: parameter is only used in recursion
if flag == 0 {
0
} else {
@@ -46,6 +54,7 @@ fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
}
fn _not_primitive(flag: u32, b: String) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { _not_primitive(flag - 1, b) }
}
@@ -53,10 +62,13 @@ struct A;
impl A {
fn _method(flag: usize, a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { Self::_method(flag - 1, a) }
}
fn _method_self(&self, flag: usize, a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
+ //~| ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
}
}
@@ -68,10 +80,12 @@ trait B {
impl B for A {
fn method(flag: u32, a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { Self::method(flag - 1, a) }
}
fn method_self(&self, flag: u32, a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
}
}
@@ -98,10 +112,12 @@ impl B for u32 {
trait C {
fn method(flag: u32, a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { Self::method(flag - 1, a) }
}
fn method_self(&self, flag: u32, a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
}
}
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
index 571e5c4b5..85eee99c0 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
@@ -5,188 +5,189 @@ LL | fn _one_unused(flag: u32, a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:12:53
+ --> $DIR/only_used_in_recursion.rs:13:53
|
LL | if flag == 0 { 0 } else { _one_unused(flag - 1, a) }
| ^
= note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::only_used_in_recursion)]`
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:15:27
+ --> $DIR/only_used_in_recursion.rs:16:27
|
LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:16:53
+ --> $DIR/only_used_in_recursion.rs:19:53
|
LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:15:35
+ --> $DIR/only_used_in_recursion.rs:16:35
|
LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_b`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:16:56
+ --> $DIR/only_used_in_recursion.rs:19:56
|
LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:19:26
+ --> $DIR/only_used_in_recursion.rs:22:26
|
LL | fn _with_calc(flag: u32, a: i64) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:23:32
+ --> $DIR/only_used_in_recursion.rs:27:32
|
LL | _with_calc(flag - 1, (-a + 10) * 5)
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:32:33
+ --> $DIR/only_used_in_recursion.rs:36:33
|
LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:36:38
+ --> $DIR/only_used_in_recursion.rs:42:38
|
LL | _used_with_unused(flag - 1, -a, a + b)
| ^ ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:32:41
+ --> $DIR/only_used_in_recursion.rs:36:41
|
LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_b`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:36:45
+ --> $DIR/only_used_in_recursion.rs:42:45
|
LL | _used_with_unused(flag - 1, -a, a + b)
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:40:35
+ --> $DIR/only_used_in_recursion.rs:46:35
|
LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:44:39
+ --> $DIR/only_used_in_recursion.rs:52:39
|
LL | _codependent_unused(flag - 1, a * b, a + b)
| ^ ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:40:43
+ --> $DIR/only_used_in_recursion.rs:46:43
|
LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_b`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:44:43
+ --> $DIR/only_used_in_recursion.rs:52:43
|
LL | _codependent_unused(flag - 1, a * b, a + b)
| ^ ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:48:30
+ --> $DIR/only_used_in_recursion.rs:56:30
|
LL | fn _not_primitive(flag: u32, b: String) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_b`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:49:56
+ --> $DIR/only_used_in_recursion.rs:58:56
|
LL | if flag == 0 { 0 } else { _not_primitive(flag - 1, b) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:55:29
+ --> $DIR/only_used_in_recursion.rs:64:29
|
LL | fn _method(flag: usize, a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:56:59
+ --> $DIR/only_used_in_recursion.rs:66:59
|
LL | if flag == 0 { 0 } else { Self::_method(flag - 1, a) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:59:22
+ --> $DIR/only_used_in_recursion.rs:69:22
|
LL | fn _method_self(&self, flag: usize, a: usize) -> usize {
| ^^^^
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:60:35
+ --> $DIR/only_used_in_recursion.rs:72:35
|
LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
| ^^^^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:59:41
+ --> $DIR/only_used_in_recursion.rs:69:41
|
LL | fn _method_self(&self, flag: usize, a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:60:63
+ --> $DIR/only_used_in_recursion.rs:72:63
|
LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:70:26
+ --> $DIR/only_used_in_recursion.rs:82:26
|
LL | fn method(flag: u32, a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:71:58
+ --> $DIR/only_used_in_recursion.rs:84:58
|
LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:74:38
+ --> $DIR/only_used_in_recursion.rs:87:38
|
LL | fn method_self(&self, flag: u32, a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:75:62
+ --> $DIR/only_used_in_recursion.rs:89:62
|
LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:100:26
+ --> $DIR/only_used_in_recursion.rs:114:26
|
LL | fn method(flag: u32, a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:101:58
+ --> $DIR/only_used_in_recursion.rs:116:58
|
LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion.rs:104:38
+ --> $DIR/only_used_in_recursion.rs:119:38
|
LL | fn method_self(&self, flag: u32, a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion.rs:105:62
+ --> $DIR/only_used_in_recursion.rs:121:62
|
LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
| ^
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.rs b/src/tools/clippy/tests/ui/only_used_in_recursion2.rs
index 45dd0553f..1353ff881 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion2.rs
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.rs
@@ -1,7 +1,9 @@
#![warn(clippy::only_used_in_recursion)]
-
+//@no-rustfix
fn _with_inner(flag: u32, a: u32, b: u32) -> usize {
+ //~^ ERROR: parameter is only used in recursion
fn inner(flag: u32, a: u32) -> u32 {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 { 0 } else { inner(flag, a) }
}
@@ -10,6 +12,7 @@ fn _with_inner(flag: u32, a: u32, b: u32) -> usize {
}
fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 {
+ //~^ ERROR: parameter is only used in recursion
if let Some(x) = a.and_then(|x| f(x, x)) {
_with_closure(Some(x), b, f)
} else {
@@ -60,6 +63,7 @@ impl E<()> for () {
}
fn overwritten_param(flag: u32, mut a: usize) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 {
return 0;
} else if flag > 5 {
@@ -71,6 +75,7 @@ fn overwritten_param(flag: u32, mut a: usize) -> usize {
}
fn field_direct(flag: u32, mut a: (usize,)) -> usize {
+ //~^ ERROR: parameter is only used in recursion
if flag == 0 {
0
} else {
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
index 8dcbfdd61..3ddd9758c 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
@@ -5,56 +5,57 @@ LL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_b`
|
note: parameter used here
- --> $DIR/only_used_in_recursion2.rs:9:52
+ --> $DIR/only_used_in_recursion2.rs:11:52
|
LL | if flag == 0 { 0 } else { _with_inner(flag, a, b + x) }
| ^
= note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::only_used_in_recursion)]`
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion2.rs:4:25
+ --> $DIR/only_used_in_recursion2.rs:5:25
|
LL | fn inner(flag: u32, a: u32) -> u32 {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion2.rs:5:47
+ --> $DIR/only_used_in_recursion2.rs:7:47
|
LL | if flag == 0 { 0 } else { inner(flag, a) }
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion2.rs:12:34
+ --> $DIR/only_used_in_recursion2.rs:14:34
|
LL | fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 {
| ^ help: if this is intentional, prefix it with an underscore: `_b`
|
note: parameter used here
- --> $DIR/only_used_in_recursion2.rs:14:32
+ --> $DIR/only_used_in_recursion2.rs:17:32
|
LL | _with_closure(Some(x), b, f)
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion2.rs:62:37
+ --> $DIR/only_used_in_recursion2.rs:65:37
|
LL | fn overwritten_param(flag: u32, mut a: usize) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion2.rs:70:29
+ --> $DIR/only_used_in_recursion2.rs:74:29
|
LL | overwritten_param(flag, a)
| ^
error: parameter is only used in recursion
- --> $DIR/only_used_in_recursion2.rs:73:32
+ --> $DIR/only_used_in_recursion2.rs:77:32
|
LL | fn field_direct(flag: u32, mut a: (usize,)) -> usize {
| ^ help: if this is intentional, prefix it with an underscore: `_a`
|
note: parameter used here
- --> $DIR/only_used_in_recursion2.rs:78:32
+ --> $DIR/only_used_in_recursion2.rs:83:32
|
LL | field_direct(flag - 1, a)
| ^
diff --git a/src/tools/clippy/tests/ui/op_ref.fixed b/src/tools/clippy/tests/ui/op_ref.fixed
new file mode 100644
index 000000000..183dcf4f0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/op_ref.fixed
@@ -0,0 +1,99 @@
+#![allow(unused_variables, clippy::disallowed_names)]
+#![warn(clippy::op_ref)]
+use std::collections::HashSet;
+use std::ops::{BitAnd, Mul};
+
+fn main() {
+ let tracked_fds: HashSet<i32> = HashSet::new();
+ let new_fds = HashSet::new();
+ let unwanted = &tracked_fds - &new_fds;
+
+ let foo = 5 - 6;
+ //~^ ERROR: needlessly taken reference of both operands
+ //~| NOTE: `-D clippy::op-ref` implied by `-D warnings`
+
+ let bar = String::new();
+ let bar = "foo" == &bar;
+
+ let a = "a".to_string();
+ let b = "a";
+
+ if b < &a {
+ println!("OK");
+ }
+
+ struct X(i32);
+ impl BitAnd for X {
+ type Output = X;
+ fn bitand(self, rhs: X) -> X {
+ X(self.0 & rhs.0)
+ }
+ }
+ impl<'a> BitAnd<&'a X> for X {
+ type Output = X;
+ fn bitand(self, rhs: &'a X) -> X {
+ X(self.0 & rhs.0)
+ }
+ }
+ let x = X(1);
+ let y = X(2);
+ let z = x & &y;
+
+ #[derive(Copy, Clone)]
+ struct Y(i32);
+ impl BitAnd for Y {
+ type Output = Y;
+ fn bitand(self, rhs: Y) -> Y {
+ Y(self.0 & rhs.0)
+ }
+ }
+ impl<'a> BitAnd<&'a Y> for Y {
+ type Output = Y;
+ fn bitand(self, rhs: &'a Y) -> Y {
+ Y(self.0 & rhs.0)
+ }
+ }
+ let x = Y(1);
+ let y = Y(2);
+ let z = x & y;
+ //~^ ERROR: taken reference of right operand
+}
+
+#[derive(Clone, Copy)]
+struct A(i32);
+#[derive(Clone, Copy)]
+struct B(i32);
+
+impl Mul<&A> for B {
+ type Output = i32;
+ fn mul(self, rhs: &A) -> Self::Output {
+ self.0 * rhs.0
+ }
+}
+impl Mul<A> for B {
+ type Output = i32;
+ fn mul(self, rhs: A) -> Self::Output {
+ // Should not lint because removing the reference would lead to unconditional recursion
+ self * &rhs
+ }
+}
+impl Mul<&A> for A {
+ type Output = i32;
+ fn mul(self, rhs: &A) -> Self::Output {
+ self.0 * rhs.0
+ }
+}
+impl Mul<A> for A {
+ type Output = i32;
+ fn mul(self, rhs: A) -> Self::Output {
+ let one = B(1);
+ let two = 2;
+ let three = 3;
+ let _ = one * self;
+ //~^ ERROR: taken reference of right operand
+ let _ = two + three;
+ //~^ ERROR: taken reference of right operand
+ // Removing the reference would lead to unconditional recursion
+ self * &rhs
+ }
+}
diff --git a/src/tools/clippy/tests/ui/op_ref.rs b/src/tools/clippy/tests/ui/op_ref.rs
index 07226b0a1..6ed4f23d2 100644
--- a/src/tools/clippy/tests/ui/op_ref.rs
+++ b/src/tools/clippy/tests/ui/op_ref.rs
@@ -9,6 +9,8 @@ fn main() {
let unwanted = &tracked_fds - &new_fds;
let foo = &5 - &6;
+ //~^ ERROR: needlessly taken reference of both operands
+ //~| NOTE: `-D clippy::op-ref` implied by `-D warnings`
let bar = String::new();
let bar = "foo" == &bar;
@@ -54,6 +56,7 @@ fn main() {
let x = Y(1);
let y = Y(2);
let z = x & &y;
+ //~^ ERROR: taken reference of right operand
}
#[derive(Clone, Copy)]
@@ -87,7 +90,9 @@ impl Mul<A> for A {
let two = 2;
let three = 3;
let _ = one * &self;
+ //~^ ERROR: taken reference of right operand
let _ = two + &three;
+ //~^ ERROR: taken reference of right operand
// Removing the reference would lead to unconditional recursion
self * &rhs
}
diff --git a/src/tools/clippy/tests/ui/op_ref.stderr b/src/tools/clippy/tests/ui/op_ref.stderr
index fe36c0116..f03e24b84 100644
--- a/src/tools/clippy/tests/ui/op_ref.stderr
+++ b/src/tools/clippy/tests/ui/op_ref.stderr
@@ -5,13 +5,14 @@ LL | let foo = &5 - &6;
| ^^^^^^^
|
= note: `-D clippy::op-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::op_ref)]`
help: use the values directly
|
LL | let foo = 5 - 6;
| ~ ~
error: taken reference of right operand
- --> $DIR/op_ref.rs:56:13
+ --> $DIR/op_ref.rs:58:13
|
LL | let z = x & &y;
| ^^^^--
@@ -19,7 +20,7 @@ LL | let z = x & &y;
| help: use the right value directly: `y`
error: taken reference of right operand
- --> $DIR/op_ref.rs:89:17
+ --> $DIR/op_ref.rs:92:17
|
LL | let _ = one * &self;
| ^^^^^^-----
@@ -27,7 +28,7 @@ LL | let _ = one * &self;
| help: use the right value directly: `self`
error: taken reference of right operand
- --> $DIR/op_ref.rs:90:17
+ --> $DIR/op_ref.rs:94:17
|
LL | let _ = two + &three;
| ^^^^^^------
diff --git a/src/tools/clippy/tests/ui/open_options.rs b/src/tools/clippy/tests/ui/open_options.rs
index 9063fafbc..0cdc5bf2b 100644
--- a/src/tools/clippy/tests/ui/open_options.rs
+++ b/src/tools/clippy/tests/ui/open_options.rs
@@ -4,11 +4,19 @@ use std::fs::OpenOptions;
#[warn(clippy::nonsensical_open_options)]
fn main() {
OpenOptions::new().read(true).truncate(true).open("foo.txt");
+ //~^ ERROR: file opened with `truncate` and `read`
+ //~| NOTE: `-D clippy::nonsensical-open-options` implied by `-D warnings`
OpenOptions::new().append(true).truncate(true).open("foo.txt");
+ //~^ ERROR: file opened with `append` and `truncate`
OpenOptions::new().read(true).read(false).open("foo.txt");
+ //~^ ERROR: the method `read` is called more than once
OpenOptions::new().create(true).create(false).open("foo.txt");
+ //~^ ERROR: the method `create` is called more than once
OpenOptions::new().write(true).write(false).open("foo.txt");
+ //~^ ERROR: the method `write` is called more than once
OpenOptions::new().append(true).append(false).open("foo.txt");
+ //~^ ERROR: the method `append` is called more than once
OpenOptions::new().truncate(true).truncate(false).open("foo.txt");
+ //~^ ERROR: the method `truncate` is called more than once
}
diff --git a/src/tools/clippy/tests/ui/open_options.stderr b/src/tools/clippy/tests/ui/open_options.stderr
index 26fe9f6fb..7ac826f52 100644
--- a/src/tools/clippy/tests/ui/open_options.stderr
+++ b/src/tools/clippy/tests/ui/open_options.stderr
@@ -5,39 +5,40 @@ LL | OpenOptions::new().read(true).truncate(true).open("foo.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::nonsensical-open-options` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::nonsensical_open_options)]`
error: file opened with `append` and `truncate`
- --> $DIR/open_options.rs:7:5
+ --> $DIR/open_options.rs:9:5
|
LL | OpenOptions::new().append(true).truncate(true).open("foo.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the method `read` is called more than once
- --> $DIR/open_options.rs:9:5
+ --> $DIR/open_options.rs:12:5
|
LL | OpenOptions::new().read(true).read(false).open("foo.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the method `create` is called more than once
- --> $DIR/open_options.rs:10:5
+ --> $DIR/open_options.rs:14:5
|
LL | OpenOptions::new().create(true).create(false).open("foo.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the method `write` is called more than once
- --> $DIR/open_options.rs:11:5
+ --> $DIR/open_options.rs:16:5
|
LL | OpenOptions::new().write(true).write(false).open("foo.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the method `append` is called more than once
- --> $DIR/open_options.rs:12:5
+ --> $DIR/open_options.rs:18:5
|
LL | OpenOptions::new().append(true).append(false).open("foo.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the method `truncate` is called more than once
- --> $DIR/open_options.rs:13:5
+ --> $DIR/open_options.rs:20:5
|
LL | OpenOptions::new().truncate(true).truncate(false).open("foo.txt");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/option_as_ref_deref.fixed b/src/tools/clippy/tests/ui/option_as_ref_deref.fixed
index 4d1a6a1ab..c5a959ba5 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_deref.fixed
+++ b/src/tools/clippy/tests/ui/option_as_ref_deref.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::redundant_clone, clippy::useless_vec)]
#![warn(clippy::option_as_ref_deref)]
diff --git a/src/tools/clippy/tests/ui/option_as_ref_deref.rs b/src/tools/clippy/tests/ui/option_as_ref_deref.rs
index 66d5a1250..1aeedf211 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_deref.rs
+++ b/src/tools/clippy/tests/ui/option_as_ref_deref.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::redundant_clone, clippy::useless_vec)]
#![warn(clippy::option_as_ref_deref)]
diff --git a/src/tools/clippy/tests/ui/option_as_ref_deref.stderr b/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
index e471b56ee..eb0661c52 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
+++ b/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
@@ -1,13 +1,14 @@
error: called `.as_ref().map(Deref::deref)` on an Option value. This can be done more directly by calling `opt.clone().as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:13:13
+ --> $DIR/option_as_ref_deref.rs:11:13
|
LL | let _ = opt.clone().as_ref().map(Deref::deref).map(str::len);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.clone().as_deref()`
|
= note: `-D clippy::option-as-ref-deref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_deref)]`
error: called `.as_ref().map(Deref::deref)` on an Option value. This can be done more directly by calling `opt.clone().as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:16:13
+ --> $DIR/option_as_ref_deref.rs:14:13
|
LL | let _ = opt.clone()
| _____________^
@@ -17,97 +18,97 @@ LL | | )
| |_________^ help: try using as_deref instead: `opt.clone().as_deref()`
error: called `.as_mut().map(DerefMut::deref_mut)` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead
- --> $DIR/option_as_ref_deref.rs:22:13
+ --> $DIR/option_as_ref_deref.rs:20:13
|
LL | let _ = opt.as_mut().map(DerefMut::deref_mut);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
error: called `.as_ref().map(String::as_str)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:24:13
+ --> $DIR/option_as_ref_deref.rs:22:13
|
LL | let _ = opt.as_ref().map(String::as_str);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
error: called `.as_ref().map(|x| x.as_str())` on an Option value. This can be done more directly by calling `opt.as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:25:13
+ --> $DIR/option_as_ref_deref.rs:23:13
|
LL | let _ = opt.as_ref().map(|x| x.as_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
error: called `.as_mut().map(String::as_mut_str)` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead
- --> $DIR/option_as_ref_deref.rs:26:13
+ --> $DIR/option_as_ref_deref.rs:24:13
|
LL | let _ = opt.as_mut().map(String::as_mut_str);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
error: called `.as_mut().map(|x| x.as_mut_str())` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead
- --> $DIR/option_as_ref_deref.rs:27:13
+ --> $DIR/option_as_ref_deref.rs:25:13
|
LL | let _ = opt.as_mut().map(|x| x.as_mut_str());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
error: called `.as_ref().map(CString::as_c_str)` on an Option value. This can be done more directly by calling `Some(CString::new(vec![]).unwrap()).as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:28:13
+ --> $DIR/option_as_ref_deref.rs:26:13
|
LL | let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(CString::new(vec![]).unwrap()).as_deref()`
error: called `.as_ref().map(OsString::as_os_str)` on an Option value. This can be done more directly by calling `Some(OsString::new()).as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:29:13
+ --> $DIR/option_as_ref_deref.rs:27:13
|
LL | let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(OsString::new()).as_deref()`
error: called `.as_ref().map(PathBuf::as_path)` on an Option value. This can be done more directly by calling `Some(PathBuf::new()).as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:30:13
+ --> $DIR/option_as_ref_deref.rs:28:13
|
LL | let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(PathBuf::new()).as_deref()`
error: called `.as_ref().map(Vec::as_slice)` on an Option value. This can be done more directly by calling `Some(Vec::<()>::new()).as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:31:13
+ --> $DIR/option_as_ref_deref.rs:29:13
|
LL | let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(Vec::<()>::new()).as_deref()`
error: called `.as_mut().map(Vec::as_mut_slice)` on an Option value. This can be done more directly by calling `Some(Vec::<()>::new()).as_deref_mut()` instead
- --> $DIR/option_as_ref_deref.rs:32:13
+ --> $DIR/option_as_ref_deref.rs:30:13
|
LL | let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `Some(Vec::<()>::new()).as_deref_mut()`
error: called `.as_ref().map(|x| x.deref())` on an Option value. This can be done more directly by calling `opt.as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:34:13
+ --> $DIR/option_as_ref_deref.rs:32:13
|
LL | let _ = opt.as_ref().map(|x| x.deref());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
error: called `.as_mut().map(|x| x.deref_mut())` on an Option value. This can be done more directly by calling `opt.clone().as_deref_mut()` instead
- --> $DIR/option_as_ref_deref.rs:35:13
+ --> $DIR/option_as_ref_deref.rs:33:13
|
LL | let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.clone().as_deref_mut()`
error: called `.as_ref().map(|x| &**x)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:42:13
+ --> $DIR/option_as_ref_deref.rs:40:13
|
LL | let _ = opt.as_ref().map(|x| &**x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
error: called `.as_mut().map(|x| &mut **x)` on an Option value. This can be done more directly by calling `opt.as_deref_mut()` instead
- --> $DIR/option_as_ref_deref.rs:43:13
+ --> $DIR/option_as_ref_deref.rs:41:13
|
LL | let _ = opt.as_mut().map(|x| &mut **x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
error: called `.as_ref().map(std::ops::Deref::deref)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:46:13
+ --> $DIR/option_as_ref_deref.rs:44:13
|
LL | let _ = opt.as_ref().map(std::ops::Deref::deref);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
error: called `.as_ref().map(String::as_str)` on an Option value. This can be done more directly by calling `opt.as_deref()` instead
- --> $DIR/option_as_ref_deref.rs:58:13
+ --> $DIR/option_as_ref_deref.rs:56:13
|
LL | let _ = opt.as_ref().map(String::as_str);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
diff --git a/src/tools/clippy/tests/ui/option_env_unwrap.rs b/src/tools/clippy/tests/ui/option_env_unwrap.rs
index 61dbad939..f8d382340 100644
--- a/src/tools/clippy/tests/ui/option_env_unwrap.rs
+++ b/src/tools/clippy/tests/ui/option_env_unwrap.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::option_env_unwrap)]
#![allow(clippy::map_flatten)]
diff --git a/src/tools/clippy/tests/ui/option_env_unwrap.stderr b/src/tools/clippy/tests/ui/option_env_unwrap.stderr
index cfa9dd58a..de31d0c7f 100644
--- a/src/tools/clippy/tests/ui/option_env_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/option_env_unwrap.stderr
@@ -6,6 +6,7 @@ LL | let _ = option_env!("PATH").unwrap();
|
= help: consider using the `env!` macro instead
= note: `-D clippy::option-env-unwrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::option_env_unwrap)]`
error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> $DIR/option_env_unwrap.rs:11:13
diff --git a/src/tools/clippy/tests/ui/option_filter_map.fixed b/src/tools/clippy/tests/ui/option_filter_map.fixed
index 93c250cfa..ee004c0e1 100644
--- a/src/tools/clippy/tests/ui/option_filter_map.fixed
+++ b/src/tools/clippy/tests/ui/option_filter_map.fixed
@@ -1,6 +1,5 @@
-//@run-rustfix
#![warn(clippy::option_filter_map)]
-#![allow(clippy::map_flatten)]
+#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]
fn main() {
let _ = Some(Some(1)).flatten();
diff --git a/src/tools/clippy/tests/ui/option_filter_map.rs b/src/tools/clippy/tests/ui/option_filter_map.rs
index 2c5f03250..eae2fa176 100644
--- a/src/tools/clippy/tests/ui/option_filter_map.rs
+++ b/src/tools/clippy/tests/ui/option_filter_map.rs
@@ -1,6 +1,5 @@
-//@run-rustfix
#![warn(clippy::option_filter_map)]
-#![allow(clippy::map_flatten)]
+#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]
fn main() {
let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap);
diff --git a/src/tools/clippy/tests/ui/option_filter_map.stderr b/src/tools/clippy/tests/ui/option_filter_map.stderr
index 4a030ac9a..148f9d02f 100644
--- a/src/tools/clippy/tests/ui/option_filter_map.stderr
+++ b/src/tools/clippy/tests/ui/option_filter_map.stderr
@@ -1,43 +1,44 @@
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:6:27
+ --> $DIR/option_filter_map.rs:5:27
|
LL | let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`
|
= note: `-D clippy::option-filter-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::option_filter_map)]`
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:7:27
+ --> $DIR/option_filter_map.rs:6:27
|
LL | let _ = Some(Some(1)).filter(|o| o.is_some()).map(|o| o.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:8:35
+ --> $DIR/option_filter_map.rs:7:35
|
LL | let _ = Some(1).map(odds_out).filter(Option::is_some).map(Option::unwrap);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:9:35
+ --> $DIR/option_filter_map.rs:8:35
|
LL | let _ = Some(1).map(odds_out).filter(|o| o.is_some()).map(|o| o.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:11:39
+ --> $DIR/option_filter_map.rs:10:39
|
LL | let _ = vec![Some(1)].into_iter().filter(Option::is_some).map(Option::unwrap);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:12:39
+ --> $DIR/option_filter_map.rs:11:39
|
LL | let _ = vec![Some(1)].into_iter().filter(|o| o.is_some()).map(|o| o.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:16:10
+ --> $DIR/option_filter_map.rs:15:10
|
LL | .filter(Option::is_some)
| __________^
@@ -45,7 +46,7 @@ LL | | .map(Option::unwrap);
| |____________________________^ help: consider using `flatten` instead: `flatten()`
error: `filter` for `Some` followed by `unwrap`
- --> $DIR/option_filter_map.rs:21:10
+ --> $DIR/option_filter_map.rs:20:10
|
LL | .filter(|o| o.is_some())
| __________^
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index 6fee3cce6..c3415a7df 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::option_if_let_else)]
#![allow(
unused_tuple_struct_fields,
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs
index 4b3cf948a..86537f620 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::option_if_let_else)]
#![allow(
unused_tuple_struct_fields,
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr
index 350f0f07e..6d7d02f8c 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.stderr
+++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr
@@ -1,5 +1,5 @@
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:13:5
+ --> $DIR/option_if_let_else.rs:12:5
|
LL | / if let Some(x) = string {
LL | | (true, x)
@@ -9,21 +9,22 @@ LL | | }
| |_____^ help: try: `string.map_or((false, "hello"), |x| (true, x))`
|
= note: `-D clippy::option-if-let-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:31:13
+ --> $DIR/option_if_let_else.rs:30:13
|
LL | let _ = if let Some(s) = *string { s.len() } else { 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:32:13
+ --> $DIR/option_if_let_else.rs:31:13
|
LL | let _ = if let Some(s) = &num { s } else { &0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:33:13
+ --> $DIR/option_if_let_else.rs:32:13
|
LL | let _ = if let Some(s) = &mut num {
| _____________^
@@ -43,13 +44,13 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:39:13
+ --> $DIR/option_if_let_else.rs:38:13
|
LL | let _ = if let Some(ref s) = num { s } else { &0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:40:13
+ --> $DIR/option_if_let_else.rs:39:13
|
LL | let _ = if let Some(mut s) = num {
| _____________^
@@ -69,7 +70,7 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:46:13
+ --> $DIR/option_if_let_else.rs:45:13
|
LL | let _ = if let Some(ref mut s) = num {
| _____________^
@@ -89,7 +90,7 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:55:5
+ --> $DIR/option_if_let_else.rs:54:5
|
LL | / if let Some(x) = arg {
LL | | let y = x * x;
@@ -108,7 +109,7 @@ LL + })
|
error: use Option::map_or_else instead of an if let/else
- --> $DIR/option_if_let_else.rs:68:13
+ --> $DIR/option_if_let_else.rs:67:13
|
LL | let _ = if let Some(x) = arg {
| _____________^
@@ -120,7 +121,7 @@ LL | | };
| |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
error: use Option::map_or_else instead of an if let/else
- --> $DIR/option_if_let_else.rs:77:13
+ --> $DIR/option_if_let_else.rs:76:13
|
LL | let _ = if let Some(x) = arg {
| _____________^
@@ -143,7 +144,7 @@ LL ~ }, |x| x * x * x * x);
|
error: use Option::map_or_else instead of an if let/else
- --> $DIR/option_if_let_else.rs:110:13
+ --> $DIR/option_if_let_else.rs:109:13
|
LL | / if let Some(idx) = s.find('.') {
LL | | vec![s[..idx].to_string(), s[idx..].to_string()]
@@ -153,7 +154,7 @@ LL | | }
| |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
error: use Option::map_or_else instead of an if let/else
- --> $DIR/option_if_let_else.rs:121:5
+ --> $DIR/option_if_let_else.rs:120:5
|
LL | / if let Ok(binding) = variable {
LL | | println!("Ok {binding}");
@@ -172,13 +173,13 @@ LL + })
|
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:143:13
+ --> $DIR/option_if_let_else.rs:142:13
|
LL | let _ = if let Some(x) = optional { x + 2 } else { 5 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:153:13
+ --> $DIR/option_if_let_else.rs:152:13
|
LL | let _ = if let Some(x) = Some(0) {
| _____________^
@@ -200,13 +201,13 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:181:13
+ --> $DIR/option_if_let_else.rs:180:13
|
LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:185:13
+ --> $DIR/option_if_let_else.rs:184:13
|
LL | let _ = if let Some(x) = Some(0) {
| _____________^
@@ -226,7 +227,7 @@ LL ~ });
|
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:224:13
+ --> $DIR/option_if_let_else.rs:223:13
|
LL | let _ = match s {
| _____________^
@@ -236,7 +237,7 @@ LL | | };
| |_____^ help: try: `s.map_or(1, |string| string.len())`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:228:13
+ --> $DIR/option_if_let_else.rs:227:13
|
LL | let _ = match Some(10) {
| _____________^
@@ -246,7 +247,7 @@ LL | | };
| |_____^ help: try: `Some(10).map_or(5, |a| a + 1)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:234:13
+ --> $DIR/option_if_let_else.rs:233:13
|
LL | let _ = match res {
| _____________^
@@ -256,7 +257,7 @@ LL | | };
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:238:13
+ --> $DIR/option_if_let_else.rs:237:13
|
LL | let _ = match res {
| _____________^
@@ -266,13 +267,13 @@ LL | | };
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:242:13
+ --> $DIR/option_if_let_else.rs:241:13
|
LL | let _ = if let Ok(a) = res { a + 1 } else { 5 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:259:9
+ --> $DIR/option_if_let_else.rs:258:9
|
LL | / match initial {
LL | | Some(value) => do_something(value),
@@ -281,7 +282,7 @@ LL | | }
| |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))`
error: use Option::map_or instead of an if let/else
- --> $DIR/option_if_let_else.rs:266:9
+ --> $DIR/option_if_let_else.rs:265:9
|
LL | / match initial {
LL | | Some(value) => do_something2(value),
diff --git a/src/tools/clippy/tests/ui/option_map_or_none.fixed b/src/tools/clippy/tests/ui/option_map_or_none.fixed
index 501757647..5f0ef34d2 100644
--- a/src/tools/clippy/tests/ui/option_map_or_none.fixed
+++ b/src/tools/clippy/tests/ui/option_map_or_none.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::bind_instead_of_map)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/option_map_or_none.rs b/src/tools/clippy/tests/ui/option_map_or_none.rs
index 4d8704e73..56b1f6121 100644
--- a/src/tools/clippy/tests/ui/option_map_or_none.rs
+++ b/src/tools/clippy/tests/ui/option_map_or_none.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::bind_instead_of_map)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/option_map_or_none.stderr b/src/tools/clippy/tests/ui/option_map_or_none.stderr
index 7befcb890..fa150718f 100644
--- a/src/tools/clippy/tests/ui/option_map_or_none.stderr
+++ b/src/tools/clippy/tests/ui/option_map_or_none.stderr
@@ -1,13 +1,14 @@
error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `map(..)` instead
- --> $DIR/option_map_or_none.rs:12:26
+ --> $DIR/option_map_or_none.rs:10:26
|
LL | let _: Option<i32> = opt.map_or(None, |x| Some(x + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `map` instead: `opt.map(|x| x + 1)`
|
= note: `-D clippy::option-map-or-none` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::option_map_or_none)]`
error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `map(..)` instead
- --> $DIR/option_map_or_none.rs:15:26
+ --> $DIR/option_map_or_none.rs:13:26
|
LL | let _: Option<i32> = opt.map_or(None, |x| {
| __________________________^
@@ -16,13 +17,13 @@ LL | | });
| |_________________________^ help: try using `map` instead: `opt.map(|x| x + 1)`
error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `and_then(..)` instead
- --> $DIR/option_map_or_none.rs:19:26
+ --> $DIR/option_map_or_none.rs:17:26
|
LL | let _: Option<i32> = opt.map_or(None, bar);
| ^^^^^^^^^^^^^^^^^^^^^ help: try using `and_then` instead: `opt.and_then(bar)`
error: called `map_or(None, ..)` on an `Option` value. This can be done more directly by calling `and_then(..)` instead
- --> $DIR/option_map_or_none.rs:20:26
+ --> $DIR/option_map_or_none.rs:18:26
|
LL | let _: Option<i32> = opt.map_or(None, |x| {
| __________________________^
@@ -42,12 +43,13 @@ LL ~ });
|
error: called `map_or(None, Some)` on a `Result` value. This can be done more directly by calling `ok()` instead
- --> $DIR/option_map_or_none.rs:27:26
+ --> $DIR/option_map_or_none.rs:25:26
|
LL | let _: Option<i32> = r.map_or(None, Some);
| ^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `r.ok()`
|
= note: `-D clippy::result-map-or-into-option` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`
error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
index 8f64451ed..5dcc6464f 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::option_map_unit_fn)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)]
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
index 2bf7a8e0f..5489545fe 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::option_map_unit_fn)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)]
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
index 5be5f10b0..34aca31e9 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
@@ -1,5 +1,5 @@
error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:38:5
+ --> $DIR/option_map_unit_fn_fixable.rs:37:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
@@ -7,9 +7,10 @@ LL | x.field.map(do_nothing);
| help: try: `if let Some(x_field) = x.field { do_nothing(x_field) }`
|
= note: `-D clippy::option-map-unit-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::option_map_unit_fn)]`
error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:40:5
+ --> $DIR/option_map_unit_fn_fixable.rs:39:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
@@ -17,7 +18,7 @@ LL | x.field.map(do_nothing);
| help: try: `if let Some(x_field) = x.field { do_nothing(x_field) }`
error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:42:5
+ --> $DIR/option_map_unit_fn_fixable.rs:41:5
|
LL | x.field.map(diverge);
| ^^^^^^^^^^^^^^^^^^^^-
@@ -25,7 +26,7 @@ LL | x.field.map(diverge);
| help: try: `if let Some(x_field) = x.field { diverge(x_field) }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:48:5
+ --> $DIR/option_map_unit_fn_fixable.rs:47:5
|
LL | x.field.map(|value| x.do_option_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -33,7 +34,7 @@ LL | x.field.map(|value| x.do_option_nothing(value + captured));
| help: try: `if let Some(value) = x.field { x.do_option_nothing(value + captured) }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:50:5
+ --> $DIR/option_map_unit_fn_fixable.rs:49:5
|
LL | x.field.map(|value| { x.do_option_plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -41,7 +42,7 @@ LL | x.field.map(|value| { x.do_option_plus_one(value + captured); });
| help: try: `if let Some(value) = x.field { x.do_option_plus_one(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:53:5
+ --> $DIR/option_map_unit_fn_fixable.rs:52:5
|
LL | x.field.map(|value| do_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -49,7 +50,7 @@ LL | x.field.map(|value| do_nothing(value + captured));
| help: try: `if let Some(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:55:5
+ --> $DIR/option_map_unit_fn_fixable.rs:54:5
|
LL | x.field.map(|value| { do_nothing(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -57,7 +58,7 @@ LL | x.field.map(|value| { do_nothing(value + captured) });
| help: try: `if let Some(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:57:5
+ --> $DIR/option_map_unit_fn_fixable.rs:56:5
|
LL | x.field.map(|value| { do_nothing(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -65,7 +66,7 @@ LL | x.field.map(|value| { do_nothing(value + captured); });
| help: try: `if let Some(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:59:5
+ --> $DIR/option_map_unit_fn_fixable.rs:58:5
|
LL | x.field.map(|value| { { do_nothing(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -73,7 +74,7 @@ LL | x.field.map(|value| { { do_nothing(value + captured); } });
| help: try: `if let Some(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:62:5
+ --> $DIR/option_map_unit_fn_fixable.rs:61:5
|
LL | x.field.map(|value| diverge(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -81,7 +82,7 @@ LL | x.field.map(|value| diverge(value + captured));
| help: try: `if let Some(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:64:5
+ --> $DIR/option_map_unit_fn_fixable.rs:63:5
|
LL | x.field.map(|value| { diverge(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -89,7 +90,7 @@ LL | x.field.map(|value| { diverge(value + captured) });
| help: try: `if let Some(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:66:5
+ --> $DIR/option_map_unit_fn_fixable.rs:65:5
|
LL | x.field.map(|value| { diverge(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -97,7 +98,7 @@ LL | x.field.map(|value| { diverge(value + captured); });
| help: try: `if let Some(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:68:5
+ --> $DIR/option_map_unit_fn_fixable.rs:67:5
|
LL | x.field.map(|value| { { diverge(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -105,7 +106,7 @@ LL | x.field.map(|value| { { diverge(value + captured); } });
| help: try: `if let Some(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:73:5
+ --> $DIR/option_map_unit_fn_fixable.rs:72:5
|
LL | x.field.map(|value| { let y = plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -113,7 +114,7 @@ LL | x.field.map(|value| { let y = plus_one(value + captured); });
| help: try: `if let Some(value) = x.field { let y = plus_one(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:75:5
+ --> $DIR/option_map_unit_fn_fixable.rs:74:5
|
LL | x.field.map(|value| { plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -121,7 +122,7 @@ LL | x.field.map(|value| { plus_one(value + captured); });
| help: try: `if let Some(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:77:5
+ --> $DIR/option_map_unit_fn_fixable.rs:76:5
|
LL | x.field.map(|value| { { plus_one(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -129,7 +130,7 @@ LL | x.field.map(|value| { { plus_one(value + captured); } });
| help: try: `if let Some(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:80:5
+ --> $DIR/option_map_unit_fn_fixable.rs:79:5
|
LL | x.field.map(|ref value| { do_nothing(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -137,7 +138,7 @@ LL | x.field.map(|ref value| { do_nothing(value + captured) });
| help: try: `if let Some(ref value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:82:5
+ --> $DIR/option_map_unit_fn_fixable.rs:81:5
|
LL | option().map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -145,7 +146,7 @@ LL | option().map(do_nothing);
| help: try: `if let Some(a) = option() { do_nothing(a) }`
error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
- --> $DIR/option_map_unit_fn_fixable.rs:84:5
+ --> $DIR/option_map_unit_fn_fixable.rs:83:5
|
LL | option().map(|value| println!("{:?}", value));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
diff --git a/src/tools/clippy/tests/ui/option_option.rs b/src/tools/clippy/tests/ui/option_option.rs
index 2faab9e03..9bbdd3aaa 100644
--- a/src/tools/clippy/tests/ui/option_option.rs
+++ b/src/tools/clippy/tests/ui/option_option.rs
@@ -2,40 +2,51 @@
#![allow(clippy::unnecessary_wraps)]
const C: Option<Option<i32>> = None;
+//~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if
static S: Option<Option<i32>> = None;
+//~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if
fn input(_: Option<Option<u8>>) {}
+//~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if
fn output() -> Option<Option<u8>> {
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if
None
}
fn output_nested() -> Vec<Option<Option<u8>>> {
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if
vec![None]
}
// The lint only generates one warning for this
fn output_nested_nested() -> Option<Option<Option<u8>>> {
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if
None
}
struct Struct {
x: Option<Option<u8>>,
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum
}
impl Struct {
fn struct_fn() -> Option<Option<u8>> {
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum
None
}
}
trait Trait {
fn trait_fn() -> Option<Option<u8>>;
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum
}
enum Enum {
Tuple(Option<Option<u8>>),
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum
Struct { x: Option<Option<u8>> },
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum
}
// The lint allows this
@@ -77,6 +88,7 @@ mod issue_4298 {
#[serde(default)]
#[serde(borrow)]
foo: Option<Option<Cow<'a, str>>>,
+ //~^ ERROR: consider using `Option<T>` instead of `Option<Option<T>>` or a custom
}
#[allow(clippy::option_option)]
diff --git a/src/tools/clippy/tests/ui/option_option.stderr b/src/tools/clippy/tests/ui/option_option.stderr
index a925bb35b..fcae9655d 100644
--- a/src/tools/clippy/tests/ui/option_option.stderr
+++ b/src/tools/clippy/tests/ui/option_option.stderr
@@ -11,67 +11,67 @@ LL | #![deny(clippy::option_option)]
| ^^^^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:5:11
+ --> $DIR/option_option.rs:6:11
|
LL | static S: Option<Option<i32>> = None;
| ^^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:7:13
+ --> $DIR/option_option.rs:9:13
|
LL | fn input(_: Option<Option<u8>>) {}
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:9:16
+ --> $DIR/option_option.rs:12:16
|
LL | fn output() -> Option<Option<u8>> {
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:13:27
+ --> $DIR/option_option.rs:17:27
|
LL | fn output_nested() -> Vec<Option<Option<u8>>> {
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:18:30
+ --> $DIR/option_option.rs:23:30
|
LL | fn output_nested_nested() -> Option<Option<Option<u8>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:23:8
+ --> $DIR/option_option.rs:29:8
|
LL | x: Option<Option<u8>>,
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:27:23
+ --> $DIR/option_option.rs:34:23
|
LL | fn struct_fn() -> Option<Option<u8>> {
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:33:22
+ --> $DIR/option_option.rs:41:22
|
LL | fn trait_fn() -> Option<Option<u8>>;
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:37:11
+ --> $DIR/option_option.rs:46:11
|
LL | Tuple(Option<Option<u8>>),
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:38:17
+ --> $DIR/option_option.rs:48:17
|
LL | Struct { x: Option<Option<u8>> },
| ^^^^^^^^^^^^^^^^^^
error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
- --> $DIR/option_option.rs:79:14
+ --> $DIR/option_option.rs:90:14
|
LL | foo: Option<Option<Cow<'a, str>>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index 581f3ad45..e7ba54864 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::or_fun_call)]
#![allow(dead_code)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs
index 1f3987eb8..196632133 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.rs
+++ b/src/tools/clippy/tests/ui/or_fun_call.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::or_fun_call)]
#![allow(dead_code)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index 519f09165..afa4b7628 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -1,189 +1,191 @@
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:53:22
+ --> $DIR/or_fun_call.rs:52:22
|
LL | with_constructor.unwrap_or(make());
| ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(make)`
|
= note: `-D clippy::or-fun-call` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]`
error: use of `unwrap_or` to construct default value
- --> $DIR/or_fun_call.rs:56:14
+ --> $DIR/or_fun_call.rs:55:14
|
LL | with_new.unwrap_or(Vec::new());
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
= note: `-D clippy::unwrap-or-default` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:59:21
+ --> $DIR/or_fun_call.rs:58:21
|
LL | with_const_args.unwrap_or(Vec::with_capacity(12));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Vec::with_capacity(12))`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:62:14
+ --> $DIR/or_fun_call.rs:61:14
|
LL | with_err.unwrap_or(make());
| ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| make())`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:65:19
+ --> $DIR/or_fun_call.rs:64:19
|
LL | with_err_args.unwrap_or(Vec::with_capacity(12));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Vec::with_capacity(12))`
error: use of `unwrap_or` to construct default value
- --> $DIR/or_fun_call.rs:68:24
+ --> $DIR/or_fun_call.rs:67:24
|
LL | with_default_trait.unwrap_or(Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or` to construct default value
- --> $DIR/or_fun_call.rs:71:23
+ --> $DIR/or_fun_call.rs:70:23
|
LL | with_default_type.unwrap_or(u64::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:74:18
+ --> $DIR/or_fun_call.rs:73:18
|
LL | self_default.unwrap_or(<FakeDefault>::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(<FakeDefault>::default)`
error: use of `unwrap_or` to construct default value
- --> $DIR/or_fun_call.rs:77:18
+ --> $DIR/or_fun_call.rs:76:18
|
LL | real_default.unwrap_or(<FakeDefault as Default>::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or` to construct default value
- --> $DIR/or_fun_call.rs:80:14
+ --> $DIR/or_fun_call.rs:79:14
|
LL | with_vec.unwrap_or(vec![]);
| ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:83:21
+ --> $DIR/or_fun_call.rs:82:21
|
LL | without_default.unwrap_or(Foo::new());
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(Foo::new)`
error: use of `or_insert` to construct default value
- --> $DIR/or_fun_call.rs:86:19
+ --> $DIR/or_fun_call.rs:85:19
|
LL | map.entry(42).or_insert(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `or_insert` to construct default value
- --> $DIR/or_fun_call.rs:89:23
+ --> $DIR/or_fun_call.rs:88:23
|
LL | map_vec.entry(42).or_insert(vec![]);
| ^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `or_insert` to construct default value
- --> $DIR/or_fun_call.rs:92:21
+ --> $DIR/or_fun_call.rs:91:21
|
LL | btree.entry(42).or_insert(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `or_insert` to construct default value
- --> $DIR/or_fun_call.rs:95:25
+ --> $DIR/or_fun_call.rs:94:25
|
LL | btree_vec.entry(42).or_insert(vec![]);
| ^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `unwrap_or` to construct default value
- --> $DIR/or_fun_call.rs:98:21
+ --> $DIR/or_fun_call.rs:97:21
|
LL | let _ = stringy.unwrap_or(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:106:21
+ --> $DIR/or_fun_call.rs:105:21
|
LL | let _ = Some(1).unwrap_or(map[&1]);
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:108:21
+ --> $DIR/or_fun_call.rs:107:21
|
LL | let _ = Some(1).unwrap_or(map[&1]);
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])`
error: use of `or` followed by a function call
- --> $DIR/or_fun_call.rs:132:35
+ --> $DIR/or_fun_call.rs:131:35
|
LL | let _ = Some("a".to_string()).or(Some("b".to_string()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_else(|| Some("b".to_string()))`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:171:14
+ --> $DIR/or_fun_call.rs:170:14
|
LL | None.unwrap_or(ptr_to_ref(s));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| ptr_to_ref(s))`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:177:14
+ --> $DIR/or_fun_call.rs:176:14
|
LL | None.unwrap_or(unsafe { ptr_to_ref(s) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })`
error: use of `unwrap_or` followed by a function call
- --> $DIR/or_fun_call.rs:179:14
+ --> $DIR/or_fun_call.rs:178:14
|
LL | None.unwrap_or( unsafe { ptr_to_ref(s) } );
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })`
error: use of `map_or` followed by a function call
- --> $DIR/or_fun_call.rs:254:25
+ --> $DIR/or_fun_call.rs:253:25
|
LL | let _ = Some(4).map_or(g(), |v| v);
| ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(g, |v| v)`
error: use of `map_or` followed by a function call
- --> $DIR/or_fun_call.rs:255:25
+ --> $DIR/or_fun_call.rs:254:25
|
LL | let _ = Some(4).map_or(g(), f);
| ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/or_fun_call.rs:286:18
+ --> $DIR/or_fun_call.rs:285:18
|
LL | with_new.unwrap_or_else(Vec::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/or_fun_call.rs:289:28
+ --> $DIR/or_fun_call.rs:288:28
|
LL | with_default_trait.unwrap_or_else(Default::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/or_fun_call.rs:292:27
+ --> $DIR/or_fun_call.rs:291:27
|
LL | with_default_type.unwrap_or_else(u64::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/or_fun_call.rs:295:22
+ --> $DIR/or_fun_call.rs:294:22
|
LL | real_default.unwrap_or_else(<FakeDefault as Default>::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `or_insert_with` to construct default value
- --> $DIR/or_fun_call.rs:298:23
+ --> $DIR/or_fun_call.rs:297:23
|
LL | map.entry(42).or_insert_with(String::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `or_insert_with` to construct default value
- --> $DIR/or_fun_call.rs:301:25
+ --> $DIR/or_fun_call.rs:300:25
|
LL | btree.entry(42).or_insert_with(String::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/or_fun_call.rs:304:25
+ --> $DIR/or_fun_call.rs:303:25
|
LL | let _ = stringy.unwrap_or_else(String::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.fixed b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
index 773dfc3c5..c94478614 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::or_then_unwrap)]
#![allow(clippy::map_identity, clippy::let_unit_value, clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.rs b/src/tools/clippy/tests/ui/or_then_unwrap.rs
index 5867e0148..10e43e1d1 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.rs
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::or_then_unwrap)]
#![allow(clippy::map_identity, clippy::let_unit_value, clippy::unnecessary_literal_unwrap)]
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.stderr b/src/tools/clippy/tests/ui/or_then_unwrap.stderr
index 2a1a52407..99e4488c0 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.stderr
@@ -1,19 +1,20 @@
error: found `.or(Some(…)).unwrap()`
- --> $DIR/or_then_unwrap.rs:24:20
+ --> $DIR/or_then_unwrap.rs:22:20
|
LL | let _ = option.or(Some("fallback")).unwrap(); // should trigger lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")`
|
= note: `-D clippy::or-then-unwrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::or_then_unwrap)]`
error: found `.or(Ok(…)).unwrap()`
- --> $DIR/or_then_unwrap.rs:27:20
+ --> $DIR/or_then_unwrap.rs:25:20
|
LL | let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")`
error: found `.or(Some(…)).unwrap()`
- --> $DIR/or_then_unwrap.rs:31:31
+ --> $DIR/or_then_unwrap.rs:29:31
|
LL | let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")`
diff --git a/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.rs b/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.rs
index edd2123d4..81674653b 100644
--- a/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.rs
+++ b/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.rs
@@ -6,6 +6,9 @@ fn main() {
// issue 3102
let num = 1;
- &x[num..10]; // should trigger out of bounds error
- &x[10..num]; // should trigger out of bounds error
+ &x[num..10];
+ //~^ ERROR: range is out of bounds
+ //~| NOTE: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`
+ &x[10..num];
+ //~^ ERROR: range is out of bounds
}
diff --git a/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.stderr b/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.stderr
index 516c1df40..37db11caa 100644
--- a/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.stderr
+++ b/src/tools/clippy/tests/ui/out_of_bounds_indexing/issue-3102.stderr
@@ -1,15 +1,16 @@
error: range is out of bounds
--> $DIR/issue-3102.rs:9:13
|
-LL | &x[num..10]; // should trigger out of bounds error
+LL | &x[num..10];
| ^^
|
= note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
error: range is out of bounds
- --> $DIR/issue-3102.rs:10:8
+ --> $DIR/issue-3102.rs:12:8
|
-LL | &x[10..num]; // should trigger out of bounds error
+LL | &x[10..num];
| ^^
error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.rs b/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.rs
index 4c541c23f..c38ca5123 100644
--- a/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.rs
+++ b/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.rs
@@ -5,11 +5,18 @@ fn main() {
let x = [1, 2, 3, 4];
&x[..=4];
+ //~^ ERROR: range is out of bounds
+ //~| NOTE: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`
&x[1..5];
+ //~^ ERROR: range is out of bounds
&x[5..];
+ //~^ ERROR: range is out of bounds
&x[..5];
+ //~^ ERROR: range is out of bounds
&x[5..].iter().map(|x| 2 * x).collect::<Vec<i32>>();
+ //~^ ERROR: range is out of bounds
&x[0..=4];
+ //~^ ERROR: range is out of bounds
&x[4..]; // Ok, should not produce stderr.
&x[..4]; // Ok, should not produce stderr.
diff --git a/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.stderr b/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.stderr
index 3d95afcda..ddef38beb 100644
--- a/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.stderr
+++ b/src/tools/clippy/tests/ui/out_of_bounds_indexing/simple.stderr
@@ -5,33 +5,34 @@ LL | &x[..=4];
| ^
|
= note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
error: range is out of bounds
- --> $DIR/simple.rs:8:11
+ --> $DIR/simple.rs:10:11
|
LL | &x[1..5];
| ^
error: range is out of bounds
- --> $DIR/simple.rs:9:8
+ --> $DIR/simple.rs:12:8
|
LL | &x[5..];
| ^
error: range is out of bounds
- --> $DIR/simple.rs:10:10
+ --> $DIR/simple.rs:14:10
|
LL | &x[..5];
| ^
error: range is out of bounds
- --> $DIR/simple.rs:11:8
+ --> $DIR/simple.rs:16:8
|
LL | &x[5..].iter().map(|x| 2 * x).collect::<Vec<i32>>();
| ^
error: range is out of bounds
- --> $DIR/simple.rs:12:12
+ --> $DIR/simple.rs:18:12
|
LL | &x[0..=4];
| ^
diff --git a/src/tools/clippy/tests/ui/overflow_check_conditional.rs b/src/tools/clippy/tests/ui/overflow_check_conditional.rs
index 14a6b98d0..a70bb3bc4 100644
--- a/src/tools/clippy/tests/ui/overflow_check_conditional.rs
+++ b/src/tools/clippy/tests/ui/overflow_check_conditional.rs
@@ -3,13 +3,22 @@
fn test(a: u32, b: u32, c: u32) {
if a + b < a {}
+ //~^ ERROR: you are trying to use classic C overflow conditions that will fail in Rust
+ //~| NOTE: `-D clippy::overflow-check-conditional` implied by `-D warnings`
if a > a + b {}
+ //~^ ERROR: you are trying to use classic C overflow conditions that will fail in Rust
if a + b < b {}
+ //~^ ERROR: you are trying to use classic C overflow conditions that will fail in Rust
if b > a + b {}
+ //~^ ERROR: you are trying to use classic C overflow conditions that will fail in Rust
if a - b > b {}
+ //~^ ERROR: you are trying to use classic C underflow conditions that will fail in Rus
if b < a - b {}
+ //~^ ERROR: you are trying to use classic C underflow conditions that will fail in Rus
if a - b > a {}
+ //~^ ERROR: you are trying to use classic C underflow conditions that will fail in Rus
if a < a - b {}
+ //~^ ERROR: you are trying to use classic C underflow conditions that will fail in Rus
if a + b < c {}
if c > a + b {}
if a - b < c {}
diff --git a/src/tools/clippy/tests/ui/overflow_check_conditional.stderr b/src/tools/clippy/tests/ui/overflow_check_conditional.stderr
index 3ec2298f8..b3cab8a21 100644
--- a/src/tools/clippy/tests/ui/overflow_check_conditional.stderr
+++ b/src/tools/clippy/tests/ui/overflow_check_conditional.stderr
@@ -5,45 +5,46 @@ LL | if a + b < a {}
| ^^^^^^^^^
|
= note: `-D clippy::overflow-check-conditional` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::overflow_check_conditional)]`
error: you are trying to use classic C overflow conditions that will fail in Rust
- --> $DIR/overflow_check_conditional.rs:6:8
+ --> $DIR/overflow_check_conditional.rs:8:8
|
LL | if a > a + b {}
| ^^^^^^^^^
error: you are trying to use classic C overflow conditions that will fail in Rust
- --> $DIR/overflow_check_conditional.rs:7:8
+ --> $DIR/overflow_check_conditional.rs:10:8
|
LL | if a + b < b {}
| ^^^^^^^^^
error: you are trying to use classic C overflow conditions that will fail in Rust
- --> $DIR/overflow_check_conditional.rs:8:8
+ --> $DIR/overflow_check_conditional.rs:12:8
|
LL | if b > a + b {}
| ^^^^^^^^^
error: you are trying to use classic C underflow conditions that will fail in Rust
- --> $DIR/overflow_check_conditional.rs:9:8
+ --> $DIR/overflow_check_conditional.rs:14:8
|
LL | if a - b > b {}
| ^^^^^^^^^
error: you are trying to use classic C underflow conditions that will fail in Rust
- --> $DIR/overflow_check_conditional.rs:10:8
+ --> $DIR/overflow_check_conditional.rs:16:8
|
LL | if b < a - b {}
| ^^^^^^^^^
error: you are trying to use classic C underflow conditions that will fail in Rust
- --> $DIR/overflow_check_conditional.rs:11:8
+ --> $DIR/overflow_check_conditional.rs:18:8
|
LL | if a - b > a {}
| ^^^^^^^^^
error: you are trying to use classic C underflow conditions that will fail in Rust
- --> $DIR/overflow_check_conditional.rs:12:8
+ --> $DIR/overflow_check_conditional.rs:20:8
|
LL | if a < a - b {}
| ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/overly_complex_bool_expr.fixed b/src/tools/clippy/tests/ui/overly_complex_bool_expr.fixed
new file mode 100644
index 000000000..e44f60631
--- /dev/null
+++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.fixed
@@ -0,0 +1,39 @@
+#![feature(lint_reasons)]
+#![allow(unused, clippy::diverging_sub_expression)]
+#![warn(clippy::overly_complex_bool_expr)]
+
+fn main() {
+ let a: bool = unimplemented!();
+ let b: bool = unimplemented!();
+ let c: bool = unimplemented!();
+ let d: bool = unimplemented!();
+ let e: bool = unimplemented!();
+ let _ = a;
+ //~^ ERROR: this boolean expression contains a logic bug
+ let _ = !(a && b);
+ let _ = false;
+ //~^ ERROR: this boolean expression contains a logic bug
+ // don't lint on cfgs
+ let _ = cfg!(you_shall_not_not_pass) && a;
+ let _ = a || !b || !c || !d || !e;
+ let _ = !(a && b || c);
+}
+
+fn equality_stuff() {
+ let a: i32 = unimplemented!();
+ let b: i32 = unimplemented!();
+ let _ = false;
+ //~^ ERROR: this boolean expression contains a logic bug
+ let _ = false;
+ //~^ ERROR: this boolean expression contains a logic bug
+ let _ = false;
+ //~^ ERROR: this boolean expression contains a logic bug
+ let _ = a > b && a == b;
+}
+
+fn check_expect() {
+ let a: i32 = unimplemented!();
+ let b: i32 = unimplemented!();
+ #[expect(clippy::overly_complex_bool_expr)]
+ let _ = a < b && a >= b;
+}
diff --git a/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs b/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs
index 04a30a832..f010a8537 100644
--- a/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs
+++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.rs
@@ -9,8 +9,10 @@ fn main() {
let d: bool = unimplemented!();
let e: bool = unimplemented!();
let _ = a && b || a;
+ //~^ ERROR: this boolean expression contains a logic bug
let _ = !(a && b);
let _ = false && a;
+ //~^ ERROR: this boolean expression contains a logic bug
// don't lint on cfgs
let _ = cfg!(you_shall_not_not_pass) && a;
let _ = a || !b || !c || !d || !e;
@@ -21,8 +23,11 @@ fn equality_stuff() {
let a: i32 = unimplemented!();
let b: i32 = unimplemented!();
let _ = a == b && a != b;
+ //~^ ERROR: this boolean expression contains a logic bug
let _ = a < b && a >= b;
+ //~^ ERROR: this boolean expression contains a logic bug
let _ = a > b && a <= b;
+ //~^ ERROR: this boolean expression contains a logic bug
let _ = a > b && a == b;
}
diff --git a/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
index e989f2ece..dc62d0e1d 100644
--- a/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
+++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
@@ -10,51 +10,52 @@ help: this expression can be optimized out by applying boolean operations to the
LL | let _ = a && b || a;
| ^
= note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::overly_complex_bool_expr)]`
error: this boolean expression contains a logic bug
- --> $DIR/overly_complex_bool_expr.rs:13:13
+ --> $DIR/overly_complex_bool_expr.rs:14:13
|
LL | let _ = false && a;
| ^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/overly_complex_bool_expr.rs:13:22
+ --> $DIR/overly_complex_bool_expr.rs:14:22
|
LL | let _ = false && a;
| ^
error: this boolean expression contains a logic bug
- --> $DIR/overly_complex_bool_expr.rs:23:13
+ --> $DIR/overly_complex_bool_expr.rs:25:13
|
LL | let _ = a == b && a != b;
| ^^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/overly_complex_bool_expr.rs:23:13
+ --> $DIR/overly_complex_bool_expr.rs:25:13
|
LL | let _ = a == b && a != b;
| ^^^^^^
error: this boolean expression contains a logic bug
- --> $DIR/overly_complex_bool_expr.rs:24:13
+ --> $DIR/overly_complex_bool_expr.rs:27:13
|
LL | let _ = a < b && a >= b;
| ^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/overly_complex_bool_expr.rs:24:13
+ --> $DIR/overly_complex_bool_expr.rs:27:13
|
LL | let _ = a < b && a >= b;
| ^^^^^
error: this boolean expression contains a logic bug
- --> $DIR/overly_complex_bool_expr.rs:25:13
+ --> $DIR/overly_complex_bool_expr.rs:29:13
|
LL | let _ = a > b && a <= b;
| ^^^^^^^^^^^^^^^ help: it would look like the following: `false`
|
help: this expression can be optimized out by applying boolean operations to the outer expression
- --> $DIR/overly_complex_bool_expr.rs:25:13
+ --> $DIR/overly_complex_bool_expr.rs:29:13
|
LL | let _ = a > b && a <= b;
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.rs b/src/tools/clippy/tests/ui/panic_in_result_fn.rs
index e75eb1b6e..41e2f5226 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn.rs
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn.rs
@@ -4,6 +4,7 @@ struct A;
impl A {
fn result_with_panic() -> Result<bool, String> // should emit lint
+ //~^ ERROR: used `panic!()` or assertion in a function that returns `Result`
{
panic!("error");
}
@@ -50,6 +51,7 @@ impl A {
}
fn function_result_with_panic() -> Result<bool, String> // should emit lint
+//~^ ERROR: used `panic!()` or assertion in a function that returns `Result`
{
panic!("error");
}
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
index b758fc238..d55c5cf36 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
@@ -2,6 +2,7 @@ error: used `panic!()` or assertion in a function that returns `Result`
--> $DIR/panic_in_result_fn.rs:6:5
|
LL | / fn result_with_panic() -> Result<bool, String> // should emit lint
+LL | |
LL | | {
LL | | panic!("error");
LL | | }
@@ -9,16 +10,18 @@ LL | | }
|
= 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
note: return Err() instead of panicking
- --> $DIR/panic_in_result_fn.rs:8:9
+ --> $DIR/panic_in_result_fn.rs:9:9
|
LL | panic!("error");
| ^^^^^^^^^^^^^^^
= note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]`
error: used `panic!()` or assertion in a function that returns `Result`
- --> $DIR/panic_in_result_fn.rs:52:1
+ --> $DIR/panic_in_result_fn.rs:53:1
|
LL | / fn function_result_with_panic() -> Result<bool, String> // should emit lint
+LL | |
LL | | {
LL | | panic!("error");
LL | | }
@@ -26,7 +29,7 @@ LL | | }
|
= 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
note: return Err() instead of panicking
- --> $DIR/panic_in_result_fn.rs:54:5
+ --> $DIR/panic_in_result_fn.rs:56:5
|
LL | panic!("error");
| ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs
index 08ab4d868..672c4c738 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs
@@ -5,18 +5,21 @@ struct A;
impl A {
fn result_with_assert_with_message(x: i32) -> Result<bool, String> // should emit lint
+ //~^ ERROR: used `panic!()` or assertion in a function that returns `Result`
{
assert!(x == 5, "wrong argument");
Ok(true)
}
fn result_with_assert_eq(x: i32) -> Result<bool, String> // should emit lint
+ //~^ ERROR: used `panic!()` or assertion in a function that returns `Result`
{
assert_eq!(x, 5);
Ok(true)
}
fn result_with_assert_ne(x: i32) -> Result<bool, String> // should emit lint
+ //~^ ERROR: used `panic!()` or assertion in a function that returns `Result`
{
assert_ne!(x, 1);
Ok(true)
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
index 0dd213a7e..a80e6f27a 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
@@ -2,6 +2,7 @@ error: used `panic!()` or assertion in a function that returns `Result`
--> $DIR/panic_in_result_fn_assertions.rs:7:5
|
LL | / fn result_with_assert_with_message(x: i32) -> Result<bool, String> // should emit lint
+LL | |
LL | | {
LL | | assert!(x == 5, "wrong argument");
LL | | Ok(true)
@@ -10,16 +11,18 @@ LL | | }
|
= 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
note: return Err() instead of panicking
- --> $DIR/panic_in_result_fn_assertions.rs:9:9
+ --> $DIR/panic_in_result_fn_assertions.rs:10:9
|
LL | assert!(x == 5, "wrong argument");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]`
error: used `panic!()` or assertion in a function that returns `Result`
- --> $DIR/panic_in_result_fn_assertions.rs:13:5
+ --> $DIR/panic_in_result_fn_assertions.rs:14:5
|
LL | / fn result_with_assert_eq(x: i32) -> Result<bool, String> // should emit lint
+LL | |
LL | | {
LL | | assert_eq!(x, 5);
LL | | Ok(true)
@@ -28,15 +31,16 @@ LL | | }
|
= 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
note: return Err() instead of panicking
- --> $DIR/panic_in_result_fn_assertions.rs:15:9
+ --> $DIR/panic_in_result_fn_assertions.rs:17:9
|
LL | assert_eq!(x, 5);
| ^^^^^^^^^^^^^^^^
error: used `panic!()` or assertion in a function that returns `Result`
- --> $DIR/panic_in_result_fn_assertions.rs:19:5
+ --> $DIR/panic_in_result_fn_assertions.rs:21:5
|
LL | / fn result_with_assert_ne(x: i32) -> Result<bool, String> // should emit lint
+LL | |
LL | | {
LL | | assert_ne!(x, 1);
LL | | Ok(true)
@@ -45,7 +49,7 @@ LL | | }
|
= 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
note: return Err() instead of panicking
- --> $DIR/panic_in_result_fn_assertions.rs:21:9
+ --> $DIR/panic_in_result_fn_assertions.rs:24:9
|
LL | assert_ne!(x, 1);
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/panicking_macros.rs b/src/tools/clippy/tests/ui/panicking_macros.rs
index 041ef17fa..dccfbd409 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.rs
+++ b/src/tools/clippy/tests/ui/panicking_macros.rs
@@ -21,41 +21,61 @@ fn inline_const() {
fn panic() {
let a = 2;
panic!();
+ //~^ ERROR: `panic` should not be present in production code
+ //~| NOTE: `-D clippy::panic` implied by `-D warnings`
panic!("message");
+ //~^ ERROR: `panic` should not be present in production code
panic!("{} {}", "panic with", "multiple arguments");
+ //~^ ERROR: `panic` should not be present in production code
let b = a + 2;
}
fn todo() {
let a = 2;
todo!();
+ //~^ ERROR: `todo` should not be present in production code
+ //~| NOTE: `-D clippy::todo` implied by `-D warnings`
todo!("message");
+ //~^ ERROR: `todo` should not be present in production code
todo!("{} {}", "panic with", "multiple arguments");
+ //~^ ERROR: `todo` should not be present in production code
let b = a + 2;
}
fn unimplemented() {
let a = 2;
unimplemented!();
+ //~^ ERROR: `unimplemented` should not be present in production code
+ //~| NOTE: `-D clippy::unimplemented` implied by `-D warnings`
unimplemented!("message");
+ //~^ ERROR: `unimplemented` should not be present in production code
unimplemented!("{} {}", "panic with", "multiple arguments");
+ //~^ ERROR: `unimplemented` should not be present in production code
let b = a + 2;
}
fn unreachable() {
let a = 2;
unreachable!();
+ //~^ ERROR: usage of the `unreachable!` macro
+ //~| NOTE: `-D clippy::unreachable` implied by `-D warnings`
unreachable!("message");
+ //~^ ERROR: usage of the `unreachable!` macro
unreachable!("{} {}", "panic with", "multiple arguments");
+ //~^ ERROR: usage of the `unreachable!` macro
let b = a + 2;
}
fn core_versions() {
use core::{panic, todo, unimplemented, unreachable};
panic!();
+ //~^ ERROR: `panic` should not be present in production code
todo!();
+ //~^ ERROR: `todo` should not be present in production code
unimplemented!();
+ //~^ ERROR: `unimplemented` should not be present in production code
unreachable!();
+ //~^ ERROR: usage of the `unreachable!` macro
}
fn assert() {
diff --git a/src/tools/clippy/tests/ui/panicking_macros.stderr b/src/tools/clippy/tests/ui/panicking_macros.stderr
index 4ceb6d144..59ce57d0b 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.stderr
+++ b/src/tools/clippy/tests/ui/panicking_macros.stderr
@@ -5,99 +5,103 @@ LL | panic!();
| ^^^^^^^^
|
= note: `-D clippy::panic` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::panic)]`
error: `panic` should not be present in production code
- --> $DIR/panicking_macros.rs:24:5
+ --> $DIR/panicking_macros.rs:26:5
|
LL | panic!("message");
| ^^^^^^^^^^^^^^^^^
error: `panic` should not be present in production code
- --> $DIR/panicking_macros.rs:25:5
+ --> $DIR/panicking_macros.rs:28:5
|
LL | panic!("{} {}", "panic with", "multiple arguments");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `todo` should not be present in production code
- --> $DIR/panicking_macros.rs:31:5
+ --> $DIR/panicking_macros.rs:35:5
|
LL | todo!();
| ^^^^^^^
|
= note: `-D clippy::todo` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::todo)]`
error: `todo` should not be present in production code
- --> $DIR/panicking_macros.rs:32:5
+ --> $DIR/panicking_macros.rs:38:5
|
LL | todo!("message");
| ^^^^^^^^^^^^^^^^
error: `todo` should not be present in production code
- --> $DIR/panicking_macros.rs:33:5
+ --> $DIR/panicking_macros.rs:40:5
|
LL | todo!("{} {}", "panic with", "multiple arguments");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `unimplemented` should not be present in production code
- --> $DIR/panicking_macros.rs:39:5
+ --> $DIR/panicking_macros.rs:47:5
|
LL | unimplemented!();
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unimplemented` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unimplemented)]`
error: `unimplemented` should not be present in production code
- --> $DIR/panicking_macros.rs:40:5
+ --> $DIR/panicking_macros.rs:50:5
|
LL | unimplemented!("message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `unimplemented` should not be present in production code
- --> $DIR/panicking_macros.rs:41:5
+ --> $DIR/panicking_macros.rs:52:5
|
LL | unimplemented!("{} {}", "panic with", "multiple arguments");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: usage of the `unreachable!` macro
- --> $DIR/panicking_macros.rs:47:5
+ --> $DIR/panicking_macros.rs:59:5
|
LL | unreachable!();
| ^^^^^^^^^^^^^^
|
= note: `-D clippy::unreachable` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unreachable)]`
error: usage of the `unreachable!` macro
- --> $DIR/panicking_macros.rs:48:5
+ --> $DIR/panicking_macros.rs:62:5
|
LL | unreachable!("message");
| ^^^^^^^^^^^^^^^^^^^^^^^
error: usage of the `unreachable!` macro
- --> $DIR/panicking_macros.rs:49:5
+ --> $DIR/panicking_macros.rs:64:5
|
LL | unreachable!("{} {}", "panic with", "multiple arguments");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `panic` should not be present in production code
- --> $DIR/panicking_macros.rs:55:5
+ --> $DIR/panicking_macros.rs:71:5
|
LL | panic!();
| ^^^^^^^^
error: `todo` should not be present in production code
- --> $DIR/panicking_macros.rs:56:5
+ --> $DIR/panicking_macros.rs:73:5
|
LL | todo!();
| ^^^^^^^
error: `unimplemented` should not be present in production code
- --> $DIR/panicking_macros.rs:57:5
+ --> $DIR/panicking_macros.rs:75:5
|
LL | unimplemented!();
| ^^^^^^^^^^^^^^^^
error: usage of the `unreachable!` macro
- --> $DIR/panicking_macros.rs:58:5
+ --> $DIR/panicking_macros.rs:77:5
|
LL | unreachable!();
| ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/partial_pub_fields.rs b/src/tools/clippy/tests/ui/partial_pub_fields.rs
index 668545da8..316b36c25 100644
--- a/src/tools/clippy/tests/ui/partial_pub_fields.rs
+++ b/src/tools/clippy/tests/ui/partial_pub_fields.rs
@@ -8,19 +8,23 @@ fn main() {
pub struct FileSet {
files: HashMap<String, u32>,
pub paths: HashMap<u32, String>,
+ //~^ ERROR: mixed usage of pub and non-pub fields
}
pub struct Color {
pub r: u8,
pub g: u8,
b: u8,
+ //~^ ERROR: mixed usage of pub and non-pub fields
}
pub struct Point(i32, pub i32);
+ //~^ ERROR: mixed usage of pub and non-pub fields
pub struct Visibility {
r#pub: bool,
pub pos: u32,
+ //~^ ERROR: mixed usage of pub and non-pub fields
}
// Don't lint on empty structs;
diff --git a/src/tools/clippy/tests/ui/partial_pub_fields.stderr b/src/tools/clippy/tests/ui/partial_pub_fields.stderr
index 84cfc1a91..a15228740 100644
--- a/src/tools/clippy/tests/ui/partial_pub_fields.stderr
+++ b/src/tools/clippy/tests/ui/partial_pub_fields.stderr
@@ -6,9 +6,10 @@ LL | pub paths: HashMap<u32, String>,
|
= help: consider using private field here
= note: `-D clippy::partial-pub-fields` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::partial_pub_fields)]`
error: mixed usage of pub and non-pub fields
- --> $DIR/partial_pub_fields.rs:16:9
+ --> $DIR/partial_pub_fields.rs:17:9
|
LL | b: u8,
| ^
@@ -16,7 +17,7 @@ LL | b: u8,
= help: consider using public field here
error: mixed usage of pub and non-pub fields
- --> $DIR/partial_pub_fields.rs:19:27
+ --> $DIR/partial_pub_fields.rs:21:27
|
LL | pub struct Point(i32, pub i32);
| ^^^
@@ -24,7 +25,7 @@ LL | pub struct Point(i32, pub i32);
= help: consider using private field here
error: mixed usage of pub and non-pub fields
- --> $DIR/partial_pub_fields.rs:23:9
+ --> $DIR/partial_pub_fields.rs:26:9
|
LL | pub pos: u32,
| ^^^
diff --git a/src/tools/clippy/tests/ui/partialeq_ne_impl.rs b/src/tools/clippy/tests/ui/partialeq_ne_impl.rs
index 1338d3c74..555eeebe1 100644
--- a/src/tools/clippy/tests/ui/partialeq_ne_impl.rs
+++ b/src/tools/clippy/tests/ui/partialeq_ne_impl.rs
@@ -7,6 +7,8 @@ impl PartialEq for Foo {
true
}
fn ne(&self, _: &Foo) -> bool {
+ //~^ ERROR: re-implementing `PartialEq::ne` is unnecessary
+ //~| NOTE: `-D clippy::partialeq-ne-impl` implied by `-D warnings`
false
}
}
diff --git a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr
index b92da4511..163d6b1dd 100644
--- a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr
+++ b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr
@@ -2,11 +2,14 @@ error: re-implementing `PartialEq::ne` is unnecessary
--> $DIR/partialeq_ne_impl.rs:9:5
|
LL | / fn ne(&self, _: &Foo) -> bool {
+LL | |
+LL | |
LL | | false
LL | | }
| |_____^
|
= note: `-D clippy::partialeq-ne-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::partialeq_ne_impl)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.fixed b/src/tools/clippy/tests/ui/partialeq_to_none.fixed
index 95e184b1d..87adbca39 100644
--- a/src/tools/clippy/tests/ui/partialeq_to_none.fixed
+++ b/src/tools/clippy/tests/ui/partialeq_to_none.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::partialeq_to_none)]
#![allow(clippy::eq_op, clippy::needless_if)]
diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.rs b/src/tools/clippy/tests/ui/partialeq_to_none.rs
index 4fa50dcc1..b623e6a66 100644
--- a/src/tools/clippy/tests/ui/partialeq_to_none.rs
+++ b/src/tools/clippy/tests/ui/partialeq_to_none.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::partialeq_to_none)]
#![allow(clippy::eq_op, clippy::needless_if)]
diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.stderr b/src/tools/clippy/tests/ui/partialeq_to_none.stderr
index 4f84862a2..50ce15001 100644
--- a/src/tools/clippy/tests/ui/partialeq_to_none.stderr
+++ b/src/tools/clippy/tests/ui/partialeq_to_none.stderr
@@ -1,61 +1,62 @@
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:15:8
+ --> $DIR/partialeq_to_none.rs:14:8
|
LL | if f != None { "yay" } else { "nay" }
| ^^^^^^^^^ help: use `Option::is_some()` instead: `f.is_some()`
|
= note: `-D clippy::partialeq-to-none` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::partialeq_to_none)]`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:45:13
+ --> $DIR/partialeq_to_none.rs:44:13
|
LL | let _ = x == None;
| ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:46:13
+ --> $DIR/partialeq_to_none.rs:45:13
|
LL | let _ = x != None;
| ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:47:13
+ --> $DIR/partialeq_to_none.rs:46:13
|
LL | let _ = None == x;
| ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:48:13
+ --> $DIR/partialeq_to_none.rs:47:13
|
LL | let _ = None != x;
| ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:50:8
+ --> $DIR/partialeq_to_none.rs:49:8
|
LL | if foobar() == None {}
| ^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `foobar().is_none()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:52:8
+ --> $DIR/partialeq_to_none.rs:51:8
|
LL | if bar().ok() != None {}
| ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `bar().ok().is_some()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:54:13
+ --> $DIR/partialeq_to_none.rs:53:13
|
LL | let _ = Some(1 + 2) != None;
| ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `Some(1 + 2).is_some()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:56:13
+ --> $DIR/partialeq_to_none.rs:55:13
|
LL | let _ = { Some(0) } == None;
| ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `{ Some(0) }.is_none()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:58:13
+ --> $DIR/partialeq_to_none.rs:57:13
|
LL | let _ = {
| _____________^
@@ -77,31 +78,31 @@ LL ~ }.is_some();
|
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:68:13
+ --> $DIR/partialeq_to_none.rs:67:13
|
LL | let _ = optref() == &&None;
| ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:69:13
+ --> $DIR/partialeq_to_none.rs:68:13
|
LL | let _ = &&None != optref();
| ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:70:13
+ --> $DIR/partialeq_to_none.rs:69:13
|
LL | let _ = **optref() == None;
| ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:71:13
+ --> $DIR/partialeq_to_none.rs:70:13
|
LL | let _ = &None != *optref();
| ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()`
error: binary comparison to literal `Option::None`
- --> $DIR/partialeq_to_none.rs:74:13
+ --> $DIR/partialeq_to_none.rs:73:13
|
LL | let _ = None != *x;
| ^^^^^^^^^^ help: use `Option::is_some()` instead: `(*x).is_some()`
diff --git a/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed b/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed
index 393fc6e1c..86e3e5bbd 100644
--- a/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed
+++ b/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
use std::path::PathBuf;
#[warn(clippy::all, clippy::path_buf_push_overwrite)]
diff --git a/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs b/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs
index 18de6e064..460cc254e 100644
--- a/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs
+++ b/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
use std::path::PathBuf;
#[warn(clippy::all, clippy::path_buf_push_overwrite)]
diff --git a/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr b/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr
index bb8dce2bb..1453d020c 100644
--- a/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr
+++ b/src/tools/clippy/tests/ui/path_buf_push_overwrite.stderr
@@ -1,10 +1,11 @@
-error: calling `push` with '/' or '/' (file system root) will overwrite the previous path definition
- --> $DIR/path_buf_push_overwrite.rs:7:12
+error: calling `push` with '/' or '\' (file system root) will overwrite the previous path definition
+ --> $DIR/path_buf_push_overwrite.rs:6:12
|
LL | x.push("/bar");
| ^^^^^^ help: try: `"bar"`
|
= note: `-D clippy::path-buf-push-overwrite` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::path_buf_push_overwrite)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.fixed b/src/tools/clippy/tests/ui/path_ends_with_ext.fixed
new file mode 100644
index 000000000..49767e242
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.fixed
@@ -0,0 +1,36 @@
+#![warn(clippy::path_ends_with_ext)]
+use std::path::Path;
+
+macro_rules! arg {
+ () => {
+ ".md"
+ };
+}
+
+fn test(path: &Path) {
+ path.extension().is_some_and(|ext| ext == "md");
+ //~^ ERROR: this looks like a failed attempt at checking for the file extension
+
+ // some "extensions" are allowed by default
+ path.ends_with(".git");
+
+ // most legitimate "dotfiles" are longer than 3 chars, so we allow them as well
+ path.ends_with(".bashrc");
+
+ // argument from expn shouldn't trigger
+ path.ends_with(arg!());
+
+ path.ends_with("..");
+ path.ends_with("./a");
+ path.ends_with(".");
+ path.ends_with("");
+}
+
+// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that
+#[clippy::msrv = "1.69"]
+fn under_msv(path: &Path) -> bool {
+ path.extension().map_or(false, |ext| ext == "md")
+ //~^ ERROR: this looks like a failed attempt at checking for the file extension
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.rs b/src/tools/clippy/tests/ui/path_ends_with_ext.rs
new file mode 100644
index 000000000..2dfd04621
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.rs
@@ -0,0 +1,36 @@
+#![warn(clippy::path_ends_with_ext)]
+use std::path::Path;
+
+macro_rules! arg {
+ () => {
+ ".md"
+ };
+}
+
+fn test(path: &Path) {
+ path.ends_with(".md");
+ //~^ ERROR: this looks like a failed attempt at checking for the file extension
+
+ // some "extensions" are allowed by default
+ path.ends_with(".git");
+
+ // most legitimate "dotfiles" are longer than 3 chars, so we allow them as well
+ path.ends_with(".bashrc");
+
+ // argument from expn shouldn't trigger
+ path.ends_with(arg!());
+
+ path.ends_with("..");
+ path.ends_with("./a");
+ path.ends_with(".");
+ path.ends_with("");
+}
+
+// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that
+#[clippy::msrv = "1.69"]
+fn under_msv(path: &Path) -> bool {
+ path.ends_with(".md")
+ //~^ ERROR: this looks like a failed attempt at checking for the file extension
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.stderr b/src/tools/clippy/tests/ui/path_ends_with_ext.stderr
new file mode 100644
index 000000000..a73ab4d08
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.stderr
@@ -0,0 +1,17 @@
+error: this looks like a failed attempt at checking for the file extension
+ --> $DIR/path_ends_with_ext.rs:11:5
+ |
+LL | path.ends_with(".md");
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().is_some_and(|ext| ext == "md")`
+ |
+ = note: `-D clippy::path-ends-with-ext` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::path_ends_with_ext)]`
+
+error: this looks like a failed attempt at checking for the file extension
+ --> $DIR/path_ends_with_ext.rs:32:5
+ |
+LL | path.ends_with(".md")
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().map_or(false, |ext| ext == "md")`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.rs b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.rs
index 55a8c2621..61dee47cb 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.rs
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.rs
@@ -7,12 +7,14 @@ fn should_lint() {
let value = &Some(23);
match value {
Some(_) => (),
+ //~^ ERROR: type of pattern does not match the expression type
_ => (),
}
let value = &mut Some(23);
match value {
Some(_) => (),
+ //~^ ERROR: type of pattern does not match the expression type
_ => (),
}
}
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr
index 87fb243b6..f21e1894a 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr
@@ -6,9 +6,10 @@ LL | Some(_) => (),
|
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
= note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
error: type of pattern does not match the expression type
- --> $DIR/mutability.rs:15:9
+ --> $DIR/mutability.rs:16:9
|
LL | Some(_) => (),
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.rs b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.rs
index 065ea9fb9..558d496ae 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.rs
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.rs
@@ -13,8 +13,11 @@ fn alternatives() {
// not ok
if let Value::B | Value::A(_) = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let &Value::B | &Value::A(Some(_)) = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let Value::B | Value::A(Some(_)) = *ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
if let &Value::B | &Value::A(_) = ref_value {}
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr
index a91b5ac6c..b72c24840 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr
@@ -6,9 +6,10 @@ LL | if let Value::B | Value::A(_) = ref_value {}
|
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
= note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
error: type of pattern does not match the expression type
- --> $DIR/pattern_alternatives.rs:16:34
+ --> $DIR/pattern_alternatives.rs:17:34
|
LL | if let &Value::B | &Value::A(Some(_)) = ref_value {}
| ^^^^^^^
@@ -16,7 +17,7 @@ LL | if let &Value::B | &Value::A(Some(_)) = ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_alternatives.rs:17:32
+ --> $DIR/pattern_alternatives.rs:19:32
|
LL | if let Value::B | Value::A(Some(_)) = *ref_value {}
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.rs b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.rs
index 417b1c107..d9b22693f 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.rs
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.rs
@@ -11,8 +11,11 @@ fn struct_types() {
// not ok
let Struct { .. } = ref_value;
+ //~^ ERROR: type of pattern does not match the expression type
if let &Struct { ref_inner: Some(_) } = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let Struct { ref_inner: Some(_) } = *ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
let &Struct { .. } = ref_value;
@@ -30,10 +33,15 @@ fn struct_enum_variants() {
// not ok
if let StructEnum::Var { .. } = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let StructEnum::Var { inner_ref: Some(_) } = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let StructEnum::Empty = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
if let &StructEnum::Var { .. } = ref_value {}
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr
index 8bc5c63ba..c46c7de6d 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr
@@ -6,9 +6,10 @@ LL | let Struct { .. } = ref_value;
|
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
= note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
error: type of pattern does not match the expression type
- --> $DIR/pattern_structs.rs:14:33
+ --> $DIR/pattern_structs.rs:15:33
|
LL | if let &Struct { ref_inner: Some(_) } = ref_value {}
| ^^^^^^^
@@ -16,7 +17,7 @@ LL | if let &Struct { ref_inner: Some(_) } = ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_structs.rs:15:32
+ --> $DIR/pattern_structs.rs:17:32
|
LL | if let Struct { ref_inner: Some(_) } = *ref_value {}
| ^^^^^^^
@@ -24,7 +25,7 @@ LL | if let Struct { ref_inner: Some(_) } = *ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_structs.rs:32:12
+ --> $DIR/pattern_structs.rs:35:12
|
LL | if let StructEnum::Var { .. } = ref_value {}
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | if let StructEnum::Var { .. } = ref_value {}
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_structs.rs:33:12
+ --> $DIR/pattern_structs.rs:37:12
|
LL | if let StructEnum::Var { inner_ref: Some(_) } = ref_value {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | if let StructEnum::Var { inner_ref: Some(_) } = ref_value {}
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_structs.rs:34:42
+ --> $DIR/pattern_structs.rs:39:42
|
LL | if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {}
| ^^^^^^^
@@ -48,7 +49,7 @@ LL | if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_structs.rs:35:41
+ --> $DIR/pattern_structs.rs:41:41
|
LL | if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {}
| ^^^^^^^
@@ -56,7 +57,7 @@ LL | if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_structs.rs:36:12
+ --> $DIR/pattern_structs.rs:43:12
|
LL | if let StructEnum::Empty = ref_value {}
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.rs b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.rs
index 19504a051..f44e3543c 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.rs
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.rs
@@ -9,8 +9,11 @@ fn tuple_types() {
// not ok
let TupleStruct(_) = ref_value;
+ //~^ ERROR: type of pattern does not match the expression type
if let &TupleStruct(Some(_)) = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let TupleStruct(Some(_)) = *ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
let &TupleStruct(_) = ref_value;
@@ -28,9 +31,13 @@ fn tuple_enum_variants() {
// not ok
if let TupleEnum::Var(_) = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let &TupleEnum::Var(Some(_)) = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let TupleEnum::Var(Some(_)) = *ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let TupleEnum::Empty = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
if let &TupleEnum::Var(_) = ref_value {}
@@ -46,8 +53,11 @@ fn plain_tuples() {
// not ok
let (_a, _b) = ref_value;
+ //~^ ERROR: type of pattern does not match the expression type
if let &(_a, Some(_)) = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
if let (_a, Some(_)) = *ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
let &(_a, _b) = ref_value;
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr
index a1ef540d2..b365731d5 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr
@@ -6,9 +6,10 @@ LL | let TupleStruct(_) = ref_value;
|
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
= note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:12:25
+ --> $DIR/pattern_tuples.rs:13:25
|
LL | if let &TupleStruct(Some(_)) = ref_value {}
| ^^^^^^^
@@ -16,7 +17,7 @@ LL | if let &TupleStruct(Some(_)) = ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:13:24
+ --> $DIR/pattern_tuples.rs:15:24
|
LL | if let TupleStruct(Some(_)) = *ref_value {}
| ^^^^^^^
@@ -24,7 +25,7 @@ LL | if let TupleStruct(Some(_)) = *ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:30:12
+ --> $DIR/pattern_tuples.rs:33:12
|
LL | if let TupleEnum::Var(_) = ref_value {}
| ^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | if let TupleEnum::Var(_) = ref_value {}
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:31:28
+ --> $DIR/pattern_tuples.rs:35:28
|
LL | if let &TupleEnum::Var(Some(_)) = ref_value {}
| ^^^^^^^
@@ -40,7 +41,7 @@ LL | if let &TupleEnum::Var(Some(_)) = ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:32:27
+ --> $DIR/pattern_tuples.rs:37:27
|
LL | if let TupleEnum::Var(Some(_)) = *ref_value {}
| ^^^^^^^
@@ -48,7 +49,7 @@ LL | if let TupleEnum::Var(Some(_)) = *ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:33:12
+ --> $DIR/pattern_tuples.rs:39:12
|
LL | if let TupleEnum::Empty = ref_value {}
| ^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | if let TupleEnum::Empty = ref_value {}
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:48:9
+ --> $DIR/pattern_tuples.rs:55:9
|
LL | let (_a, _b) = ref_value;
| ^^^^^^^^
@@ -64,7 +65,7 @@ LL | let (_a, _b) = ref_value;
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:49:18
+ --> $DIR/pattern_tuples.rs:57:18
|
LL | if let &(_a, Some(_)) = ref_value {}
| ^^^^^^^
@@ -72,7 +73,7 @@ LL | if let &(_a, Some(_)) = ref_value {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/pattern_tuples.rs:50:17
+ --> $DIR/pattern_tuples.rs:59:17
|
LL | if let (_a, Some(_)) = *ref_value {}
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs
index e89917c41..dbc7c3f31 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs
@@ -9,6 +9,7 @@ fn syntax_match() {
// not ok
match ref_value {
Some(_) => (),
+ //~^ ERROR: type of pattern does not match the expression type
None => (),
}
@@ -28,6 +29,7 @@ fn syntax_if_let() {
// not ok
if let Some(_) = ref_value {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
if let &Some(_) = ref_value {}
@@ -39,6 +41,7 @@ fn syntax_while_let() {
// not ok
while let Some(_) = ref_value {
+ //~^ ERROR: type of pattern does not match the expression type
break;
}
@@ -57,6 +60,7 @@ fn syntax_for() {
// not ok
for (_a, _b) in slice.iter() {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
for &(_a, _b) in slice.iter() {}
@@ -67,6 +71,7 @@ fn syntax_let() {
// not ok
let (_n, _m) = ref_value;
+ //~^ ERROR: type of pattern does not match the expression type
// ok
let &(_n, _m) = ref_value;
@@ -76,6 +81,7 @@ fn syntax_let() {
fn syntax_fn() {
// not ok
fn foo((_a, _b): &(i32, i32)) {}
+ //~^ ERROR: type of pattern does not match the expression type
// ok
fn foo_ok_1(&(_a, _b): &(i32, i32)) {}
@@ -90,6 +96,7 @@ fn syntax_closure() {
// not ok
foo(|(_a, _b)| ());
+ //~^ ERROR: type of pattern does not match the expression type
// ok
foo(|&(_a, _b)| ());
@@ -106,6 +113,7 @@ fn macro_with_expression() {
// not ok
matching_macro!(match value {
Some(_) => (),
+ //~^ ERROR: type of pattern does not match the expression type
_ => (),
});
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
index f56a3a893..dfe4639c7 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
@@ -6,9 +6,10 @@ LL | Some(_) => (),
|
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
= note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:30:12
+ --> $DIR/syntax.rs:31:12
|
LL | if let Some(_) = ref_value {}
| ^^^^^^^
@@ -16,7 +17,7 @@ LL | if let Some(_) = ref_value {}
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:41:15
+ --> $DIR/syntax.rs:43:15
|
LL | while let Some(_) = ref_value {
| ^^^^^^^
@@ -24,7 +25,7 @@ LL | while let Some(_) = ref_value {
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:59:9
+ --> $DIR/syntax.rs:62:9
|
LL | for (_a, _b) in slice.iter() {}
| ^^^^^^^^
@@ -32,7 +33,7 @@ LL | for (_a, _b) in slice.iter() {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:69:9
+ --> $DIR/syntax.rs:73:9
|
LL | let (_n, _m) = ref_value;
| ^^^^^^^^
@@ -40,7 +41,7 @@ LL | let (_n, _m) = ref_value;
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:78:12
+ --> $DIR/syntax.rs:83:12
|
LL | fn foo((_a, _b): &(i32, i32)) {}
| ^^^^^^^^
@@ -48,7 +49,7 @@ LL | fn foo((_a, _b): &(i32, i32)) {}
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:92:10
+ --> $DIR/syntax.rs:98:10
|
LL | foo(|(_a, _b)| ());
| ^^^^^^^^
@@ -56,7 +57,7 @@ LL | foo(|(_a, _b)| ());
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:108:9
+ --> $DIR/syntax.rs:115:9
|
LL | Some(_) => (),
| ^^^^^^^
@@ -64,7 +65,7 @@ LL | Some(_) => (),
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> $DIR/syntax.rs:128:17
+ --> $DIR/syntax.rs:136:17
|
LL | Some(_) => (),
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/patterns.fixed b/src/tools/clippy/tests/ui/patterns.fixed
index 714143e75..332cba971 100644
--- a/src/tools/clippy/tests/ui/patterns.fixed
+++ b/src/tools/clippy/tests/ui/patterns.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::all)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/patterns.rs b/src/tools/clippy/tests/ui/patterns.rs
index 153e26407..45d907688 100644
--- a/src/tools/clippy/tests/ui/patterns.rs
+++ b/src/tools/clippy/tests/ui/patterns.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::all)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/patterns.stderr b/src/tools/clippy/tests/ui/patterns.stderr
index 276330d21..2f608bbc1 100644
--- a/src/tools/clippy/tests/ui/patterns.stderr
+++ b/src/tools/clippy/tests/ui/patterns.stderr
@@ -1,19 +1,20 @@
error: the `y @ _` pattern can be written as just `y`
- --> $DIR/patterns.rs:15:9
+ --> $DIR/patterns.rs:14:9
|
LL | y @ _ => (),
| ^^^^^ help: try: `y`
|
= note: `-D clippy::redundant-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern)]`
error: the `x @ _` pattern can be written as just `x`
- --> $DIR/patterns.rs:30:9
+ --> $DIR/patterns.rs:29:9
|
LL | ref mut x @ _ => {
| ^^^^^^^^^^^^^ help: try: `ref mut x`
error: the `x @ _` pattern can be written as just `x`
- --> $DIR/patterns.rs:38:9
+ --> $DIR/patterns.rs:37:9
|
LL | ref x @ _ => println!("vec: {:?}", x),
| ^^^^^^^^^ help: try: `ref x`
diff --git a/src/tools/clippy/tests/ui/permissions_set_readonly_false.rs b/src/tools/clippy/tests/ui/permissions_set_readonly_false.rs
index 28c00d100..5a84a64fd 100644
--- a/src/tools/clippy/tests/ui/permissions_set_readonly_false.rs
+++ b/src/tools/clippy/tests/ui/permissions_set_readonly_false.rs
@@ -17,6 +17,8 @@ fn main() {
let mut permissions = metadata.permissions();
// lint here
permissions.set_readonly(false);
+ //~^ ERROR: call to `set_readonly` with argument `false`
+ //~| NOTE: on Unix platforms this results in the file being world writable
// no lint
permissions.set_readonly(true);
diff --git a/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr b/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr
index e7a8ee6cb..58a7de84d 100644
--- a/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr
+++ b/src/tools/clippy/tests/ui/permissions_set_readonly_false.stderr
@@ -8,6 +8,7 @@ LL | permissions.set_readonly(false);
= help: you can set the desired permissions using `PermissionsExt`. For more information, see
https://doc.rust-lang.org/std/os/unix/fs/trait.PermissionsExt.html
= note: `-D clippy::permissions-set-readonly-false` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::permissions_set_readonly_false)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/precedence.fixed b/src/tools/clippy/tests/ui/precedence.fixed
index af4d5636b..cc87de0d9 100644
--- a/src/tools/clippy/tests/ui/precedence.fixed
+++ b/src/tools/clippy/tests/ui/precedence.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::precedence)]
#![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)]
#![allow(clippy::identity_op)]
diff --git a/src/tools/clippy/tests/ui/precedence.rs b/src/tools/clippy/tests/ui/precedence.rs
index e23ae9127..00c18d92b 100644
--- a/src/tools/clippy/tests/ui/precedence.rs
+++ b/src/tools/clippy/tests/ui/precedence.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::precedence)]
#![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)]
#![allow(clippy::identity_op)]
diff --git a/src/tools/clippy/tests/ui/precedence.stderr b/src/tools/clippy/tests/ui/precedence.stderr
index 03d585b39..bd0cbccc7 100644
--- a/src/tools/clippy/tests/ui/precedence.stderr
+++ b/src/tools/clippy/tests/ui/precedence.stderr
@@ -1,73 +1,74 @@
error: operator precedence can trip the unwary
- --> $DIR/precedence.rs:17:5
+ --> $DIR/precedence.rs:16:5
|
LL | 1 << 2 + 3;
| ^^^^^^^^^^ help: consider parenthesizing your expression: `1 << (2 + 3)`
|
= note: `-D clippy::precedence` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::precedence)]`
error: operator precedence can trip the unwary
- --> $DIR/precedence.rs:18:5
+ --> $DIR/precedence.rs:17:5
|
LL | 1 + 2 << 3;
| ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 2) << 3`
error: operator precedence can trip the unwary
- --> $DIR/precedence.rs:19:5
+ --> $DIR/precedence.rs:18:5
|
LL | 4 >> 1 + 1;
| ^^^^^^^^^^ help: consider parenthesizing your expression: `4 >> (1 + 1)`
error: operator precedence can trip the unwary
- --> $DIR/precedence.rs:20:5
+ --> $DIR/precedence.rs:19:5
|
LL | 1 + 3 >> 2;
| ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 3) >> 2`
error: operator precedence can trip the unwary
- --> $DIR/precedence.rs:21:5
+ --> $DIR/precedence.rs:20:5
|
LL | 1 ^ 1 - 1;
| ^^^^^^^^^ help: consider parenthesizing your expression: `1 ^ (1 - 1)`
error: operator precedence can trip the unwary
- --> $DIR/precedence.rs:22:5
+ --> $DIR/precedence.rs:21:5
|
LL | 3 | 2 - 1;
| ^^^^^^^^^ help: consider parenthesizing your expression: `3 | (2 - 1)`
error: operator precedence can trip the unwary
- --> $DIR/precedence.rs:23:5
+ --> $DIR/precedence.rs:22:5
|
LL | 3 & 5 - 2;
| ^^^^^^^^^ help: consider parenthesizing your expression: `3 & (5 - 2)`
error: unary minus has lower precedence than method call
- --> $DIR/precedence.rs:24:5
+ --> $DIR/precedence.rs:23:5
|
LL | -1i32.abs();
| ^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1i32.abs())`
error: unary minus has lower precedence than method call
- --> $DIR/precedence.rs:25:5
+ --> $DIR/precedence.rs:24:5
|
LL | -1f32.abs();
| ^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1f32.abs())`
error: unary minus has lower precedence than method call
- --> $DIR/precedence.rs:52:13
+ --> $DIR/precedence.rs:51:13
|
LL | let _ = -1.0_f64.cos().cos();
| ^^^^^^^^^^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1.0_f64.cos().cos())`
error: unary minus has lower precedence than method call
- --> $DIR/precedence.rs:53:13
+ --> $DIR/precedence.rs:52:13
|
LL | let _ = -1.0_f64.cos().sin();
| ^^^^^^^^^^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1.0_f64.cos().sin())`
error: unary minus has lower precedence than method call
- --> $DIR/precedence.rs:54:13
+ --> $DIR/precedence.rs:53:13
|
LL | let _ = -1.0_f64.sin().cos();
| ^^^^^^^^^^^^^^^^^^^^ help: consider adding parentheses to clarify your intent: `-(1.0_f64.sin().cos())`
diff --git a/src/tools/clippy/tests/ui/print.rs b/src/tools/clippy/tests/ui/print.rs
index 366ccc2b3..9ac4b51e1 100644
--- a/src/tools/clippy/tests/ui/print.rs
+++ b/src/tools/clippy/tests/ui/print.rs
@@ -9,6 +9,8 @@ struct Foo;
impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "{:?}", 43.1415)
+ //~^ ERROR: use of `Debug`-based formatting
+ //~| NOTE: `-D clippy::use-debug` implied by `-D warnings`
}
}
@@ -21,13 +23,21 @@ impl Debug for Foo {
fn main() {
println!("Hello");
+ //~^ ERROR: use of `println!`
+ //~| NOTE: `-D clippy::print-stdout` implied by `-D warnings`
print!("Hello");
+ //~^ ERROR: use of `print!`
print!("Hello {}", "World");
+ //~^ ERROR: use of `print!`
print!("Hello {:?}", "World");
+ //~^ ERROR: use of `print!`
+ //~| ERROR: use of `Debug`-based formatting
print!("Hello {:#?}", "#orld");
+ //~^ ERROR: use of `print!`
+ //~| ERROR: use of `Debug`-based formatting
assert_eq!(42, 1337);
diff --git a/src/tools/clippy/tests/ui/print.stderr b/src/tools/clippy/tests/ui/print.stderr
index 1754c4183..bb8d94508 100644
--- a/src/tools/clippy/tests/ui/print.stderr
+++ b/src/tools/clippy/tests/ui/print.stderr
@@ -5,47 +5,49 @@ LL | write!(f, "{:?}", 43.1415)
| ^^^^
|
= note: `-D clippy::use-debug` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::use_debug)]`
error: use of `println!`
- --> $DIR/print.rs:23:5
+ --> $DIR/print.rs:25:5
|
LL | println!("Hello");
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::print-stdout` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_stdout)]`
error: use of `print!`
- --> $DIR/print.rs:24:5
+ --> $DIR/print.rs:28:5
|
LL | print!("Hello");
| ^^^^^^^^^^^^^^^
error: use of `print!`
- --> $DIR/print.rs:26:5
+ --> $DIR/print.rs:31:5
|
LL | print!("Hello {}", "World");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: use of `print!`
- --> $DIR/print.rs:28:5
+ --> $DIR/print.rs:34:5
|
LL | print!("Hello {:?}", "World");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: use of `Debug`-based formatting
- --> $DIR/print.rs:28:19
+ --> $DIR/print.rs:34:19
|
LL | print!("Hello {:?}", "World");
| ^^^^
error: use of `print!`
- --> $DIR/print.rs:30:5
+ --> $DIR/print.rs:38:5
|
LL | print!("Hello {:#?}", "#orld");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: use of `Debug`-based formatting
- --> $DIR/print.rs:30:19
+ --> $DIR/print.rs:38:19
|
LL | print!("Hello {:#?}", "#orld");
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/print_in_format_impl.rs b/src/tools/clippy/tests/ui/print_in_format_impl.rs
index 64e886866..261f50832 100644
--- a/src/tools/clippy/tests/ui/print_in_format_impl.rs
+++ b/src/tools/clippy/tests/ui/print_in_format_impl.rs
@@ -1,7 +1,7 @@
#![allow(unused, clippy::print_literal, clippy::write_literal)]
#![warn(clippy::print_in_format_impl)]
use std::fmt::{Debug, Display, Error, Formatter};
-
+//@no-rustfix
macro_rules! indirect {
() => {{ println!() }};
}
@@ -18,11 +18,17 @@ impl Debug for Foo {
static WORKS_WITH_NESTED_ITEMS: bool = true;
print!("{}", 1);
+ //~^ ERROR: use of `print!` in `Debug` impl
+ //~| NOTE: `-D clippy::print-in-format-impl` implied by `-D warnings`
println!("{}", 2);
+ //~^ ERROR: use of `println!` in `Debug` impl
eprint!("{}", 3);
+ //~^ ERROR: use of `eprint!` in `Debug` impl
eprintln!("{}", 4);
+ //~^ ERROR: use of `eprintln!` in `Debug` impl
nested! {
println!("nested");
+ //~^ ERROR: use of `println!` in `Debug` impl
};
write!(f, "{}", 5);
@@ -36,6 +42,7 @@ impl Debug for Foo {
impl Display for Foo {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
print!("Display");
+ //~^ ERROR: use of `print!` in `Display` impl
write!(f, "Display");
Ok(())
@@ -46,6 +53,7 @@ struct UnnamedFormatter;
impl Debug for UnnamedFormatter {
fn fmt(&self, _: &mut Formatter) -> Result<(), Error> {
println!("UnnamedFormatter");
+ //~^ ERROR: use of `println!` in `Debug` impl
Ok(())
}
}
diff --git a/src/tools/clippy/tests/ui/print_in_format_impl.stderr b/src/tools/clippy/tests/ui/print_in_format_impl.stderr
index 63b7179bc..57f06dc11 100644
--- a/src/tools/clippy/tests/ui/print_in_format_impl.stderr
+++ b/src/tools/clippy/tests/ui/print_in_format_impl.stderr
@@ -5,39 +5,40 @@ LL | print!("{}", 1);
| ^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)`
|
= note: `-D clippy::print-in-format-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_in_format_impl)]`
error: use of `println!` in `Debug` impl
- --> $DIR/print_in_format_impl.rs:21:9
+ --> $DIR/print_in_format_impl.rs:23:9
|
LL | println!("{}", 2);
| ^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)`
error: use of `eprint!` in `Debug` impl
- --> $DIR/print_in_format_impl.rs:22:9
+ --> $DIR/print_in_format_impl.rs:25:9
|
LL | eprint!("{}", 3);
| ^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)`
error: use of `eprintln!` in `Debug` impl
- --> $DIR/print_in_format_impl.rs:23:9
+ --> $DIR/print_in_format_impl.rs:27:9
|
LL | eprintln!("{}", 4);
| ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)`
error: use of `println!` in `Debug` impl
- --> $DIR/print_in_format_impl.rs:25:13
+ --> $DIR/print_in_format_impl.rs:30:13
|
LL | println!("nested");
| ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)`
error: use of `print!` in `Display` impl
- --> $DIR/print_in_format_impl.rs:38:9
+ --> $DIR/print_in_format_impl.rs:44:9
|
LL | print!("Display");
| ^^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)`
error: use of `println!` in `Debug` impl
- --> $DIR/print_in_format_impl.rs:48:9
+ --> $DIR/print_in_format_impl.rs:55:9
|
LL | println!("UnnamedFormatter");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(..)`
diff --git a/src/tools/clippy/tests/ui/print_literal.fixed b/src/tools/clippy/tests/ui/print_literal.fixed
new file mode 100644
index 000000000..88cd3a54b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/print_literal.fixed
@@ -0,0 +1,58 @@
+#![warn(clippy::print_literal)]
+#![allow(clippy::uninlined_format_args)]
+
+fn main() {
+ // these should be fine
+ print!("Hello");
+ println!("Hello");
+ let world = "world";
+ println!("Hello {}", world);
+ println!("Hello {world}", world = world);
+ println!("3 in hex is {:X}", 3);
+ println!("2 + 1 = {:.4}", 3);
+ println!("2 + 1 = {:5.4}", 3);
+ println!("Debug test {:?}", "hello, world");
+ println!("{0:8} {1:>8}", "hello", "world");
+ println!("{1:8} {0:>8}", "hello", "world");
+ println!("{foo:8} {bar:>8}", foo = "hello", bar = "world");
+ println!("{bar:8} {foo:>8}", foo = "hello", bar = "world");
+ println!("{number:>width$}", number = 1, width = 6);
+ println!("{number:>0width$}", number = 1, width = 6);
+ println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
+ println!("10 / 4 is {}", 2.5);
+ println!("2 + 1 = {}", 3);
+ println!("From expansion {}", stringify!(not a string literal));
+
+ // these should throw warnings
+ print!("Hello world");
+ //~^ ERROR: literal with an empty format string
+ //~| NOTE: `-D clippy::print-literal` implied by `-D warnings`
+ println!("Hello {} world", world);
+ //~^ ERROR: literal with an empty format string
+ println!("Hello world");
+ //~^ ERROR: literal with an empty format string
+ println!("a literal {:.4}", 5);
+ //~^ ERROR: literal with an empty format string
+
+ // positional args don't change the fact
+ // that we're using a literal -- this should
+ // throw a warning
+ println!("hello world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+ println!("world hello");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+
+ // named args shouldn't change anything either
+ println!("hello world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+ println!("world hello");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+
+ // The string literal from `file!()` has a callsite span that isn't marked as coming from an
+ // expansion
+ println!("file: {}", file!());
+}
diff --git a/src/tools/clippy/tests/ui/print_literal.rs b/src/tools/clippy/tests/ui/print_literal.rs
index 538513e91..bd7444c96 100644
--- a/src/tools/clippy/tests/ui/print_literal.rs
+++ b/src/tools/clippy/tests/ui/print_literal.rs
@@ -25,19 +25,32 @@ fn main() {
// these should throw warnings
print!("Hello {}", "world");
+ //~^ ERROR: literal with an empty format string
+ //~| NOTE: `-D clippy::print-literal` implied by `-D warnings`
println!("Hello {} {}", world, "world");
+ //~^ ERROR: literal with an empty format string
println!("Hello {}", "world");
+ //~^ ERROR: literal with an empty format string
println!("{} {:.4}", "a literal", 5);
+ //~^ ERROR: literal with an empty format string
// positional args don't change the fact
// that we're using a literal -- this should
// throw a warning
println!("{0} {1}", "hello", "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
println!("{1} {0}", "hello", "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
// named args shouldn't change anything either
println!("{foo} {bar}", foo = "hello", bar = "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
println!("{bar} {foo}", foo = "hello", bar = "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
// The string literal from `file!()` has a callsite span that isn't marked as coming from an
// expansion
diff --git a/src/tools/clippy/tests/ui/print_literal.stderr b/src/tools/clippy/tests/ui/print_literal.stderr
index 71c8d188f..1d9751b92 100644
--- a/src/tools/clippy/tests/ui/print_literal.stderr
+++ b/src/tools/clippy/tests/ui/print_literal.stderr
@@ -5,6 +5,7 @@ LL | print!("Hello {}", "world");
| ^^^^^^^
|
= note: `-D clippy::print-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_literal)]`
help: try
|
LL - print!("Hello {}", "world");
@@ -12,7 +13,7 @@ LL + print!("Hello world");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:28:36
+ --> $DIR/print_literal.rs:30:36
|
LL | println!("Hello {} {}", world, "world");
| ^^^^^^^
@@ -24,7 +25,7 @@ LL + println!("Hello {} world", world);
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:29:26
+ --> $DIR/print_literal.rs:32:26
|
LL | println!("Hello {}", "world");
| ^^^^^^^
@@ -36,7 +37,7 @@ LL + println!("Hello world");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:30:26
+ --> $DIR/print_literal.rs:34:26
|
LL | println!("{} {:.4}", "a literal", 5);
| ^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL + println!("a literal {:.4}", 5);
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:35:25
+ --> $DIR/print_literal.rs:40:25
|
LL | println!("{0} {1}", "hello", "world");
| ^^^^^^^
@@ -60,7 +61,7 @@ LL + println!("hello {1}", "world");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:35:34
+ --> $DIR/print_literal.rs:40:34
|
LL | println!("{0} {1}", "hello", "world");
| ^^^^^^^
@@ -72,7 +73,7 @@ LL + println!("{0} world", "hello");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:36:34
+ --> $DIR/print_literal.rs:43:34
|
LL | println!("{1} {0}", "hello", "world");
| ^^^^^^^
@@ -84,7 +85,7 @@ LL + println!("world {0}", "hello");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:36:25
+ --> $DIR/print_literal.rs:43:25
|
LL | println!("{1} {0}", "hello", "world");
| ^^^^^^^
@@ -96,7 +97,7 @@ LL + println!("{1} hello", "world");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:39:35
+ --> $DIR/print_literal.rs:48:35
|
LL | println!("{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^
@@ -108,7 +109,7 @@ LL + println!("hello {bar}", bar = "world");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:39:50
+ --> $DIR/print_literal.rs:48:50
|
LL | println!("{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^
@@ -120,7 +121,7 @@ LL + println!("{foo} world", foo = "hello");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:40:50
+ --> $DIR/print_literal.rs:51:50
|
LL | println!("{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^
@@ -132,7 +133,7 @@ LL + println!("world {foo}", foo = "hello");
|
error: literal with an empty format string
- --> $DIR/print_literal.rs:40:35
+ --> $DIR/print_literal.rs:51:35
|
LL | println!("{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/print_stderr.rs b/src/tools/clippy/tests/ui/print_stderr.rs
index fa07e74a7..109f43ffe 100644
--- a/src/tools/clippy/tests/ui/print_stderr.rs
+++ b/src/tools/clippy/tests/ui/print_stderr.rs
@@ -2,7 +2,10 @@
fn main() {
eprintln!("Hello");
+ //~^ ERROR: use of `eprintln!`
+ //~| NOTE: `-D clippy::print-stderr` implied by `-D warnings`
println!("This should not do anything");
eprint!("World");
+ //~^ ERROR: use of `eprint!`
print!("Nor should this");
}
diff --git a/src/tools/clippy/tests/ui/print_stderr.stderr b/src/tools/clippy/tests/ui/print_stderr.stderr
index 5af735af6..7de163310 100644
--- a/src/tools/clippy/tests/ui/print_stderr.stderr
+++ b/src/tools/clippy/tests/ui/print_stderr.stderr
@@ -5,9 +5,10 @@ LL | eprintln!("Hello");
| ^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::print-stderr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_stderr)]`
error: use of `eprint!`
- --> $DIR/print_stderr.rs:6:5
+ --> $DIR/print_stderr.rs:8:5
|
LL | eprint!("World");
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/print_with_newline.fixed b/src/tools/clippy/tests/ui/print_with_newline.fixed
index 6098dea39..7ac6d2870 100644
--- a/src/tools/clippy/tests/ui/print_with_newline.fixed
+++ b/src/tools/clippy/tests/ui/print_with_newline.fixed
@@ -1,15 +1,20 @@
// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934
-//@run-rustfix
#![allow(clippy::print_literal)]
#![warn(clippy::print_with_newline)]
fn main() {
println!("Hello");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
+ //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings`
println!("Hello {}", "world");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
println!("Hello {} {}", "world", "#2");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
println!("{}", 1265);
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
println!();
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
// these are all fine
print!("");
@@ -23,29 +28,38 @@ fn main() {
print!("\n\n");
print!("like eof\n\n");
print!("Hello {} {}\n\n", "world", "#2");
- println!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
- println!("\nbla\n\n"); // #3126
+ // #3126
+ println!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n");
+ // #3126
+ println!("\nbla\n\n");
// Escaping
- print!("\\n"); // #3514
- println!("\\"); // should fail
+ // #3514
+ print!("\\n");
+ println!("\\");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
print!("\\\\n");
// Raw strings
- print!(r"\n"); // #3778
+ // #3778
+ print!(r"\n");
// Literal newlines should also fail
println!(
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
);
println!(
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
);
// Don't warn on CRLF (#4208)
print!("\r\n");
print!("foo\r\n");
- println!("\\r"); // should fail
+ // should fail
+ println!("\\r");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
print!("foo\rbar\n");
// Ignore expanded format strings
diff --git a/src/tools/clippy/tests/ui/print_with_newline.rs b/src/tools/clippy/tests/ui/print_with_newline.rs
index d9c7acc27..602d1ea3e 100644
--- a/src/tools/clippy/tests/ui/print_with_newline.rs
+++ b/src/tools/clippy/tests/ui/print_with_newline.rs
@@ -1,15 +1,20 @@
// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934
-//
#![allow(clippy::print_literal)]
#![warn(clippy::print_with_newline)]
fn main() {
print!("Hello\n");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
+ //~| NOTE: `-D clippy::print-with-newline` implied by `-D warnings`
print!("Hello {}\n", "world");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
print!("Hello {} {}\n", "world", "#2");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
print!("{}\n", 1265);
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
print!("\n");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
// these are all fine
print!("");
@@ -23,23 +28,30 @@ fn main() {
print!("\n\n");
print!("like eof\n\n");
print!("Hello {} {}\n\n", "world", "#2");
- println!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
- println!("\nbla\n\n"); // #3126
+ // #3126
+ println!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n");
+ // #3126
+ println!("\nbla\n\n");
// Escaping
- print!("\\n"); // #3514
- print!("\\\n"); // should fail
+ // #3514
+ print!("\\n");
+ print!("\\\n");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
print!("\\\\n");
// Raw strings
- print!(r"\n"); // #3778
+ // #3778
+ print!(r"\n");
// Literal newlines should also fail
print!(
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
"
"
);
print!(
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
r"
"
);
@@ -47,7 +59,9 @@ fn main() {
// Don't warn on CRLF (#4208)
print!("\r\n");
print!("foo\r\n");
- print!("\\r\n"); // should fail
+ // should fail
+ print!("\\r\n");
+ //~^ ERROR: using `print!()` with a format string that ends in a single newline
print!("foo\rbar\n");
// Ignore expanded format strings
diff --git a/src/tools/clippy/tests/ui/print_with_newline.stderr b/src/tools/clippy/tests/ui/print_with_newline.stderr
index b97711e77..7ff6a5f06 100644
--- a/src/tools/clippy/tests/ui/print_with_newline.stderr
+++ b/src/tools/clippy/tests/ui/print_with_newline.stderr
@@ -1,80 +1,82 @@
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:8:5
+ --> $DIR/print_with_newline.rs:7:5
|
-LL | print!("Hello/n");
+LL | print!("Hello\n");
| ^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::print-with-newline` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::print_with_newline)]`
help: use `println!` instead
|
-LL - print!("Hello/n");
+LL - print!("Hello\n");
LL + println!("Hello");
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:9:5
+ --> $DIR/print_with_newline.rs:10:5
|
-LL | print!("Hello {}/n", "world");
+LL | print!("Hello {}\n", "world");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `println!` instead
|
-LL - print!("Hello {}/n", "world");
+LL - print!("Hello {}\n", "world");
LL + println!("Hello {}", "world");
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:10:5
+ --> $DIR/print_with_newline.rs:12:5
|
-LL | print!("Hello {} {}/n", "world", "#2");
+LL | print!("Hello {} {}\n", "world", "#2");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `println!` instead
|
-LL - print!("Hello {} {}/n", "world", "#2");
+LL - print!("Hello {} {}\n", "world", "#2");
LL + println!("Hello {} {}", "world", "#2");
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:11:5
+ --> $DIR/print_with_newline.rs:14:5
|
-LL | print!("{}/n", 1265);
+LL | print!("{}\n", 1265);
| ^^^^^^^^^^^^^^^^^^^^
|
help: use `println!` instead
|
-LL - print!("{}/n", 1265);
+LL - print!("{}\n", 1265);
LL + println!("{}", 1265);
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:12:5
+ --> $DIR/print_with_newline.rs:16:5
|
-LL | print!("/n");
+LL | print!("\n");
| ^^^^^^^^^^^^
|
help: use `println!` instead
|
-LL - print!("/n");
+LL - print!("\n");
LL + println!();
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:31:5
+ --> $DIR/print_with_newline.rs:39:5
|
-LL | print!("///n"); // should fail
+LL | print!("\\\n");
| ^^^^^^^^^^^^^^
|
help: use `println!` instead
|
-LL - print!("///n"); // should fail
-LL + println!("//"); // should fail
+LL - print!("\\\n");
+LL + println!("\\");
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:38:5
+ --> $DIR/print_with_newline.rs:48:5
|
LL | / print!(
+LL | |
LL | | "
LL | | "
LL | | );
@@ -83,13 +85,15 @@ LL | | );
help: use `println!` instead
|
LL ~ println!(
+LL |
LL ~
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:42:5
+ --> $DIR/print_with_newline.rs:53:5
|
LL | / print!(
+LL | |
LL | | r"
LL | | "
LL | | );
@@ -98,19 +102,20 @@ LL | | );
help: use `println!` instead
|
LL ~ println!(
+LL |
LL ~
|
error: using `print!()` with a format string that ends in a single newline
- --> $DIR/print_with_newline.rs:50:5
+ --> $DIR/print_with_newline.rs:63:5
|
-LL | print!("//r/n"); // should fail
+LL | print!("\\r\n");
| ^^^^^^^^^^^^^^^
|
help: use `println!` instead
|
-LL - print!("//r/n"); // should fail
-LL + println!("//r"); // should fail
+LL - print!("\\r\n");
+LL + println!("\\r");
|
error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/println_empty_string.fixed b/src/tools/clippy/tests/ui/println_empty_string.fixed
index abf951ae2..20811fc75 100644
--- a/src/tools/clippy/tests/ui/println_empty_string.fixed
+++ b/src/tools/clippy/tests/ui/println_empty_string.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::match_single_binding)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/println_empty_string.rs b/src/tools/clippy/tests/ui/println_empty_string.rs
index fd86e2543..47f7277dc 100644
--- a/src/tools/clippy/tests/ui/println_empty_string.rs
+++ b/src/tools/clippy/tests/ui/println_empty_string.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::match_single_binding)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/println_empty_string.stderr b/src/tools/clippy/tests/ui/println_empty_string.stderr
index 3cc8bb947..c89e64f66 100644
--- a/src/tools/clippy/tests/ui/println_empty_string.stderr
+++ b/src/tools/clippy/tests/ui/println_empty_string.stderr
@@ -1,5 +1,5 @@
error: empty string literal in `println!`
- --> $DIR/println_empty_string.rs:6:5
+ --> $DIR/println_empty_string.rs:5:5
|
LL | println!("");
| ^^^^^^^^^--^
@@ -7,9 +7,10 @@ LL | println!("");
| help: remove the empty string
|
= note: `-D clippy::println-empty-string` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]`
error: empty string literal in `println!`
- --> $DIR/println_empty_string.rs:9:14
+ --> $DIR/println_empty_string.rs:8:14
|
LL | _ => println!(""),
| ^^^^^^^^^--^
@@ -17,7 +18,7 @@ LL | _ => println!(""),
| help: remove the empty string
error: empty string literal in `eprintln!`
- --> $DIR/println_empty_string.rs:13:5
+ --> $DIR/println_empty_string.rs:12:5
|
LL | eprintln!("");
| ^^^^^^^^^^--^
@@ -25,7 +26,7 @@ LL | eprintln!("");
| help: remove the empty string
error: empty string literal in `eprintln!`
- --> $DIR/println_empty_string.rs:16:14
+ --> $DIR/println_empty_string.rs:15:14
|
LL | _ => eprintln!(""),
| ^^^^^^^^^^--^
diff --git a/src/tools/clippy/tests/ui/proc_macro.rs b/src/tools/clippy/tests/ui/proc_macro.rs
index b77874034..e5b155dd1 100644
--- a/src/tools/clippy/tests/ui/proc_macro.rs
+++ b/src/tools/clippy/tests/ui/proc_macro.rs
@@ -7,6 +7,7 @@ use proc_macro::TokenStream;
#[allow(dead_code)]
fn f() {
let _x = 3.14;
+ //~^ ERROR: approximate value of `f{32, 64}::consts::PI` found
}
#[proc_macro]
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index 08075c382..91e2e7fd6 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.rs
+++ b/src/tools/clippy/tests/ui/ptr_arg.rs
@@ -7,31 +7,38 @@
clippy::needless_pass_by_ref_mut
)]
#![warn(clippy::ptr_arg)]
-
+//@no-rustfix
use std::borrow::Cow;
use std::path::{Path, PathBuf};
fn do_vec(x: &Vec<i64>) {
+ //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
+ //~| NOTE: `-D clippy::ptr-arg` implied by `-D warnings`
//Nothing here
}
fn do_vec_mut(x: &mut Vec<i64>) {
+ //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w
//Nothing here
}
fn do_str(x: &String) {
+ //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d
//Nothing here either
}
fn do_str_mut(x: &mut String) {
+ //~^ ERROR: writing `&mut String` instead of `&mut str` involves a new object where a slic
//Nothing here either
}
fn do_path(x: &PathBuf) {
+ //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice will
//Nothing here either
}
fn do_path_mut(x: &mut PathBuf) {
+ //~^ ERROR: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a sl
//Nothing here either
}
@@ -40,6 +47,7 @@ fn main() {}
trait Foo {
type Item;
fn do_vec(x: &Vec<i64>);
+ //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will
fn do_item(x: &Self::Item);
}
@@ -53,6 +61,7 @@ impl Foo for Bar {
}
fn cloned(x: &Vec<u8>) -> Vec<u8> {
+ //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
let e = x.clone();
let f = e.clone(); // OK
let g = x;
@@ -62,6 +71,7 @@ fn cloned(x: &Vec<u8>) -> Vec<u8> {
}
fn str_cloned(x: &String) -> String {
+ //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d
let a = x.clone();
let b = x.clone();
let c = b.clone();
@@ -70,6 +80,7 @@ fn str_cloned(x: &String) -> String {
}
fn path_cloned(x: &PathBuf) -> PathBuf {
+ //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice will
let a = x.clone();
let b = x.clone();
let c = b.clone();
@@ -78,6 +89,7 @@ fn path_cloned(x: &PathBuf) -> PathBuf {
}
fn false_positive_capacity(x: &Vec<u8>, y: &String) {
+ //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice will d
let a = x.capacity();
let b = y.clone();
let c = y.as_str();
@@ -92,6 +104,7 @@ fn false_positive_capacity_too(x: &String) -> String {
#[allow(dead_code)]
fn test_cow_with_ref(c: &Cow<[i32]>) {}
+//~^ ERROR: using a reference to `Cow` is not recommended
fn test_cow(c: Cow<[i32]>) {
let _c = c;
@@ -121,6 +134,7 @@ mod issue_5644 {
}
fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
+ //~^ ERROR: writing `&String` instead of `&str` involves a new object where a slice wi
struct S;
impl S {
@@ -150,22 +164,26 @@ mod issue6509 {
use std::path::PathBuf;
fn foo_vec(vec: &Vec<u8>) {
+ //~^ ERROR: writing `&Vec` instead of `&[_]` involves a new object where a slice will
let _ = vec.clone().pop();
let _ = vec.clone().clone();
}
fn foo_path(path: &PathBuf) {
+ //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice
let _ = path.clone().pop();
let _ = path.clone().clone();
}
fn foo_str(str: &PathBuf) {
+ //~^ ERROR: writing `&PathBuf` instead of `&Path` involves a new object where a slice
let _ = str.clone().pop();
let _ = str.clone().clone();
}
}
fn mut_vec_slice_methods(v: &mut Vec<u32>) {
+ //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w
v.copy_within(1..5, 10);
}
@@ -228,6 +246,9 @@ fn dyn_trait_ok(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
}
fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
+ //~^ ERROR: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice w
+ //~| ERROR: writing `&mut String` instead of `&mut str` involves a new object where a slic
+ //~| ERROR: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a sl
trait T {}
impl<U> T for Vec<U> {}
impl<U> T for [U] {}
@@ -251,14 +272,17 @@ mod issue_9218 {
// This one has an anonymous lifetime so it's not okay
fn cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str {
+ //~^ ERROR: using a reference to `Cow` is not recommended
todo!()
}
// These two's return types don't use use 'a so it's not okay
fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str {
+ //~^ ERROR: using a reference to `Cow` is not recommended
todo!()
}
fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {
+ //~^ ERROR: using a reference to `Cow` is not recommended
todo!()
}
diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr
index 0e9dd760f..cccf2d62d 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.stderr
+++ b/src/tools/clippy/tests/ui/ptr_arg.stderr
@@ -5,45 +5,46 @@ LL | fn do_vec(x: &Vec<i64>) {
| ^^^^^^^^^ help: change this to: `&[i64]`
|
= note: `-D clippy::ptr-arg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ptr_arg)]`
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:18:18
+ --> $DIR/ptr_arg.rs:20:18
|
LL | fn do_vec_mut(x: &mut Vec<i64>) {
| ^^^^^^^^^^^^^ help: change this to: `&mut [i64]`
error: writing `&String` instead of `&str` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:22:14
+ --> $DIR/ptr_arg.rs:25:14
|
LL | fn do_str(x: &String) {
| ^^^^^^^ help: change this to: `&str`
error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:26:18
+ --> $DIR/ptr_arg.rs:30:18
|
LL | fn do_str_mut(x: &mut String) {
| ^^^^^^^^^^^ help: change this to: `&mut str`
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:30:15
+ --> $DIR/ptr_arg.rs:35:15
|
LL | fn do_path(x: &PathBuf) {
| ^^^^^^^^ help: change this to: `&Path`
error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:34:19
+ --> $DIR/ptr_arg.rs:40:19
|
LL | fn do_path_mut(x: &mut PathBuf) {
| ^^^^^^^^^^^^ help: change this to: `&mut Path`
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:42:18
+ --> $DIR/ptr_arg.rs:49:18
|
LL | fn do_vec(x: &Vec<i64>);
| ^^^^^^^^^ help: change this to: `&[i64]`
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:55:14
+ --> $DIR/ptr_arg.rs:63:14
|
LL | fn cloned(x: &Vec<u8>) -> Vec<u8> {
| ^^^^^^^^
@@ -51,6 +52,7 @@ LL | fn cloned(x: &Vec<u8>) -> Vec<u8> {
help: change this to
|
LL ~ fn cloned(x: &[u8]) -> Vec<u8> {
+LL |
LL ~ let e = x.to_owned();
LL | let f = e.clone(); // OK
LL | let g = x;
@@ -60,7 +62,7 @@ LL ~ x.to_owned()
|
error: writing `&String` instead of `&str` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:64:18
+ --> $DIR/ptr_arg.rs:73:18
|
LL | fn str_cloned(x: &String) -> String {
| ^^^^^^^
@@ -68,6 +70,7 @@ LL | fn str_cloned(x: &String) -> String {
help: change this to
|
LL ~ fn str_cloned(x: &str) -> String {
+LL |
LL ~ let a = x.to_owned();
LL ~ let b = x.to_owned();
LL | let c = b.clone();
@@ -76,7 +79,7 @@ LL ~ x.to_owned()
|
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:72:19
+ --> $DIR/ptr_arg.rs:82:19
|
LL | fn path_cloned(x: &PathBuf) -> PathBuf {
| ^^^^^^^^
@@ -84,6 +87,7 @@ LL | fn path_cloned(x: &PathBuf) -> PathBuf {
help: change this to
|
LL ~ fn path_cloned(x: &Path) -> PathBuf {
+LL |
LL ~ let a = x.to_path_buf();
LL ~ let b = x.to_path_buf();
LL | let c = b.clone();
@@ -92,7 +96,7 @@ LL ~ x.to_path_buf()
|
error: writing `&String` instead of `&str` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:80:44
+ --> $DIR/ptr_arg.rs:91:44
|
LL | fn false_positive_capacity(x: &Vec<u8>, y: &String) {
| ^^^^^^^
@@ -100,25 +104,26 @@ LL | fn false_positive_capacity(x: &Vec<u8>, y: &String) {
help: change this to
|
LL ~ fn false_positive_capacity(x: &Vec<u8>, y: &str) {
+LL |
LL | let a = x.capacity();
LL ~ let b = y.to_owned();
LL ~ let c = y;
|
error: using a reference to `Cow` is not recommended
- --> $DIR/ptr_arg.rs:94:25
+ --> $DIR/ptr_arg.rs:106:25
|
LL | fn test_cow_with_ref(c: &Cow<[i32]>) {}
| ^^^^^^^^^^^ help: change this to: `&[i32]`
error: writing `&String` instead of `&str` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:123:66
+ --> $DIR/ptr_arg.rs:136:66
|
LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
| ^^^^^^^ help: change this to: `&str`
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:152:21
+ --> $DIR/ptr_arg.rs:166:21
|
LL | fn foo_vec(vec: &Vec<u8>) {
| ^^^^^^^^
@@ -126,12 +131,13 @@ LL | fn foo_vec(vec: &Vec<u8>) {
help: change this to
|
LL ~ fn foo_vec(vec: &[u8]) {
+LL |
LL ~ let _ = vec.to_owned().pop();
LL ~ let _ = vec.to_owned().clone();
|
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:157:23
+ --> $DIR/ptr_arg.rs:172:23
|
LL | fn foo_path(path: &PathBuf) {
| ^^^^^^^^
@@ -139,12 +145,13 @@ LL | fn foo_path(path: &PathBuf) {
help: change this to
|
LL ~ fn foo_path(path: &Path) {
+LL |
LL ~ let _ = path.to_path_buf().pop();
LL ~ let _ = path.to_path_buf().clone();
|
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:162:21
+ --> $DIR/ptr_arg.rs:178:21
|
LL | fn foo_str(str: &PathBuf) {
| ^^^^^^^^
@@ -152,48 +159,49 @@ LL | fn foo_str(str: &PathBuf) {
help: change this to
|
LL ~ fn foo_str(str: &Path) {
+LL |
LL ~ let _ = str.to_path_buf().pop();
LL ~ let _ = str.to_path_buf().clone();
|
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:168:29
+ --> $DIR/ptr_arg.rs:185:29
|
LL | fn mut_vec_slice_methods(v: &mut Vec<u32>) {
| ^^^^^^^^^^^^^ help: change this to: `&mut [u32]`
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:230:17
+ --> $DIR/ptr_arg.rs:248:17
|
LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
| ^^^^^^^^^^^^^ help: change this to: `&mut [u32]`
error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:230:35
+ --> $DIR/ptr_arg.rs:248:35
|
LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
| ^^^^^^^^^^^ help: change this to: `&mut str`
error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do
- --> $DIR/ptr_arg.rs:230:51
+ --> $DIR/ptr_arg.rs:248:51
|
LL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {
| ^^^^^^^^^^^^ help: change this to: `&mut Path`
error: using a reference to `Cow` is not recommended
- --> $DIR/ptr_arg.rs:253:39
+ --> $DIR/ptr_arg.rs:274:39
|
LL | fn cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str {
| ^^^^^^^^^^^^ help: change this to: `&str`
error: using a reference to `Cow` is not recommended
- --> $DIR/ptr_arg.rs:258:36
+ --> $DIR/ptr_arg.rs:280:36
|
LL | fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str {
| ^^^^^^^^^^^^^^^^ help: change this to: `&str`
error: using a reference to `Cow` is not recommended
- --> $DIR/ptr_arg.rs:261:40
+ --> $DIR/ptr_arg.rs:284:40
|
LL | fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {
| ^^^^^^^^^^^^^^^^ help: change this to: `&str`
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
index 84babb974..ca13b52ae 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::ptr_as_ptr)]
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
index 34fd76428..942c87344 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::ptr_as_ptr)]
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
index e64f33515..c0ce69b43 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
@@ -1,43 +1,44 @@
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:19:33
+ --> $DIR/ptr_as_ptr.rs:18:33
|
LL | *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()`
|
= note: `-D clippy::ptr-as-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:28:13
+ --> $DIR/ptr_as_ptr.rs:27:13
|
LL | let _ = ptr as *const i32;
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:29:13
+ --> $DIR/ptr_as_ptr.rs:28:13
|
LL | let _ = mut_ptr as *mut i32;
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:34:17
+ --> $DIR/ptr_as_ptr.rs:33:17
|
LL | let _ = *ptr_ptr as *const i32;
| ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:47:25
+ --> $DIR/ptr_as_ptr.rs:46:25
|
LL | let _: *const i32 = ptr as *const _;
| ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:48:23
+ --> $DIR/ptr_as_ptr.rs:47:23
|
LL | let _: *mut i32 = mut_ptr as _;
| ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:51:21
+ --> $DIR/ptr_as_ptr.rs:50:21
|
LL | let _ = inline!($ptr as *const i32);
| ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
@@ -45,13 +46,13 @@ LL | let _ = inline!($ptr as *const i32);
= note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:72:13
+ --> $DIR/ptr_as_ptr.rs:71:13
|
LL | let _ = ptr as *const i32;
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:73:13
+ --> $DIR/ptr_as_ptr.rs:72:13
|
LL | let _ = mut_ptr as *mut i32;
| ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
index 1ef1809d1..c410a660d 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::ptr_cast_constness)]
#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)]
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.rs b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
index 2c15cd429..6025b857b 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.rs
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::ptr_cast_constness)]
#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)]
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
index 0c3ff8636..a4bf778ad 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
@@ -1,43 +1,44 @@
error: `as` casting between raw pointers while changing only its constness
- --> $DIR/ptr_cast_constness.rs:11:41
+ --> $DIR/ptr_cast_constness.rs:10:41
|
LL | let _: &mut T = std::mem::transmute(p as *mut T);
| ^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()`
|
= note: `-D clippy::ptr-cast-constness` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ptr_cast_constness)]`
error: `as` casting between raw pointers while changing only its constness
- --> $DIR/ptr_cast_constness.rs:12:19
+ --> $DIR/ptr_cast_constness.rs:11:19
|
LL | let _ = &mut *(p as *mut T);
| ^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()`
error: `as` casting between raw pointers while changing only its constness
- --> $DIR/ptr_cast_constness.rs:27:17
+ --> $DIR/ptr_cast_constness.rs:26:17
|
LL | let _ = *ptr_ptr as *mut u32;
| ^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(*ptr_ptr).cast_mut()`
error: `as` casting between raw pointers while changing only its constness
- --> $DIR/ptr_cast_constness.rs:30:13
+ --> $DIR/ptr_cast_constness.rs:29:13
|
LL | let _ = ptr as *mut u32;
| ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
error: `as` casting between raw pointers while changing only its constness
- --> $DIR/ptr_cast_constness.rs:31:13
+ --> $DIR/ptr_cast_constness.rs:30:13
|
LL | let _ = mut_ptr as *const u32;
| ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
error: `as` casting between raw pointers while changing only its constness
- --> $DIR/ptr_cast_constness.rs:60:13
+ --> $DIR/ptr_cast_constness.rs:59:13
|
LL | let _ = ptr as *mut u32;
| ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
error: `as` casting between raw pointers while changing only its constness
- --> $DIR/ptr_cast_constness.rs:61:13
+ --> $DIR/ptr_cast_constness.rs:60:13
|
LL | let _ = mut_ptr as *const u32;
| ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
diff --git a/src/tools/clippy/tests/ui/ptr_eq.fixed b/src/tools/clippy/tests/ui/ptr_eq.fixed
index d5fa273d4..3ae6df18c 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.fixed
+++ b/src/tools/clippy/tests/ui/ptr_eq.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::ptr_eq)]
macro_rules! mac {
diff --git a/src/tools/clippy/tests/ui/ptr_eq.rs b/src/tools/clippy/tests/ui/ptr_eq.rs
index e033366a4..440d5d94a 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.rs
+++ b/src/tools/clippy/tests/ui/ptr_eq.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::ptr_eq)]
macro_rules! mac {
diff --git a/src/tools/clippy/tests/ui/ptr_eq.stderr b/src/tools/clippy/tests/ui/ptr_eq.stderr
index 45d8c6038..2a384acca 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.stderr
+++ b/src/tools/clippy/tests/ui/ptr_eq.stderr
@@ -1,13 +1,14 @@
error: use `std::ptr::eq` when comparing raw pointers
- --> $DIR/ptr_eq.rs:20:13
+ --> $DIR/ptr_eq.rs:19:13
|
LL | let _ = a as *const _ as usize == b as *const _ as usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`
|
= note: `-D clippy::ptr-eq` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]`
error: use `std::ptr::eq` when comparing raw pointers
- --> $DIR/ptr_eq.rs:21:13
+ --> $DIR/ptr_eq.rs:20:13
|
LL | let _ = a as *const _ == b as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`
diff --git a/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed b/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed
index 6ffa401d7..929512be6 100644
--- a/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed
+++ b/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::unnecessary_cast, clippy::useless_vec)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs b/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs
index de1f86cb8..146bc2776 100644
--- a/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs
+++ b/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::unnecessary_cast, clippy::useless_vec)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/ptr_offset_with_cast.stderr b/src/tools/clippy/tests/ui/ptr_offset_with_cast.stderr
index 3ba40593d..e99053846 100644
--- a/src/tools/clippy/tests/ui/ptr_offset_with_cast.stderr
+++ b/src/tools/clippy/tests/ui/ptr_offset_with_cast.stderr
@@ -1,13 +1,14 @@
error: use of `offset` with a `usize` casted to an `isize`
- --> $DIR/ptr_offset_with_cast.rs:13:17
+ --> $DIR/ptr_offset_with_cast.rs:12:17
|
LL | let _ = ptr.offset(offset_usize as isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr.add(offset_usize)`
|
= note: `-D clippy::ptr-offset-with-cast` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ptr_offset_with_cast)]`
error: use of `wrapping_offset` with a `usize` casted to an `isize`
- --> $DIR/ptr_offset_with_cast.rs:17:17
+ --> $DIR/ptr_offset_with_cast.rs:16:17
|
LL | let _ = ptr.wrapping_offset(offset_usize as isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr.wrapping_add(offset_usize)`
diff --git a/src/tools/clippy/tests/ui/pub_use.rs b/src/tools/clippy/tests/ui/pub_use.rs
index 65542bede..aef947e40 100644
--- a/src/tools/clippy/tests/ui/pub_use.rs
+++ b/src/tools/clippy/tests/ui/pub_use.rs
@@ -8,6 +8,7 @@ pub mod outer {
}
// should be linted
pub use inner::Test;
+ //~^ ERROR: using `pub use`
}
// should not be linted
diff --git a/src/tools/clippy/tests/ui/pub_use.stderr b/src/tools/clippy/tests/ui/pub_use.stderr
index ba4ee732c..781572736 100644
--- a/src/tools/clippy/tests/ui/pub_use.stderr
+++ b/src/tools/clippy/tests/ui/pub_use.stderr
@@ -6,6 +6,7 @@ LL | pub use inner::Test;
|
= help: move the exported item to a public module instead
= note: `-D clippy::pub-use` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pub_use)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/pub_with_shorthand.fixed b/src/tools/clippy/tests/ui/pub_with_shorthand.fixed
index a774faa0a..028209de0 100644
--- a/src/tools/clippy/tests/ui/pub_with_shorthand.fixed
+++ b/src/tools/clippy/tests/ui/pub_with_shorthand.fixed
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(clippy::needless_pub_self, unused)]
#![warn(clippy::pub_with_shorthand)]
diff --git a/src/tools/clippy/tests/ui/pub_with_shorthand.rs b/src/tools/clippy/tests/ui/pub_with_shorthand.rs
index 4a4bbc187..8578e3e0c 100644
--- a/src/tools/clippy/tests/ui/pub_with_shorthand.rs
+++ b/src/tools/clippy/tests/ui/pub_with_shorthand.rs
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(clippy::needless_pub_self, unused)]
#![warn(clippy::pub_with_shorthand)]
diff --git a/src/tools/clippy/tests/ui/pub_with_shorthand.stderr b/src/tools/clippy/tests/ui/pub_with_shorthand.stderr
index 323b5a23b..423b05080 100644
--- a/src/tools/clippy/tests/ui/pub_with_shorthand.stderr
+++ b/src/tools/clippy/tests/ui/pub_with_shorthand.stderr
@@ -5,6 +5,7 @@ LL | pub(self) fn a() {}
| ^^^^^^^^^ help: add it: `pub(in self)`
|
= note: `-D clippy::pub-with-shorthand` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pub_with_shorthand)]`
error: usage of `pub` without `in`
--> $DIR/pub_with_shorthand.rs:19:5
diff --git a/src/tools/clippy/tests/ui/pub_without_shorthand.fixed b/src/tools/clippy/tests/ui/pub_without_shorthand.fixed
index fdb49ac4d..715e86c17 100644
--- a/src/tools/clippy/tests/ui/pub_without_shorthand.fixed
+++ b/src/tools/clippy/tests/ui/pub_without_shorthand.fixed
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(clippy::needless_pub_self, unused)]
#![warn(clippy::pub_without_shorthand)]
diff --git a/src/tools/clippy/tests/ui/pub_without_shorthand.rs b/src/tools/clippy/tests/ui/pub_without_shorthand.rs
index 1f2ef7ece..ed2fd6f0f 100644
--- a/src/tools/clippy/tests/ui/pub_without_shorthand.rs
+++ b/src/tools/clippy/tests/ui/pub_without_shorthand.rs
@@ -1,5 +1,5 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+
+//@aux-build:proc_macros.rs
#![feature(custom_inner_attributes)]
#![allow(clippy::needless_pub_self, unused)]
#![warn(clippy::pub_without_shorthand)]
diff --git a/src/tools/clippy/tests/ui/pub_without_shorthand.stderr b/src/tools/clippy/tests/ui/pub_without_shorthand.stderr
index a18c9bf89..4fb11cb3d 100644
--- a/src/tools/clippy/tests/ui/pub_without_shorthand.stderr
+++ b/src/tools/clippy/tests/ui/pub_without_shorthand.stderr
@@ -5,6 +5,7 @@ LL | pub(in self) fn b() {}
| ^^^^^^^^^^^^ help: remove it: `pub(self)`
|
= note: `-D clippy::pub-without-shorthand` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::pub_without_shorthand)]`
error: usage of `pub` with `in`
--> $DIR/pub_without_shorthand.rs:18:5
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 20b9e42a7..2ef006c14 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(try_blocks)]
#![allow(unreachable_code)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index 8bdafd46e..c17066982 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![feature(try_blocks)]
#![allow(unreachable_code)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/question_mark.stderr b/src/tools/clippy/tests/ui/question_mark.stderr
index 62489c8c8..7b7b85d08 100644
--- a/src/tools/clippy/tests/ui/question_mark.stderr
+++ b/src/tools/clippy/tests/ui/question_mark.stderr
@@ -1,5 +1,5 @@
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:8:5
+ --> $DIR/question_mark.rs:7:5
|
LL | / if a.is_none() {
LL | | return None;
@@ -7,9 +7,10 @@ LL | | }
| |_____^ help: replace it with: `a?;`
|
= note: `-D clippy::question-mark` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::question_mark)]`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:53:9
+ --> $DIR/question_mark.rs:52:9
|
LL | / if (self.opt).is_none() {
LL | | return None;
@@ -17,7 +18,7 @@ LL | | }
| |_________^ help: replace it with: `(self.opt)?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:57:9
+ --> $DIR/question_mark.rs:56:9
|
LL | / if self.opt.is_none() {
LL | | return None
@@ -25,7 +26,7 @@ LL | | }
| |_________^ help: replace it with: `self.opt?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:61:17
+ --> $DIR/question_mark.rs:60:17
|
LL | let _ = if self.opt.is_none() {
| _________________^
@@ -36,7 +37,7 @@ LL | | };
| |_________^ help: replace it with: `Some(self.opt?)`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:67:17
+ --> $DIR/question_mark.rs:66:17
|
LL | let _ = if let Some(x) = self.opt {
| _________________^
@@ -47,7 +48,7 @@ LL | | };
| |_________^ help: replace it with: `self.opt?`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:84:9
+ --> $DIR/question_mark.rs:83:9
|
LL | / if self.opt.is_none() {
LL | | return None;
@@ -55,7 +56,7 @@ LL | | }
| |_________^ help: replace it with: `self.opt.as_ref()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:92:9
+ --> $DIR/question_mark.rs:91:9
|
LL | / if self.opt.is_none() {
LL | | return None;
@@ -63,7 +64,7 @@ LL | | }
| |_________^ help: replace it with: `self.opt.as_ref()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:100:9
+ --> $DIR/question_mark.rs:99:9
|
LL | / if self.opt.is_none() {
LL | | return None;
@@ -71,7 +72,7 @@ LL | | }
| |_________^ help: replace it with: `self.opt.as_ref()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:107:26
+ --> $DIR/question_mark.rs:106:26
|
LL | let v: &Vec<_> = if let Some(ref v) = self.opt {
| __________________________^
@@ -82,7 +83,7 @@ LL | | };
| |_________^ help: replace it with: `self.opt.as_ref()?`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:117:17
+ --> $DIR/question_mark.rs:116:17
|
LL | let v = if let Some(v) = self.opt {
| _________________^
@@ -93,7 +94,7 @@ LL | | };
| |_________^ help: replace it with: `self.opt?`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:132:5
+ --> $DIR/question_mark.rs:131:5
|
LL | / if f().is_none() {
LL | | return None;
@@ -101,13 +102,13 @@ LL | | }
| |_____^ help: replace it with: `f()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:144:13
+ --> $DIR/question_mark.rs:143:13
|
LL | let _ = if let Ok(x) = x { x } else { return x };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x?`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:146:5
+ --> $DIR/question_mark.rs:145:5
|
LL | / if x.is_err() {
LL | | return x;
@@ -115,7 +116,7 @@ LL | | }
| |_____^ help: replace it with: `x?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:214:5
+ --> $DIR/question_mark.rs:213:5
|
LL | / if let Err(err) = func_returning_result() {
LL | | return Err(err);
@@ -123,7 +124,7 @@ LL | | }
| |_____^ help: replace it with: `func_returning_result()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:221:5
+ --> $DIR/question_mark.rs:220:5
|
LL | / if let Err(err) = func_returning_result() {
LL | | return Err(err);
@@ -131,7 +132,7 @@ LL | | }
| |_____^ help: replace it with: `func_returning_result()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:298:13
+ --> $DIR/question_mark.rs:297:13
|
LL | / if a.is_none() {
LL | | return None;
diff --git a/src/tools/clippy/tests/ui/question_mark_used.rs b/src/tools/clippy/tests/ui/question_mark_used.rs
index 8c3ef7896..715d7fab8 100644
--- a/src/tools/clippy/tests/ui/question_mark_used.rs
+++ b/src/tools/clippy/tests/ui/question_mark_used.rs
@@ -9,6 +9,7 @@ fn other_function() -> Option<i32> {
fn my_function() -> Option<i32> {
other_function()?;
+ //~^ ERROR: question mark operator was used
None
}
diff --git a/src/tools/clippy/tests/ui/question_mark_used.stderr b/src/tools/clippy/tests/ui/question_mark_used.stderr
index 8b5fcbcdb..a3f440de8 100644
--- a/src/tools/clippy/tests/ui/question_mark_used.stderr
+++ b/src/tools/clippy/tests/ui/question_mark_used.stderr
@@ -6,6 +6,7 @@ LL | other_function()?;
|
= help: consider using a custom macro or match expression
= note: `-D clippy::question-mark-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::question_mark_used)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/range.rs b/src/tools/clippy/tests/ui/range.rs
index 46edf0921..9541812b0 100644
--- a/src/tools/clippy/tests/ui/range.rs
+++ b/src/tools/clippy/tests/ui/range.rs
@@ -4,6 +4,8 @@ fn main() {
let v1 = vec![1, 2, 3];
let v2 = vec![4, 5];
let _x = v1.iter().zip(0..v1.len());
+ //~^ ERROR: it is more idiomatic to use `v1.iter().enumerate()`
+ //~| NOTE: `-D clippy::range-zip-with-len` implied by `-D warnings`
let _y = v1.iter().zip(0..v2.len()); // No error
}
diff --git a/src/tools/clippy/tests/ui/range.stderr b/src/tools/clippy/tests/ui/range.stderr
index ac83b67fd..9f174307b 100644
--- a/src/tools/clippy/tests/ui/range.stderr
+++ b/src/tools/clippy/tests/ui/range.stderr
@@ -5,6 +5,7 @@ LL | let _x = v1.iter().zip(0..v1.len());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::range-zip-with-len` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::range_zip_with_len)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/range_contains.fixed b/src/tools/clippy/tests/ui/range_contains.fixed
index 47c524811..ed248df37 100644
--- a/src/tools/clippy/tests/ui/range_contains.fixed
+++ b/src/tools/clippy/tests/ui/range_contains.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_range_contains)]
#![allow(unused)]
#![allow(clippy::no_effect)]
diff --git a/src/tools/clippy/tests/ui/range_contains.rs b/src/tools/clippy/tests/ui/range_contains.rs
index a35315a64..c3188ec6d 100644
--- a/src/tools/clippy/tests/ui/range_contains.rs
+++ b/src/tools/clippy/tests/ui/range_contains.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::manual_range_contains)]
#![allow(unused)]
#![allow(clippy::no_effect)]
diff --git a/src/tools/clippy/tests/ui/range_contains.stderr b/src/tools/clippy/tests/ui/range_contains.stderr
index 1265db695..349adea21 100644
--- a/src/tools/clippy/tests/ui/range_contains.stderr
+++ b/src/tools/clippy/tests/ui/range_contains.stderr
@@ -1,127 +1,128 @@
error: manual `Range::contains` implementation
- --> $DIR/range_contains.rs:15:5
+ --> $DIR/range_contains.rs:13:5
|
LL | x >= 8 && x < 12;
| ^^^^^^^^^^^^^^^^ help: use: `(8..12).contains(&x)`
|
= note: `-D clippy::manual-range-contains` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_range_contains)]`
error: manual `Range::contains` implementation
- --> $DIR/range_contains.rs:16:5
+ --> $DIR/range_contains.rs:14:5
|
LL | x < 42 && x >= 21;
| ^^^^^^^^^^^^^^^^^ help: use: `(21..42).contains(&x)`
error: manual `Range::contains` implementation
- --> $DIR/range_contains.rs:17:5
+ --> $DIR/range_contains.rs:15:5
|
LL | 100 > x && 1 <= x;
| ^^^^^^^^^^^^^^^^^ help: use: `(1..100).contains(&x)`
error: manual `RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:20:5
+ --> $DIR/range_contains.rs:18:5
|
LL | x >= 9 && x <= 99;
| ^^^^^^^^^^^^^^^^^ help: use: `(9..=99).contains(&x)`
error: manual `RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:21:5
+ --> $DIR/range_contains.rs:19:5
|
LL | x <= 33 && x >= 1;
| ^^^^^^^^^^^^^^^^^ help: use: `(1..=33).contains(&x)`
error: manual `RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:22:5
+ --> $DIR/range_contains.rs:20:5
|
LL | 999 >= x && 1 <= x;
| ^^^^^^^^^^^^^^^^^^ help: use: `(1..=999).contains(&x)`
error: manual `!Range::contains` implementation
- --> $DIR/range_contains.rs:25:5
+ --> $DIR/range_contains.rs:23:5
|
LL | x < 8 || x >= 12;
| ^^^^^^^^^^^^^^^^ help: use: `!(8..12).contains(&x)`
error: manual `!Range::contains` implementation
- --> $DIR/range_contains.rs:26:5
+ --> $DIR/range_contains.rs:24:5
|
LL | x >= 42 || x < 21;
| ^^^^^^^^^^^^^^^^^ help: use: `!(21..42).contains(&x)`
error: manual `!Range::contains` implementation
- --> $DIR/range_contains.rs:27:5
+ --> $DIR/range_contains.rs:25:5
|
LL | 100 <= x || 1 > x;
| ^^^^^^^^^^^^^^^^^ help: use: `!(1..100).contains(&x)`
error: manual `!RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:30:5
+ --> $DIR/range_contains.rs:28:5
|
LL | x < 9 || x > 99;
| ^^^^^^^^^^^^^^^ help: use: `!(9..=99).contains(&x)`
error: manual `!RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:31:5
+ --> $DIR/range_contains.rs:29:5
|
LL | x > 33 || x < 1;
| ^^^^^^^^^^^^^^^ help: use: `!(1..=33).contains(&x)`
error: manual `!RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:32:5
+ --> $DIR/range_contains.rs:30:5
|
LL | 999 < x || 1 > x;
| ^^^^^^^^^^^^^^^^ help: use: `!(1..=999).contains(&x)`
error: manual `Range::contains` implementation
- --> $DIR/range_contains.rs:47:5
+ --> $DIR/range_contains.rs:45:5
|
LL | y >= 0. && y < 1.;
| ^^^^^^^^^^^^^^^^^ help: use: `(0. ..1.).contains(&y)`
error: manual `!RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:48:5
+ --> $DIR/range_contains.rs:46:5
|
LL | y < 0. || y > 1.;
| ^^^^^^^^^^^^^^^^ help: use: `!(0. ..=1.).contains(&y)`
error: manual `RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:51:5
+ --> $DIR/range_contains.rs:49:5
|
LL | x >= -10 && x <= 10;
| ^^^^^^^^^^^^^^^^^^^ help: use: `(-10..=10).contains(&x)`
error: manual `RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:53:5
+ --> $DIR/range_contains.rs:51:5
|
LL | y >= -3. && y <= 3.;
| ^^^^^^^^^^^^^^^^^^^ help: use: `(-3. ..=3.).contains(&y)`
error: manual `RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:58:30
+ --> $DIR/range_contains.rs:56:30
|
LL | (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
| ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&z)`
error: manual `RangeInclusive::contains` implementation
- --> $DIR/range_contains.rs:58:5
+ --> $DIR/range_contains.rs:56:5
|
LL | (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
| ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&x)`
error: manual `!Range::contains` implementation
- --> $DIR/range_contains.rs:59:29
+ --> $DIR/range_contains.rs:57:29
|
LL | (x < 0) || (x >= 10) || (z < 0) || (z >= 10);
| ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&z)`
error: manual `!Range::contains` implementation
- --> $DIR/range_contains.rs:59:5
+ --> $DIR/range_contains.rs:57:5
|
LL | (x < 0) || (x >= 10) || (z < 0) || (z >= 10);
| ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&x)`
error: manual `Range::contains` implementation
- --> $DIR/range_contains.rs:78:5
+ --> $DIR/range_contains.rs:76:5
|
LL | x >= 8 && x < 35;
| ^^^^^^^^^^^^^^^^ help: use: `(8..35).contains(&x)`
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
index 79c133cb5..e701dde86 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_parens)]
#![allow(clippy::iter_with_drain)]
fn f() -> usize {
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.rs b/src/tools/clippy/tests/ui/range_plus_minus_one.rs
index 689a6b7a1..7057fa8e3 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.rs
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_parens)]
#![allow(clippy::iter_with_drain)]
fn f() -> usize {
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
index 022369624..c5c9b145d 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
@@ -1,57 +1,59 @@
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:31:14
+ --> $DIR/range_plus_minus_one.rs:29:14
|
LL | for _ in 0..3 + 1 {}
| ^^^^^^^^ help: use: `0..=3`
|
= note: `-D clippy::range-plus-one` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::range_plus_one)]`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:34:14
+ --> $DIR/range_plus_minus_one.rs:32:14
|
LL | for _ in 0..1 + 5 {}
| ^^^^^^^^ help: use: `0..=5`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:37:14
+ --> $DIR/range_plus_minus_one.rs:35:14
|
LL | for _ in 1..1 + 1 {}
| ^^^^^^^^ help: use: `1..=1`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:43:14
+ --> $DIR/range_plus_minus_one.rs:41:14
|
LL | for _ in 0..(1 + f()) {}
| ^^^^^^^^^^^^ help: use: `0..=f()`
error: an exclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:47:13
+ --> $DIR/range_plus_minus_one.rs:45:13
|
LL | let _ = ..=11 - 1;
| ^^^^^^^^^ help: use: `..11`
|
= note: `-D clippy::range-minus-one` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::range_minus_one)]`
error: an exclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:48:13
+ --> $DIR/range_plus_minus_one.rs:46:13
|
LL | let _ = ..=(11 - 1);
| ^^^^^^^^^^^ help: use: `..11`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:49:13
+ --> $DIR/range_plus_minus_one.rs:47:13
|
LL | let _ = (1..11 + 1);
| ^^^^^^^^^^^ help: use: `(1..=11)`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:50:13
+ --> $DIR/range_plus_minus_one.rs:48:13
|
LL | let _ = (f() + 1)..(f() + 1);
| ^^^^^^^^^^^^^^^^^^^^ help: use: `((f() + 1)..=f())`
error: an inclusive range would be more readable
- --> $DIR/range_plus_minus_one.rs:54:14
+ --> $DIR/range_plus_minus_one.rs:52:14
|
LL | for _ in 1..ONE + ONE {}
| ^^^^^^^^^^^^ help: use: `1..=ONE`
diff --git a/src/tools/clippy/tests/ui/rc_buffer.fixed b/src/tools/clippy/tests/ui/rc_buffer.fixed
index 4cba292c1..35ac95a76 100644
--- a/src/tools/clippy/tests/ui/rc_buffer.fixed
+++ b/src/tools/clippy/tests/ui/rc_buffer.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::rc_buffer)]
#![allow(dead_code, unused_imports)]
diff --git a/src/tools/clippy/tests/ui/rc_buffer.rs b/src/tools/clippy/tests/ui/rc_buffer.rs
index d8a9aa278..e78fb5a6d 100644
--- a/src/tools/clippy/tests/ui/rc_buffer.rs
+++ b/src/tools/clippy/tests/ui/rc_buffer.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::rc_buffer)]
#![allow(dead_code, unused_imports)]
diff --git a/src/tools/clippy/tests/ui/rc_buffer.stderr b/src/tools/clippy/tests/ui/rc_buffer.stderr
index 9ed028e3d..04080326a 100644
--- a/src/tools/clippy/tests/ui/rc_buffer.stderr
+++ b/src/tools/clippy/tests/ui/rc_buffer.stderr
@@ -1,49 +1,50 @@
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:12:11
+ --> $DIR/rc_buffer.rs:11:11
|
LL | bad1: Rc<String>,
| ^^^^^^^^^^ help: try: `Rc<str>`
|
= note: `-D clippy::rc-buffer` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]`
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:13:11
+ --> $DIR/rc_buffer.rs:12:11
|
LL | bad2: Rc<PathBuf>,
| ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:14:11
+ --> $DIR/rc_buffer.rs:13:11
|
LL | bad3: Rc<Vec<u8>>,
| ^^^^^^^^^^^ help: try: `Rc<[u8]>`
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:15:11
+ --> $DIR/rc_buffer.rs:14:11
|
LL | bad4: Rc<OsString>,
| ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:21:17
+ --> $DIR/rc_buffer.rs:20:17
|
LL | fn func_bad1(_: Rc<String>) {}
| ^^^^^^^^^^ help: try: `Rc<str>`
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:22:17
+ --> $DIR/rc_buffer.rs:21:17
|
LL | fn func_bad2(_: Rc<PathBuf>) {}
| ^^^^^^^^^^^ help: try: `Rc<std::path::Path>`
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:23:17
+ --> $DIR/rc_buffer.rs:22:17
|
LL | fn func_bad3(_: Rc<Vec<u8>>) {}
| ^^^^^^^^^^^ help: try: `Rc<[u8]>`
error: usage of `Rc<T>` when T is a buffer type
- --> $DIR/rc_buffer.rs:24:17
+ --> $DIR/rc_buffer.rs:23:17
|
LL | fn func_bad4(_: Rc<OsString>) {}
| ^^^^^^^^^^^^ help: try: `Rc<std::ffi::OsStr>`
diff --git a/src/tools/clippy/tests/ui/rc_buffer_arc.fixed b/src/tools/clippy/tests/ui/rc_buffer_arc.fixed
index ac51ac9e4..0d01c7c47 100644
--- a/src/tools/clippy/tests/ui/rc_buffer_arc.fixed
+++ b/src/tools/clippy/tests/ui/rc_buffer_arc.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::rc_buffer)]
#![allow(dead_code, unused_imports)]
diff --git a/src/tools/clippy/tests/ui/rc_buffer_arc.rs b/src/tools/clippy/tests/ui/rc_buffer_arc.rs
index 21dc27bc5..61ab16dc1 100644
--- a/src/tools/clippy/tests/ui/rc_buffer_arc.rs
+++ b/src/tools/clippy/tests/ui/rc_buffer_arc.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::rc_buffer)]
#![allow(dead_code, unused_imports)]
diff --git a/src/tools/clippy/tests/ui/rc_buffer_arc.stderr b/src/tools/clippy/tests/ui/rc_buffer_arc.stderr
index 911feea73..52522dd72 100644
--- a/src/tools/clippy/tests/ui/rc_buffer_arc.stderr
+++ b/src/tools/clippy/tests/ui/rc_buffer_arc.stderr
@@ -1,49 +1,50 @@
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:11:11
+ --> $DIR/rc_buffer_arc.rs:10:11
|
LL | bad1: Arc<String>,
| ^^^^^^^^^^^ help: try: `Arc<str>`
|
= note: `-D clippy::rc-buffer` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]`
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:12:11
+ --> $DIR/rc_buffer_arc.rs:11:11
|
LL | bad2: Arc<PathBuf>,
| ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:13:11
+ --> $DIR/rc_buffer_arc.rs:12:11
|
LL | bad3: Arc<Vec<u8>>,
| ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:14:11
+ --> $DIR/rc_buffer_arc.rs:13:11
|
LL | bad4: Arc<OsString>,
| ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:20:17
+ --> $DIR/rc_buffer_arc.rs:19:17
|
LL | fn func_bad1(_: Arc<String>) {}
| ^^^^^^^^^^^ help: try: `Arc<str>`
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:21:17
+ --> $DIR/rc_buffer_arc.rs:20:17
|
LL | fn func_bad2(_: Arc<PathBuf>) {}
| ^^^^^^^^^^^^ help: try: `Arc<std::path::Path>`
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:22:17
+ --> $DIR/rc_buffer_arc.rs:21:17
|
LL | fn func_bad3(_: Arc<Vec<u8>>) {}
| ^^^^^^^^^^^^ help: try: `Arc<[u8]>`
error: usage of `Arc<T>` when T is a buffer type
- --> $DIR/rc_buffer_arc.rs:23:17
+ --> $DIR/rc_buffer_arc.rs:22:17
|
LL | fn func_bad4(_: Arc<OsString>) {}
| ^^^^^^^^^^^^^ help: try: `Arc<std::ffi::OsStr>`
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.rs b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.rs
index 53fcbf3c4..1c9e9aa7e 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.rs
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::rc_clone_in_vec_init)]
#![allow(clippy::useless_vec)]
use std::sync::{Arc, Mutex};
@@ -6,6 +7,8 @@ fn main() {}
fn should_warn_simple_case() {
let v = vec![Arc::new("x".to_string()); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Arc` instance
}
fn should_warn_simple_case_with_big_indentation() {
@@ -14,12 +17,16 @@ fn should_warn_simple_case_with_big_indentation() {
dbg!(k);
if true {
let v = vec![Arc::new("x".to_string()); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Arc` instance
}
}
}
fn should_warn_complex_case() {
let v = vec![
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Arc` instance
std::sync::Arc::new(Mutex::new({
let x = 1;
dbg!(x);
@@ -29,6 +36,8 @@ fn should_warn_complex_case() {
];
let v1 = vec![
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Arc` instance
Arc::new(Mutex::new({
let x = 1;
dbg!(x);
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr
index a8fd28b84..5dc4b5a10 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr
@@ -1,11 +1,12 @@
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/arc.rs:8:13
+ --> $DIR/arc.rs:9:13
|
LL | let v = vec![Arc::new("x".to_string()); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: each element will point to the same `Arc` instance
= note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::rc_clone_in_vec_init)]`
help: consider initializing each `Arc` element individually
|
LL ~ let v = {
@@ -23,7 +24,7 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/arc.rs:16:21
+ --> $DIR/arc.rs:19:21
|
LL | let v = vec![Arc::new("x".to_string()); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -46,13 +47,13 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/arc.rs:22:13
+ --> $DIR/arc.rs:27:13
|
LL | let v = vec![
| _____________^
+LL | |
+LL | |
LL | | std::sync::Arc::new(Mutex::new({
-LL | | let x = 1;
-LL | | dbg!(x);
... |
LL | | 2
LL | | ];
@@ -76,13 +77,13 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/arc.rs:31:14
+ --> $DIR/arc.rs:38:14
|
LL | let v1 = vec![
| ______________^
+LL | |
+LL | |
LL | | Arc::new(Mutex::new({
-LL | | let x = 1;
-LL | | dbg!(x);
... |
LL | | 2
LL | | ];
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.rs b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.rs
index 88ea39bf9..01cc433cb 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.rs
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::rc_clone_in_vec_init)]
#![allow(clippy::useless_vec)]
use std::rc::Rc;
@@ -7,6 +8,8 @@ fn main() {}
fn should_warn_simple_case() {
let v = vec![Rc::new("x".to_string()); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Rc` instance
}
fn should_warn_simple_case_with_big_indentation() {
@@ -15,12 +18,16 @@ fn should_warn_simple_case_with_big_indentation() {
dbg!(k);
if true {
let v = vec![Rc::new("x".to_string()); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Rc` instance
}
}
}
fn should_warn_complex_case() {
let v = vec![
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Rc` instance
std::rc::Rc::new(Mutex::new({
let x = 1;
dbg!(x);
@@ -30,6 +37,8 @@ fn should_warn_complex_case() {
];
let v1 = vec![
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Rc` instance
Rc::new(Mutex::new({
let x = 1;
dbg!(x);
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr
index eab464800..e6bc6f68b 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr
@@ -1,11 +1,12 @@
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/rc.rs:9:13
+ --> $DIR/rc.rs:10:13
|
LL | let v = vec![Rc::new("x".to_string()); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: each element will point to the same `Rc` instance
= note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::rc_clone_in_vec_init)]`
help: consider initializing each `Rc` element individually
|
LL ~ let v = {
@@ -23,7 +24,7 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/rc.rs:17:21
+ --> $DIR/rc.rs:20:21
|
LL | let v = vec![Rc::new("x".to_string()); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -46,13 +47,13 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/rc.rs:23:13
+ --> $DIR/rc.rs:28:13
|
LL | let v = vec![
| _____________^
+LL | |
+LL | |
LL | | std::rc::Rc::new(Mutex::new({
-LL | | let x = 1;
-LL | | dbg!(x);
... |
LL | | 2
LL | | ];
@@ -76,13 +77,13 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/rc.rs:32:14
+ --> $DIR/rc.rs:39:14
|
LL | let v1 = vec![
| ______________^
+LL | |
+LL | |
LL | | Rc::new(Mutex::new({
-LL | | let x = 1;
-LL | | dbg!(x);
... |
LL | | 2
LL | | ];
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.rs b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.rs
index 031421650..fd2895d40 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.rs
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::rc_clone_in_vec_init)]
#![allow(clippy::useless_vec)]
use std::rc::{Rc, Weak as UnSyncWeak};
@@ -7,10 +8,18 @@ fn main() {}
fn should_warn_simple_case() {
let v = vec![SyncWeak::<u32>::new(); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
let v2 = vec![UnSyncWeak::<u32>::new(); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
let v = vec![Rc::downgrade(&Rc::new("x".to_string())); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
}
fn should_warn_simple_case_with_big_indentation() {
@@ -19,13 +28,19 @@ fn should_warn_simple_case_with_big_indentation() {
dbg!(k);
if true {
let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
let v2 = vec![Rc::downgrade(&Rc::new("x".to_string())); 2];
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
}
}
}
fn should_warn_complex_case() {
let v = vec![
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
Arc::downgrade(&Arc::new(Mutex::new({
let x = 1;
dbg!(x);
@@ -35,6 +50,8 @@ fn should_warn_complex_case() {
];
let v1 = vec![
+ //~^ ERROR: initializing a reference-counted pointer in `vec![elem; len]`
+ //~| NOTE: each element will point to the same `Weak` instance
Rc::downgrade(&Rc::new(Mutex::new({
let x = 1;
dbg!(x);
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr
index 1f7a849b1..25d7dae72 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr
@@ -1,11 +1,12 @@
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:9:13
+ --> $DIR/weak.rs:10:13
|
LL | let v = vec![SyncWeak::<u32>::new(); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: each element will point to the same `Weak` instance
= note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::rc_clone_in_vec_init)]`
help: consider initializing each `Weak` element individually
|
LL ~ let v = {
@@ -23,7 +24,7 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:10:14
+ --> $DIR/weak.rs:13:14
|
LL | let v2 = vec![UnSyncWeak::<u32>::new(); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -46,7 +47,7 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:12:13
+ --> $DIR/weak.rs:17:13
|
LL | let v = vec![Rc::downgrade(&Rc::new("x".to_string())); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,7 +70,7 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:13:13
+ --> $DIR/weak.rs:20:13
|
LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -92,7 +93,7 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:21:21
+ --> $DIR/weak.rs:30:21
|
LL | let v = vec![Arc::downgrade(&Arc::new("x".to_string())); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -115,7 +116,7 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:22:22
+ --> $DIR/weak.rs:33:22
|
LL | let v2 = vec![Rc::downgrade(&Rc::new("x".to_string())); 2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,13 +139,13 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:28:13
+ --> $DIR/weak.rs:41:13
|
LL | let v = vec![
| _____________^
+LL | |
+LL | |
LL | | Arc::downgrade(&Arc::new(Mutex::new({
-LL | | let x = 1;
-LL | | dbg!(x);
... |
LL | | 2
LL | | ];
@@ -168,13 +169,13 @@ LL ~ };
|
error: initializing a reference-counted pointer in `vec![elem; len]`
- --> $DIR/weak.rs:37:14
+ --> $DIR/weak.rs:52:14
|
LL | let v1 = vec![
| ______________^
+LL | |
+LL | |
LL | | Rc::downgrade(&Rc::new(Mutex::new({
-LL | | let x = 1;
-LL | | dbg!(x);
... |
LL | | 2
LL | | ];
diff --git a/src/tools/clippy/tests/ui/rc_mutex.rs b/src/tools/clippy/tests/ui/rc_mutex.rs
index 432972bbc..40adb3ddc 100644
--- a/src/tools/clippy/tests/ui/rc_mutex.rs
+++ b/src/tools/clippy/tests/ui/rc_mutex.rs
@@ -6,6 +6,7 @@ use std::sync::Mutex;
pub struct MyStructWithPrivItem {
foo: Rc<Mutex<i32>>,
+ //~^ ERROR: usage of `Rc<Mutex<_>>`
}
pub struct MyStructWithPubItem {
@@ -24,8 +25,11 @@ pub enum MyEnum {
// All of these test should be trigger the lint because they are not
// part of the public api
fn test1<T>(foo: Rc<Mutex<T>>) {}
+//~^ ERROR: usage of `Rc<Mutex<_>>`
fn test2(foo: Rc<Mutex<MyEnum>>) {}
+//~^ ERROR: usage of `Rc<Mutex<_>>`
fn test3(foo: Rc<Mutex<SubT<usize>>>) {}
+//~^ ERROR: usage of `Rc<Mutex<_>>`
// All of these test should be allowed because they are part of the
// public api and `avoid_breaking_exported_api` is `false` by default.
diff --git a/src/tools/clippy/tests/ui/rc_mutex.stderr b/src/tools/clippy/tests/ui/rc_mutex.stderr
index cee3bd8b2..50922fb67 100644
--- a/src/tools/clippy/tests/ui/rc_mutex.stderr
+++ b/src/tools/clippy/tests/ui/rc_mutex.stderr
@@ -6,9 +6,10 @@ LL | foo: Rc<Mutex<i32>>,
|
= help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead
= note: `-D clippy::rc-mutex` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::rc_mutex)]`
error: usage of `Rc<Mutex<_>>`
- --> $DIR/rc_mutex.rs:26:18
+ --> $DIR/rc_mutex.rs:27:18
|
LL | fn test1<T>(foo: Rc<Mutex<T>>) {}
| ^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | fn test1<T>(foo: Rc<Mutex<T>>) {}
= help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead
error: usage of `Rc<Mutex<_>>`
- --> $DIR/rc_mutex.rs:27:15
+ --> $DIR/rc_mutex.rs:29:15
|
LL | fn test2(foo: Rc<Mutex<MyEnum>>) {}
| ^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | fn test2(foo: Rc<Mutex<MyEnum>>) {}
= help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead
error: usage of `Rc<Mutex<_>>`
- --> $DIR/rc_mutex.rs:28:15
+ --> $DIR/rc_mutex.rs:31:15
|
LL | fn test3(foo: Rc<Mutex<SubT<usize>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/read_line_without_trim.fixed b/src/tools/clippy/tests/ui/read_line_without_trim.fixed
index cb6aab84e..03a99b17d 100644
--- a/src/tools/clippy/tests/ui/read_line_without_trim.fixed
+++ b/src/tools/clippy/tests/ui/read_line_without_trim.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::read_line_without_trim)]
diff --git a/src/tools/clippy/tests/ui/read_line_without_trim.rs b/src/tools/clippy/tests/ui/read_line_without_trim.rs
index bdc409a70..65510aea0 100644
--- a/src/tools/clippy/tests/ui/read_line_without_trim.rs
+++ b/src/tools/clippy/tests/ui/read_line_without_trim.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#![warn(clippy::read_line_without_trim)]
diff --git a/src/tools/clippy/tests/ui/read_line_without_trim.stderr b/src/tools/clippy/tests/ui/read_line_without_trim.stderr
index f3d7b6042..8d46e0f79 100644
--- a/src/tools/clippy/tests/ui/read_line_without_trim.stderr
+++ b/src/tools/clippy/tests/ui/read_line_without_trim.stderr
@@ -1,5 +1,5 @@
error: calling `.parse()` without trimming the trailing newline character
- --> $DIR/read_line_without_trim.rs:14:25
+ --> $DIR/read_line_without_trim.rs:12:25
|
LL | let _x: i32 = input.parse().unwrap();
| ----- ^^^^^^^
@@ -7,14 +7,15 @@ LL | let _x: i32 = input.parse().unwrap();
| help: try: `input.trim_end()`
|
note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail
- --> $DIR/read_line_without_trim.rs:13:5
+ --> $DIR/read_line_without_trim.rs:11:5
|
LL | std::io::stdin().read_line(&mut input).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::read-line-without-trim` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::read_line_without_trim)]`
error: calling `.parse()` without trimming the trailing newline character
- --> $DIR/read_line_without_trim.rs:18:20
+ --> $DIR/read_line_without_trim.rs:16:20
|
LL | let _x = input.parse::<i32>().unwrap();
| ----- ^^^^^^^^^^^^^^
@@ -22,13 +23,13 @@ LL | let _x = input.parse::<i32>().unwrap();
| help: try: `input.trim_end()`
|
note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail
- --> $DIR/read_line_without_trim.rs:17:5
+ --> $DIR/read_line_without_trim.rs:15:5
|
LL | std::io::stdin().read_line(&mut input).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `.parse()` without trimming the trailing newline character
- --> $DIR/read_line_without_trim.rs:22:20
+ --> $DIR/read_line_without_trim.rs:20:20
|
LL | let _x = input.parse::<u32>().unwrap();
| ----- ^^^^^^^^^^^^^^
@@ -36,13 +37,13 @@ LL | let _x = input.parse::<u32>().unwrap();
| help: try: `input.trim_end()`
|
note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail
- --> $DIR/read_line_without_trim.rs:21:5
+ --> $DIR/read_line_without_trim.rs:19:5
|
LL | std::io::stdin().read_line(&mut input).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `.parse()` without trimming the trailing newline character
- --> $DIR/read_line_without_trim.rs:26:20
+ --> $DIR/read_line_without_trim.rs:24:20
|
LL | let _x = input.parse::<f32>().unwrap();
| ----- ^^^^^^^^^^^^^^
@@ -50,13 +51,13 @@ LL | let _x = input.parse::<f32>().unwrap();
| help: try: `input.trim_end()`
|
note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail
- --> $DIR/read_line_without_trim.rs:25:5
+ --> $DIR/read_line_without_trim.rs:23:5
|
LL | std::io::stdin().read_line(&mut input).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: calling `.parse()` without trimming the trailing newline character
- --> $DIR/read_line_without_trim.rs:30:20
+ --> $DIR/read_line_without_trim.rs:28:20
|
LL | let _x = input.parse::<bool>().unwrap();
| ----- ^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | let _x = input.parse::<bool>().unwrap();
| help: try: `input.trim_end()`
|
note: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause `.parse()` to fail
- --> $DIR/read_line_without_trim.rs:29:5
+ --> $DIR/read_line_without_trim.rs:27:5
|
LL | std::io::stdin().read_line(&mut input).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/read_zero_byte_vec.rs b/src/tools/clippy/tests/ui/read_zero_byte_vec.rs
index ff2ad8644..76b9b9818 100644
--- a/src/tools/clippy/tests/ui/read_zero_byte_vec.rs
+++ b/src/tools/clippy/tests/ui/read_zero_byte_vec.rs
@@ -7,7 +7,7 @@
use std::fs::File;
use std::io;
use std::io::prelude::*;
-
+//@no-rustfix
extern crate futures;
use futures::io::{AsyncRead, AsyncReadExt};
use tokio::io::{AsyncRead as TokioAsyncRead, AsyncReadExt as _, AsyncWrite as TokioAsyncWrite, AsyncWriteExt as _};
@@ -19,29 +19,36 @@ fn test() -> io::Result<()> {
// should lint
let mut data = Vec::with_capacity(20);
f.read_exact(&mut data).unwrap();
+ //~^ ERROR: reading zero byte data to `Vec`
+ //~| NOTE: `-D clippy::read-zero-byte-vec` implied by `-D warnings`
// should lint
let mut data2 = Vec::with_capacity(cap);
f.read_exact(&mut data2)?;
+ //~^ ERROR: reading zero byte data to `Vec`
// should lint
let mut data3 = Vec::new();
f.read_exact(&mut data3)?;
+ //~^ ERROR: reading zero byte data to `Vec`
// should lint
let mut data4 = vec![];
let _ = f.read(&mut data4)?;
+ //~^ ERROR: reading zero byte data to `Vec`
// should lint
let _ = {
let mut data5 = Vec::new();
f.read(&mut data5)
+ //~^ ERROR: reading zero byte data to `Vec`
};
// should lint
let _ = {
let mut data6: Vec<u8> = Default::default();
f.read(&mut data6)
+ //~^ ERROR: reading zero byte data to `Vec`
};
// should not lint
@@ -72,20 +79,24 @@ async fn test_futures<R: AsyncRead + Unpin>(r: &mut R) {
// should lint
let mut data = Vec::new();
r.read(&mut data).await.unwrap();
+ //~^ ERROR: reading zero byte data to `Vec`
// should lint
let mut data2 = Vec::new();
r.read_exact(&mut data2).await.unwrap();
+ //~^ ERROR: reading zero byte data to `Vec`
}
async fn test_tokio<R: TokioAsyncRead + Unpin>(r: &mut R) {
// should lint
let mut data = Vec::new();
r.read(&mut data).await.unwrap();
+ //~^ ERROR: reading zero byte data to `Vec`
// should lint
let mut data2 = Vec::new();
r.read_exact(&mut data2).await.unwrap();
+ //~^ ERROR: reading zero byte data to `Vec`
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr b/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr
index 4c7f605f4..523ecb294 100644
--- a/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr
+++ b/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr
@@ -5,57 +5,58 @@ LL | f.read_exact(&mut data).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data.resize(20, 0); f.read_exact(&mut data).unwrap();`
|
= note: `-D clippy::read-zero-byte-vec` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::read_zero_byte_vec)]`
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:25:5
+ --> $DIR/read_zero_byte_vec.rs:27:5
|
LL | f.read_exact(&mut data2)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data2.resize(cap, 0); f.read_exact(&mut data2)?;`
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:29:5
+ --> $DIR/read_zero_byte_vec.rs:32:5
|
LL | f.read_exact(&mut data3)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:33:5
+ --> $DIR/read_zero_byte_vec.rs:37:5
|
LL | let _ = f.read(&mut data4)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:38:9
+ --> $DIR/read_zero_byte_vec.rs:43:9
|
LL | f.read(&mut data5)
| ^^^^^^^^^^^^^^^^^^
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:44:9
+ --> $DIR/read_zero_byte_vec.rs:50:9
|
LL | f.read(&mut data6)
| ^^^^^^^^^^^^^^^^^^
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:74:5
+ --> $DIR/read_zero_byte_vec.rs:81:5
|
LL | r.read(&mut data).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:78:5
+ --> $DIR/read_zero_byte_vec.rs:86:5
|
LL | r.read_exact(&mut data2).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:84:5
+ --> $DIR/read_zero_byte_vec.rs:93:5
|
LL | r.read(&mut data).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: reading zero byte data to `Vec`
- --> $DIR/read_zero_byte_vec.rs:88:5
+ --> $DIR/read_zero_byte_vec.rs:98:5
|
LL | r.read_exact(&mut data2).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/readonly_write_lock.fixed b/src/tools/clippy/tests/ui/readonly_write_lock.fixed
new file mode 100644
index 000000000..76f4a43ae
--- /dev/null
+++ b/src/tools/clippy/tests/ui/readonly_write_lock.fixed
@@ -0,0 +1,45 @@
+#![warn(clippy::readonly_write_lock)]
+
+use std::sync::RwLock;
+
+fn mutate_i32(x: &mut i32) {
+ *x += 1;
+}
+
+fn accept_i32(_: i32) {}
+
+fn main() {
+ let lock = RwLock::new(42);
+ let lock2 = RwLock::new(1234);
+
+ {
+ let writer = lock.read().unwrap();
+ //~^ ERROR: this write lock is used only for reading
+ //~| NOTE: `-D clippy::readonly-write-lock` implied by `-D warnings`
+ dbg!(&writer);
+ }
+
+ {
+ let writer = lock.read().unwrap();
+ //~^ ERROR: this write lock is used only for reading
+ accept_i32(*writer);
+ }
+
+ {
+ let mut writer = lock.write().unwrap();
+ mutate_i32(&mut writer);
+ dbg!(&writer);
+ }
+
+ {
+ let mut writer = lock.write().unwrap();
+ *writer += 1;
+ }
+
+ {
+ let mut writer1 = lock.write().unwrap();
+ let mut writer2 = lock2.write().unwrap();
+ *writer2 += 1;
+ *writer1 = *writer2;
+ }
+}
diff --git a/src/tools/clippy/tests/ui/readonly_write_lock.rs b/src/tools/clippy/tests/ui/readonly_write_lock.rs
index 656b45787..3d1d3855f 100644
--- a/src/tools/clippy/tests/ui/readonly_write_lock.rs
+++ b/src/tools/clippy/tests/ui/readonly_write_lock.rs
@@ -14,11 +14,14 @@ fn main() {
{
let writer = lock.write().unwrap();
+ //~^ ERROR: this write lock is used only for reading
+ //~| NOTE: `-D clippy::readonly-write-lock` implied by `-D warnings`
dbg!(&writer);
}
{
let writer = lock.write().unwrap();
+ //~^ ERROR: this write lock is used only for reading
accept_i32(*writer);
}
diff --git a/src/tools/clippy/tests/ui/readonly_write_lock.stderr b/src/tools/clippy/tests/ui/readonly_write_lock.stderr
index e3d8fce7b..b4a093ce9 100644
--- a/src/tools/clippy/tests/ui/readonly_write_lock.stderr
+++ b/src/tools/clippy/tests/ui/readonly_write_lock.stderr
@@ -5,9 +5,10 @@ LL | let writer = lock.write().unwrap();
| ^^^^^^^^^^^^ help: consider using a read lock instead: `lock.read()`
|
= note: `-D clippy::readonly-write-lock` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::readonly_write_lock)]`
error: this write lock is used only for reading
- --> $DIR/readonly_write_lock.rs:21:22
+ --> $DIR/readonly_write_lock.rs:23:22
|
LL | let writer = lock.write().unwrap();
| ^^^^^^^^^^^^ help: consider using a read lock instead: `lock.read()`
diff --git a/src/tools/clippy/tests/ui/recursive_format_impl.rs b/src/tools/clippy/tests/ui/recursive_format_impl.rs
index b92490b4c..b3eafc6da 100644
--- a/src/tools/clippy/tests/ui/recursive_format_impl.rs
+++ b/src/tools/clippy/tests/ui/recursive_format_impl.rs
@@ -29,6 +29,8 @@ impl B for A {
impl fmt::Display for A {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_string())
+ //~^ ERROR: using `self.to_string` in `fmt::Display` implementation will cause inf
+ //~| NOTE: `-D clippy::recursive-format-impl` implied by `-D warnings`
}
}
@@ -73,6 +75,7 @@ struct G;
impl std::fmt::Display for G {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
+ //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs
}
}
@@ -82,12 +85,14 @@ struct H;
impl std::fmt::Display for H {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self)
+ //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs
}
}
impl std::fmt::Debug for H {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", &self)
+ //~^ ERROR: using `self` as `Debug` in `impl Debug` will cause infinite recursion
}
}
@@ -97,6 +102,7 @@ struct H2;
impl std::fmt::Display for H2 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &&&self)
+ //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs
}
}
@@ -171,12 +177,14 @@ impl std::ops::Deref for J {
impl std::fmt::Display for J {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", &*self)
+ //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs
}
}
impl std::fmt::Debug for J {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", &*self)
+ //~^ ERROR: using `self` as `Debug` in `impl Debug` will cause infinite recursion
}
}
@@ -193,6 +201,7 @@ impl std::ops::Deref for J2 {
impl std::fmt::Display for J2 {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", *self)
+ //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs
}
}
@@ -209,6 +218,7 @@ impl std::ops::Deref for J3 {
impl std::fmt::Display for J3 {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", **&&*self)
+ //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs
}
}
@@ -225,6 +235,7 @@ impl std::ops::Deref for J4 {
impl std::fmt::Display for J4 {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", &&**&&*self)
+ //~^ ERROR: using `self` as `Display` in `impl Display` will cause infinite recurs
}
}
diff --git a/src/tools/clippy/tests/ui/recursive_format_impl.stderr b/src/tools/clippy/tests/ui/recursive_format_impl.stderr
index 8a58b9a3b..adb16f44a 100644
--- a/src/tools/clippy/tests/ui/recursive_format_impl.stderr
+++ b/src/tools/clippy/tests/ui/recursive_format_impl.stderr
@@ -5,9 +5,10 @@ LL | write!(f, "{}", self.to_string())
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::recursive-format-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::recursive_format_impl)]`
error: using `self` as `Display` in `impl Display` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:75:9
+ --> $DIR/recursive_format_impl.rs:77:9
|
LL | write!(f, "{}", self)
| ^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +16,7 @@ LL | write!(f, "{}", self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Display` in `impl Display` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:84:9
+ --> $DIR/recursive_format_impl.rs:87:9
|
LL | write!(f, "{}", &self)
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +24,7 @@ LL | write!(f, "{}", &self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Debug` in `impl Debug` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:90:9
+ --> $DIR/recursive_format_impl.rs:94:9
|
LL | write!(f, "{:?}", &self)
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -31,7 +32,7 @@ LL | write!(f, "{:?}", &self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Display` in `impl Display` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:99:9
+ --> $DIR/recursive_format_impl.rs:104:9
|
LL | write!(f, "{}", &&&self)
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,7 +40,7 @@ LL | write!(f, "{}", &&&self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Display` in `impl Display` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:173:9
+ --> $DIR/recursive_format_impl.rs:179:9
|
LL | write!(f, "{}", &*self)
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +48,7 @@ LL | write!(f, "{}", &*self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Debug` in `impl Debug` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:179:9
+ --> $DIR/recursive_format_impl.rs:186:9
|
LL | write!(f, "{:?}", &*self)
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +56,7 @@ LL | write!(f, "{:?}", &*self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Display` in `impl Display` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:195:9
+ --> $DIR/recursive_format_impl.rs:203:9
|
LL | write!(f, "{}", *self)
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -63,7 +64,7 @@ LL | write!(f, "{}", *self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Display` in `impl Display` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:211:9
+ --> $DIR/recursive_format_impl.rs:220:9
|
LL | write!(f, "{}", **&&*self)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,7 +72,7 @@ LL | write!(f, "{}", **&&*self)
= note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
error: using `self` as `Display` in `impl Display` will cause infinite recursion
- --> $DIR/recursive_format_impl.rs:227:9
+ --> $DIR/recursive_format_impl.rs:237:9
|
LL | write!(f, "{}", &&**&&*self)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.rs b/src/tools/clippy/tests/ui/redundant_allocation.rs
index 9eb58a3e5..e70f8e71f 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation.rs
@@ -14,14 +14,24 @@ mod outer_box {
use std::sync::Arc;
pub fn box_test6<T>(foo: Box<Rc<T>>) {}
+ //~^ ERROR: usage of `Box<Rc<T>>`
+ //~| NOTE: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation
pub fn box_test7<T>(foo: Box<Arc<T>>) {}
+ //~^ ERROR: usage of `Box<Arc<T>>`
+ //~| NOTE: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
pub fn box_test8() -> Box<Rc<SubT<usize>>> {
+ //~^ ERROR: usage of `Box<Rc<SubT<usize>>>`
+ //~| NOTE: `Rc<SubT<usize>>` is already on the heap, `Box<Rc<SubT<usize>>>` makes an e
unimplemented!();
}
pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
+ //~^ ERROR: usage of `Box<Arc<T>>`
+ //~| NOTE: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation
+ //~| ERROR: usage of `Box<Arc<SubT<T>>>`
+ //~| NOTE: `Arc<SubT<T>>` is already on the heap, `Box<Arc<SubT<T>>>` makes an extra a
unimplemented!();
}
}
@@ -33,14 +43,24 @@ mod outer_rc {
use std::sync::Arc;
pub fn rc_test5(a: Rc<Box<bool>>) {}
+ //~^ ERROR: usage of `Rc<Box<bool>>`
+ //~| NOTE: `Box<bool>` is already on the heap, `Rc<Box<bool>>` makes an extra allocati
pub fn rc_test7(a: Rc<Arc<bool>>) {}
+ //~^ ERROR: usage of `Rc<Arc<bool>>`
+ //~| NOTE: `Arc<bool>` is already on the heap, `Rc<Arc<bool>>` makes an extra allocati
pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
+ //~^ ERROR: usage of `Rc<Box<SubT<usize>>>`
+ //~| NOTE: `Box<SubT<usize>>` is already on the heap, `Rc<Box<SubT<usize>>>` makes an
unimplemented!();
}
pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
+ //~^ ERROR: usage of `Rc<Arc<T>>`
+ //~| NOTE: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation
+ //~| ERROR: usage of `Rc<Arc<SubT<T>>>`
+ //~| NOTE: `Arc<SubT<T>>` is already on the heap, `Rc<Arc<SubT<T>>>` makes an extra al
unimplemented!();
}
}
@@ -52,14 +72,24 @@ mod outer_arc {
use std::sync::Arc;
pub fn arc_test5(a: Arc<Box<bool>>) {}
+ //~^ ERROR: usage of `Arc<Box<bool>>`
+ //~| NOTE: `Box<bool>` is already on the heap, `Arc<Box<bool>>` makes an extra allocat
pub fn arc_test6(a: Arc<Rc<bool>>) {}
+ //~^ ERROR: usage of `Arc<Rc<bool>>`
+ //~| NOTE: `Rc<bool>` is already on the heap, `Arc<Rc<bool>>` makes an extra allocatio
pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
+ //~^ ERROR: usage of `Arc<Box<SubT<usize>>>`
+ //~| NOTE: `Box<SubT<usize>>` is already on the heap, `Arc<Box<SubT<usize>>>` makes an
unimplemented!();
}
pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
+ //~^ ERROR: usage of `Arc<Rc<T>>`
+ //~| NOTE: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation
+ //~| ERROR: usage of `Arc<Rc<SubT<T>>>`
+ //~| NOTE: `Rc<SubT<T>>` is already on the heap, `Arc<Rc<SubT<T>>>` makes an extra all
unimplemented!();
}
}
@@ -82,6 +112,8 @@ mod box_dyn {
pub fn test_rc(_: Rc<Box<dyn T>>) {}
pub fn test_arc(_: Arc<Box<dyn T>>) {}
pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}
+ //~^ ERROR: usage of `Rc<Box<Box<dyn T>>>`
+ //~| NOTE: `Box<Box<dyn T>>` is already on the heap, `Rc<Box<Box<dyn T>>>` makes an ex
}
// https://github.com/rust-lang/rust-clippy/issues/8604
@@ -114,9 +146,22 @@ mod box_fat_ptr {
pub fn test_box_custom(_: Box<Box<DynSized>>) {}
pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {}
+ //~^ ERROR: usage of `Rc<Box<Box<str>>>`
+ //~| NOTE: `Box<Box<str>>` is already on the heap, `Rc<Box<Box<str>>>` makes an extra
pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {}
+ //~^ ERROR: usage of `Rc<Box<Box<[usize]>>>`
+ //~| NOTE: `Box<Box<[usize]>>` is already on the heap, `Rc<Box<Box<[usize]>>>` makes a
pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {}
+ //~^ ERROR: usage of `Rc<Box<Box<Path>>>`
+ //~| NOTE: `Box<Box<Path>>` is already on the heap, `Rc<Box<Box<Path>>>` makes an extr
pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {}
+ //~^ ERROR: usage of `Rc<Box<Box<DynSized>>>`
+ //~| NOTE: `Box<Box<DynSized>>` is already on the heap, `Rc<Box<Box<DynSized>>>` makes
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn type_in_closure() {
+ let _ = |_: &mut Box<Box<dyn ToString>>| {};
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.stderr b/src/tools/clippy/tests/ui/redundant_allocation.stderr
index a9a1eed70..d72f6b202 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.stderr
+++ b/src/tools/clippy/tests/ui/redundant_allocation.stderr
@@ -7,9 +7,10 @@ LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {}
= note: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation
= help: consider using just `Box<T>` or `Rc<T>`
= note: `-D clippy::redundant-allocation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_allocation)]`
error: usage of `Box<Arc<T>>`
- --> $DIR/redundant_allocation.rs:18:30
+ --> $DIR/redundant_allocation.rs:20:30
|
LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {}
| ^^^^^^^^^^^
@@ -18,7 +19,7 @@ LL | pub fn box_test7<T>(foo: Box<Arc<T>>) {}
= help: consider using just `Box<T>` or `Arc<T>`
error: usage of `Box<Rc<SubT<usize>>>`
- --> $DIR/redundant_allocation.rs:20:27
+ --> $DIR/redundant_allocation.rs:24:27
|
LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^
@@ -27,7 +28,7 @@ LL | pub fn box_test8() -> Box<Rc<SubT<usize>>> {
= help: consider using just `Box<SubT<usize>>` or `Rc<SubT<usize>>`
error: usage of `Box<Arc<T>>`
- --> $DIR/redundant_allocation.rs:24:30
+ --> $DIR/redundant_allocation.rs:30:30
|
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
| ^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
= help: consider using just `Box<T>` or `Arc<T>`
error: usage of `Box<Arc<SubT<T>>>`
- --> $DIR/redundant_allocation.rs:24:46
+ --> $DIR/redundant_allocation.rs:30:46
|
LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {
= help: consider using just `Box<SubT<T>>` or `Arc<SubT<T>>`
error: usage of `Rc<Box<bool>>`
- --> $DIR/redundant_allocation.rs:35:24
+ --> $DIR/redundant_allocation.rs:45:24
|
LL | pub fn rc_test5(a: Rc<Box<bool>>) {}
| ^^^^^^^^^^^^^
@@ -54,7 +55,7 @@ LL | pub fn rc_test5(a: Rc<Box<bool>>) {}
= help: consider using just `Rc<bool>` or `Box<bool>`
error: usage of `Rc<Arc<bool>>`
- --> $DIR/redundant_allocation.rs:37:24
+ --> $DIR/redundant_allocation.rs:49:24
|
LL | pub fn rc_test7(a: Rc<Arc<bool>>) {}
| ^^^^^^^^^^^^^
@@ -63,7 +64,7 @@ LL | pub fn rc_test7(a: Rc<Arc<bool>>) {}
= help: consider using just `Rc<bool>` or `Arc<bool>`
error: usage of `Rc<Box<SubT<usize>>>`
- --> $DIR/redundant_allocation.rs:39:26
+ --> $DIR/redundant_allocation.rs:53:26
|
LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | pub fn rc_test8() -> Rc<Box<SubT<usize>>> {
= help: consider using just `Rc<SubT<usize>>` or `Box<SubT<usize>>`
error: usage of `Rc<Arc<T>>`
- --> $DIR/redundant_allocation.rs:43:29
+ --> $DIR/redundant_allocation.rs:59:29
|
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
| ^^^^^^^^^^
@@ -81,7 +82,7 @@ LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
= help: consider using just `Rc<T>` or `Arc<T>`
error: usage of `Rc<Arc<SubT<T>>>`
- --> $DIR/redundant_allocation.rs:43:44
+ --> $DIR/redundant_allocation.rs:59:44
|
LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^
@@ -90,7 +91,7 @@ LL | pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {
= help: consider using just `Rc<SubT<T>>` or `Arc<SubT<T>>`
error: usage of `Arc<Box<bool>>`
- --> $DIR/redundant_allocation.rs:54:25
+ --> $DIR/redundant_allocation.rs:74:25
|
LL | pub fn arc_test5(a: Arc<Box<bool>>) {}
| ^^^^^^^^^^^^^^
@@ -99,7 +100,7 @@ LL | pub fn arc_test5(a: Arc<Box<bool>>) {}
= help: consider using just `Arc<bool>` or `Box<bool>`
error: usage of `Arc<Rc<bool>>`
- --> $DIR/redundant_allocation.rs:56:25
+ --> $DIR/redundant_allocation.rs:78:25
|
LL | pub fn arc_test6(a: Arc<Rc<bool>>) {}
| ^^^^^^^^^^^^^
@@ -108,7 +109,7 @@ LL | pub fn arc_test6(a: Arc<Rc<bool>>) {}
= help: consider using just `Arc<bool>` or `Rc<bool>`
error: usage of `Arc<Box<SubT<usize>>>`
- --> $DIR/redundant_allocation.rs:58:27
+ --> $DIR/redundant_allocation.rs:82:27
|
LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
| ^^^^^^^^^^^^^^^^^^^^^
@@ -117,7 +118,7 @@ LL | pub fn arc_test8() -> Arc<Box<SubT<usize>>> {
= help: consider using just `Arc<SubT<usize>>` or `Box<SubT<usize>>`
error: usage of `Arc<Rc<T>>`
- --> $DIR/redundant_allocation.rs:62:30
+ --> $DIR/redundant_allocation.rs:88:30
|
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
| ^^^^^^^^^^
@@ -126,7 +127,7 @@ LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
= help: consider using just `Arc<T>` or `Rc<T>`
error: usage of `Arc<Rc<SubT<T>>>`
- --> $DIR/redundant_allocation.rs:62:45
+ --> $DIR/redundant_allocation.rs:88:45
|
LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
| ^^^^^^^^^^^^^^^^
@@ -135,7 +136,7 @@ LL | pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
= help: consider using just `Arc<SubT<T>>` or `Rc<SubT<T>>`
error: usage of `Rc<Box<Box<dyn T>>>`
- --> $DIR/redundant_allocation.rs:84:27
+ --> $DIR/redundant_allocation.rs:114:27
|
LL | pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}
| ^^^^^^^^^^^^^^^^^^^
@@ -144,7 +145,7 @@ LL | pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}
= help: consider using just `Rc<Box<dyn T>>` or `Box<Box<dyn T>>`
error: usage of `Rc<Box<Box<str>>>`
- --> $DIR/redundant_allocation.rs:116:31
+ --> $DIR/redundant_allocation.rs:148:31
|
LL | pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {}
| ^^^^^^^^^^^^^^^^^
@@ -153,7 +154,7 @@ LL | pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {}
= help: consider using just `Rc<Box<str>>` or `Box<Box<str>>`
error: usage of `Rc<Box<Box<[usize]>>>`
- --> $DIR/redundant_allocation.rs:117:33
+ --> $DIR/redundant_allocation.rs:151:33
|
LL | pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^
@@ -162,7 +163,7 @@ LL | pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {}
= help: consider using just `Rc<Box<[usize]>>` or `Box<Box<[usize]>>`
error: usage of `Rc<Box<Box<Path>>>`
- --> $DIR/redundant_allocation.rs:118:32
+ --> $DIR/redundant_allocation.rs:154:32
|
LL | pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {}
| ^^^^^^^^^^^^^^^^^^
@@ -171,7 +172,7 @@ LL | pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {}
= help: consider using just `Rc<Box<Path>>` or `Box<Box<Path>>`
error: usage of `Rc<Box<Box<DynSized>>>`
- --> $DIR/redundant_allocation.rs:119:34
+ --> $DIR/redundant_allocation.rs:157:34
|
LL | pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
index b97863daf..61c989c67 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::all)]
#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
#![allow(clippy::disallowed_names, unused_variables, dead_code)]
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
index bffb6f8c0..3ad1e9a97 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::all)]
#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]
#![allow(clippy::disallowed_names, unused_variables, dead_code)]
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr b/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr
index 524ca5bf4..603600f30 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr
@@ -1,14 +1,15 @@
error: usage of `Box<&T>`
- --> $DIR/redundant_allocation_fixable.rs:24:30
+ --> $DIR/redundant_allocation_fixable.rs:23:30
|
LL | pub fn box_test1<T>(foo: Box<&T>) {}
| ^^^^^^^ help: try: `&T`
|
= note: `&T` is already a pointer, `Box<&T>` allocates a pointer on the heap
= note: `-D clippy::redundant-allocation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_allocation)]`
error: usage of `Box<&MyStruct>`
- --> $DIR/redundant_allocation_fixable.rs:26:27
+ --> $DIR/redundant_allocation_fixable.rs:25:27
|
LL | pub fn box_test2(foo: Box<&MyStruct>) {}
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
@@ -16,7 +17,7 @@ LL | pub fn box_test2(foo: Box<&MyStruct>) {}
= note: `&MyStruct` is already a pointer, `Box<&MyStruct>` allocates a pointer on the heap
error: usage of `Box<&MyEnum>`
- --> $DIR/redundant_allocation_fixable.rs:28:27
+ --> $DIR/redundant_allocation_fixable.rs:27:27
|
LL | pub fn box_test3(foo: Box<&MyEnum>) {}
| ^^^^^^^^^^^^ help: try: `&MyEnum`
@@ -24,7 +25,7 @@ LL | pub fn box_test3(foo: Box<&MyEnum>) {}
= note: `&MyEnum` is already a pointer, `Box<&MyEnum>` allocates a pointer on the heap
error: usage of `Box<Box<T>>`
- --> $DIR/redundant_allocation_fixable.rs:32:30
+ --> $DIR/redundant_allocation_fixable.rs:31:30
|
LL | pub fn box_test5<T>(foo: Box<Box<T>>) {}
| ^^^^^^^^^^^ help: try: `Box<T>`
@@ -32,7 +33,7 @@ LL | pub fn box_test5<T>(foo: Box<Box<T>>) {}
= note: `Box<T>` is already on the heap, `Box<Box<T>>` makes an extra allocation
error: usage of `Rc<&T>`
- --> $DIR/redundant_allocation_fixable.rs:41:29
+ --> $DIR/redundant_allocation_fixable.rs:40:29
|
LL | pub fn rc_test1<T>(foo: Rc<&T>) {}
| ^^^^^^ help: try: `&T`
@@ -40,7 +41,7 @@ LL | pub fn rc_test1<T>(foo: Rc<&T>) {}
= note: `&T` is already a pointer, `Rc<&T>` allocates a pointer on the heap
error: usage of `Rc<&MyStruct>`
- --> $DIR/redundant_allocation_fixable.rs:43:26
+ --> $DIR/redundant_allocation_fixable.rs:42:26
|
LL | pub fn rc_test2(foo: Rc<&MyStruct>) {}
| ^^^^^^^^^^^^^ help: try: `&MyStruct`
@@ -48,7 +49,7 @@ LL | pub fn rc_test2(foo: Rc<&MyStruct>) {}
= note: `&MyStruct` is already a pointer, `Rc<&MyStruct>` allocates a pointer on the heap
error: usage of `Rc<&MyEnum>`
- --> $DIR/redundant_allocation_fixable.rs:45:26
+ --> $DIR/redundant_allocation_fixable.rs:44:26
|
LL | pub fn rc_test3(foo: Rc<&MyEnum>) {}
| ^^^^^^^^^^^ help: try: `&MyEnum`
@@ -56,7 +57,7 @@ LL | pub fn rc_test3(foo: Rc<&MyEnum>) {}
= note: `&MyEnum` is already a pointer, `Rc<&MyEnum>` allocates a pointer on the heap
error: usage of `Rc<Rc<bool>>`
- --> $DIR/redundant_allocation_fixable.rs:49:24
+ --> $DIR/redundant_allocation_fixable.rs:48:24
|
LL | pub fn rc_test6(a: Rc<Rc<bool>>) {}
| ^^^^^^^^^^^^ help: try: `Rc<bool>`
@@ -64,7 +65,7 @@ LL | pub fn rc_test6(a: Rc<Rc<bool>>) {}
= note: `Rc<bool>` is already on the heap, `Rc<Rc<bool>>` makes an extra allocation
error: usage of `Arc<&T>`
- --> $DIR/redundant_allocation_fixable.rs:58:30
+ --> $DIR/redundant_allocation_fixable.rs:57:30
|
LL | pub fn arc_test1<T>(foo: Arc<&T>) {}
| ^^^^^^^ help: try: `&T`
@@ -72,7 +73,7 @@ LL | pub fn arc_test1<T>(foo: Arc<&T>) {}
= note: `&T` is already a pointer, `Arc<&T>` allocates a pointer on the heap
error: usage of `Arc<&MyStruct>`
- --> $DIR/redundant_allocation_fixable.rs:60:27
+ --> $DIR/redundant_allocation_fixable.rs:59:27
|
LL | pub fn arc_test2(foo: Arc<&MyStruct>) {}
| ^^^^^^^^^^^^^^ help: try: `&MyStruct`
@@ -80,7 +81,7 @@ LL | pub fn arc_test2(foo: Arc<&MyStruct>) {}
= note: `&MyStruct` is already a pointer, `Arc<&MyStruct>` allocates a pointer on the heap
error: usage of `Arc<&MyEnum>`
- --> $DIR/redundant_allocation_fixable.rs:62:27
+ --> $DIR/redundant_allocation_fixable.rs:61:27
|
LL | pub fn arc_test3(foo: Arc<&MyEnum>) {}
| ^^^^^^^^^^^^ help: try: `&MyEnum`
@@ -88,7 +89,7 @@ LL | pub fn arc_test3(foo: Arc<&MyEnum>) {}
= note: `&MyEnum` is already a pointer, `Arc<&MyEnum>` allocates a pointer on the heap
error: usage of `Arc<Arc<bool>>`
- --> $DIR/redundant_allocation_fixable.rs:66:25
+ --> $DIR/redundant_allocation_fixable.rs:65:25
|
LL | pub fn arc_test7(a: Arc<Arc<bool>>) {}
| ^^^^^^^^^^^^^^ help: try: `Arc<bool>`
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.fixed b/src/tools/clippy/tests/ui/redundant_as_str.fixed
new file mode 100644
index 000000000..a38523a7c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.fixed
@@ -0,0 +1,24 @@
+#![warn(clippy::redundant_as_str)]
+
+fn main() {
+ let string = "Hello, world!".to_owned();
+
+ // These methods are redundant and the `as_str` can be removed
+ let _redundant = string.as_bytes();
+ let _redundant = string.is_empty();
+
+ // These methods don't use `as_str` when they are redundant
+ let _no_as_str = string.as_bytes();
+ let _no_as_str = string.is_empty();
+
+ // These methods are not redundant, and are equivelant to
+ // doing dereferencing the string and applying the method
+ let _not_redundant = string.as_str().escape_unicode();
+ let _not_redundant = string.as_str().trim();
+ let _not_redundant = string.as_str().split_whitespace();
+
+ // These methods don't use `as_str` and are applied on a `str` directly
+ let borrowed_str = "Hello, world!";
+ let _is_str = borrowed_str.as_bytes();
+ let _is_str = borrowed_str.is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.rs b/src/tools/clippy/tests/ui/redundant_as_str.rs
new file mode 100644
index 000000000..33adb6099
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.rs
@@ -0,0 +1,24 @@
+#![warn(clippy::redundant_as_str)]
+
+fn main() {
+ let string = "Hello, world!".to_owned();
+
+ // These methods are redundant and the `as_str` can be removed
+ let _redundant = string.as_str().as_bytes();
+ let _redundant = string.as_str().is_empty();
+
+ // These methods don't use `as_str` when they are redundant
+ let _no_as_str = string.as_bytes();
+ let _no_as_str = string.is_empty();
+
+ // These methods are not redundant, and are equivelant to
+ // doing dereferencing the string and applying the method
+ let _not_redundant = string.as_str().escape_unicode();
+ let _not_redundant = string.as_str().trim();
+ let _not_redundant = string.as_str().split_whitespace();
+
+ // These methods don't use `as_str` and are applied on a `str` directly
+ let borrowed_str = "Hello, world!";
+ let _is_str = borrowed_str.as_bytes();
+ let _is_str = borrowed_str.is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.stderr b/src/tools/clippy/tests/ui/redundant_as_str.stderr
new file mode 100644
index 000000000..0ea42a94a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.stderr
@@ -0,0 +1,17 @@
+error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too
+ --> $DIR/redundant_as_str.rs:7:29
+ |
+LL | let _redundant = string.as_str().as_bytes();
+ | ^^^^^^^^^^^^^^^^^ help: try: `as_bytes`
+ |
+ = note: `-D clippy::redundant-as-str` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_as_str)]`
+
+error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too
+ --> $DIR/redundant_as_str.rs:8:29
+ |
+LL | let _redundant = string.as_str().is_empty();
+ | ^^^^^^^^^^^^^^^^^ help: try: `is_empty`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/redundant_async_block.fixed b/src/tools/clippy/tests/ui/redundant_async_block.fixed
index 328958491..d492ea1be 100644
--- a/src/tools/clippy/tests/ui/redundant_async_block.fixed
+++ b/src/tools/clippy/tests/ui/redundant_async_block.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::manual_async_fn)]
#![warn(clippy::redundant_async_block)]
diff --git a/src/tools/clippy/tests/ui/redundant_async_block.rs b/src/tools/clippy/tests/ui/redundant_async_block.rs
index cd189b315..dd96e1410 100644
--- a/src/tools/clippy/tests/ui/redundant_async_block.rs
+++ b/src/tools/clippy/tests/ui/redundant_async_block.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::manual_async_fn)]
#![warn(clippy::redundant_async_block)]
diff --git a/src/tools/clippy/tests/ui/redundant_async_block.stderr b/src/tools/clippy/tests/ui/redundant_async_block.stderr
index f3dcb09b4..adb44d7a6 100644
--- a/src/tools/clippy/tests/ui/redundant_async_block.stderr
+++ b/src/tools/clippy/tests/ui/redundant_async_block.stderr
@@ -1,55 +1,56 @@
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:15:13
+ --> $DIR/redundant_async_block.rs:13:13
|
LL | let x = async { f.await };
| ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f`
|
= note: `-D clippy::redundant-async-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_async_block)]`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:22:16
+ --> $DIR/redundant_async_block.rs:20:16
|
LL | let fut2 = async { fut1.await };
| ^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:26:16
+ --> $DIR/redundant_async_block.rs:24:16
|
LL | let fut2 = async move { fut1.await };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:29:15
+ --> $DIR/redundant_async_block.rs:27:15
|
LL | let fut = async { async { 42 }.await };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:45:5
+ --> $DIR/redundant_async_block.rs:43:5
|
LL | async move { fut.await }
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:58:5
+ --> $DIR/redundant_async_block.rs:56:5
|
LL | async move { fut.await }
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:63:5
+ --> $DIR/redundant_async_block.rs:61:5
|
LL | async { f.await }
| ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:86:5
+ --> $DIR/redundant_async_block.rs:84:5
|
LL | async { async { f().await + 1 }.await }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { f().await + 1 }`
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:149:13
+ --> $DIR/redundant_async_block.rs:147:13
|
LL | async { async { 42 }.await }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }`
@@ -60,7 +61,7 @@ LL | mac!()
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this async expression only awaits a single future
- --> $DIR/redundant_async_block.rs:169:13
+ --> $DIR/redundant_async_block.rs:167:13
|
LL | async { async { $e }.await }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { $e }`
diff --git a/src/tools/clippy/tests/ui/redundant_at_rest_pattern.fixed b/src/tools/clippy/tests/ui/redundant_at_rest_pattern.fixed
index 080cf13b5..a79976373 100644
--- a/src/tools/clippy/tests/ui/redundant_at_rest_pattern.fixed
+++ b/src/tools/clippy/tests/ui/redundant_at_rest_pattern.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(irrefutable_let_patterns, unused)]
#![warn(clippy::redundant_at_rest_pattern)]
diff --git a/src/tools/clippy/tests/ui/redundant_at_rest_pattern.rs b/src/tools/clippy/tests/ui/redundant_at_rest_pattern.rs
index a8a802829..f103d1f1a 100644
--- a/src/tools/clippy/tests/ui/redundant_at_rest_pattern.rs
+++ b/src/tools/clippy/tests/ui/redundant_at_rest_pattern.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(irrefutable_let_patterns, unused)]
#![warn(clippy::redundant_at_rest_pattern)]
diff --git a/src/tools/clippy/tests/ui/redundant_at_rest_pattern.stderr b/src/tools/clippy/tests/ui/redundant_at_rest_pattern.stderr
index e2a4d9ffd..3a44636fc 100644
--- a/src/tools/clippy/tests/ui/redundant_at_rest_pattern.stderr
+++ b/src/tools/clippy/tests/ui/redundant_at_rest_pattern.stderr
@@ -1,37 +1,38 @@
error: using a rest pattern to bind an entire slice to a local
- --> $DIR/redundant_at_rest_pattern.rs:10:12
+ --> $DIR/redundant_at_rest_pattern.rs:9:12
|
LL | if let [a @ ..] = [()] {}
| ^^^^^^^^ help: this is better represented with just the binding: `a`
|
= note: `-D clippy::redundant-at-rest-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_at_rest_pattern)]`
error: using a rest pattern to bind an entire slice to a local
- --> $DIR/redundant_at_rest_pattern.rs:11:12
+ --> $DIR/redundant_at_rest_pattern.rs:10:12
|
LL | if let [ref a @ ..] = [()] {}
| ^^^^^^^^^^^^ help: this is better represented with just the binding: `ref a`
error: using a rest pattern to bind an entire slice to a local
- --> $DIR/redundant_at_rest_pattern.rs:12:12
+ --> $DIR/redundant_at_rest_pattern.rs:11:12
|
LL | if let [mut a @ ..] = [()] {}
| ^^^^^^^^^^^^ help: this is better represented with just the binding: `mut a`
error: using a rest pattern to bind an entire slice to a local
- --> $DIR/redundant_at_rest_pattern.rs:13:12
+ --> $DIR/redundant_at_rest_pattern.rs:12:12
|
LL | if let [ref mut a @ ..] = [()] {}
| ^^^^^^^^^^^^^^^^ help: this is better represented with just the binding: `ref mut a`
error: using a rest pattern to bind an entire slice to a local
- --> $DIR/redundant_at_rest_pattern.rs:15:12
+ --> $DIR/redundant_at_rest_pattern.rs:14:12
|
LL | if let [a @ ..] = &*v {}
| ^^^^^^^^ help: this is better represented with just the binding: `a`
error: using a rest pattern to bind an entire slice to a local
- --> $DIR/redundant_at_rest_pattern.rs:17:12
+ --> $DIR/redundant_at_rest_pattern.rs:16:12
|
LL | if let [a @ ..] = s {}
| ^^^^^^^^ help: this is better represented with just the binding: `a`
diff --git a/src/tools/clippy/tests/ui/redundant_clone.fixed b/src/tools/clippy/tests/ui/redundant_clone.fixed
index 5037c08eb..867f5b210 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.fixed
+++ b/src/tools/clippy/tests/ui/redundant_clone.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
// rustfix-only-machine-applicable
#![feature(lint_reasons)]
#![warn(clippy::redundant_clone)]
diff --git a/src/tools/clippy/tests/ui/redundant_clone.rs b/src/tools/clippy/tests/ui/redundant_clone.rs
index 501898bf1..adcbd01e8 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.rs
+++ b/src/tools/clippy/tests/ui/redundant_clone.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
// rustfix-only-machine-applicable
#![feature(lint_reasons)]
#![warn(clippy::redundant_clone)]
diff --git a/src/tools/clippy/tests/ui/redundant_clone.stderr b/src/tools/clippy/tests/ui/redundant_clone.stderr
index 8660c0e1f..4115fcf21 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.stderr
+++ b/src/tools/clippy/tests/ui/redundant_clone.stderr
@@ -1,180 +1,181 @@
error: redundant clone
- --> $DIR/redundant_clone.rs:16:42
+ --> $DIR/redundant_clone.rs:15:42
|
LL | let _s = ["lorem", "ipsum"].join(" ").to_string();
| ^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:16:14
+ --> $DIR/redundant_clone.rs:15:14
|
LL | let _s = ["lorem", "ipsum"].join(" ").to_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::redundant-clone` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
error: redundant clone
- --> $DIR/redundant_clone.rs:19:15
+ --> $DIR/redundant_clone.rs:18:15
|
LL | let _s = s.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:19:14
+ --> $DIR/redundant_clone.rs:18:14
|
LL | let _s = s.clone();
| ^
error: redundant clone
- --> $DIR/redundant_clone.rs:22:15
+ --> $DIR/redundant_clone.rs:21:15
|
LL | let _s = s.to_string();
| ^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:22:14
+ --> $DIR/redundant_clone.rs:21:14
|
LL | let _s = s.to_string();
| ^
error: redundant clone
- --> $DIR/redundant_clone.rs:25:15
+ --> $DIR/redundant_clone.rs:24:15
|
LL | let _s = s.to_owned();
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:25:14
+ --> $DIR/redundant_clone.rs:24:14
|
LL | let _s = s.to_owned();
| ^
error: redundant clone
- --> $DIR/redundant_clone.rs:27:42
+ --> $DIR/redundant_clone.rs:26:42
|
LL | let _s = Path::new("/a/b/").join("c").to_owned();
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:27:14
+ --> $DIR/redundant_clone.rs:26:14
|
LL | let _s = Path::new("/a/b/").join("c").to_owned();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/redundant_clone.rs:29:42
+ --> $DIR/redundant_clone.rs:28:42
|
LL | let _s = Path::new("/a/b/").join("c").to_path_buf();
| ^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:29:14
+ --> $DIR/redundant_clone.rs:28:14
|
LL | let _s = Path::new("/a/b/").join("c").to_path_buf();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/redundant_clone.rs:31:29
+ --> $DIR/redundant_clone.rs:30:29
|
LL | let _s = OsString::new().to_owned();
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:31:14
+ --> $DIR/redundant_clone.rs:30:14
|
LL | let _s = OsString::new().to_owned();
| ^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/redundant_clone.rs:33:29
+ --> $DIR/redundant_clone.rs:32:29
|
LL | let _s = OsString::new().to_os_string();
| ^^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:33:14
+ --> $DIR/redundant_clone.rs:32:14
|
LL | let _s = OsString::new().to_os_string();
| ^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/redundant_clone.rs:44:19
+ --> $DIR/redundant_clone.rs:43:19
|
LL | let _t = tup.0.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:44:14
+ --> $DIR/redundant_clone.rs:43:14
|
LL | let _t = tup.0.clone();
| ^^^^^
error: redundant clone
- --> $DIR/redundant_clone.rs:76:25
+ --> $DIR/redundant_clone.rs:75:25
|
LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) }
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:76:24
+ --> $DIR/redundant_clone.rs:75:24
|
LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) }
| ^
error: redundant clone
- --> $DIR/redundant_clone.rs:133:15
+ --> $DIR/redundant_clone.rs:132:15
|
LL | let _s = s.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:133:14
+ --> $DIR/redundant_clone.rs:132:14
|
LL | let _s = s.clone();
| ^
error: redundant clone
- --> $DIR/redundant_clone.rs:134:15
+ --> $DIR/redundant_clone.rs:133:15
|
LL | let _t = t.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:134:14
+ --> $DIR/redundant_clone.rs:133:14
|
LL | let _t = t.clone();
| ^
error: redundant clone
- --> $DIR/redundant_clone.rs:144:19
+ --> $DIR/redundant_clone.rs:143:19
|
LL | let _f = f.clone();
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:144:18
+ --> $DIR/redundant_clone.rs:143:18
|
LL | let _f = f.clone();
| ^
error: redundant clone
- --> $DIR/redundant_clone.rs:156:14
+ --> $DIR/redundant_clone.rs:155:14
|
LL | let y = x.clone().join("matthias");
| ^^^^^^^^ help: remove this
|
note: cloned value is neither consumed nor mutated
- --> $DIR/redundant_clone.rs:156:13
+ --> $DIR/redundant_clone.rs:155:13
|
LL | let y = x.clone().join("matthias");
| ^^^^^^^^^
error: redundant clone
- --> $DIR/redundant_clone.rs:210:11
+ --> $DIR/redundant_clone.rs:209:11
|
LL | foo(&x.clone(), move || {
| ^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/redundant_clone.rs:210:10
+ --> $DIR/redundant_clone.rs:209:10
|
LL | foo(&x.clone(), move || {
| ^
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_early.rs b/src/tools/clippy/tests/ui/redundant_closure_call_early.rs
index 5649d8dd1..6f9c9fd52 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_early.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_early.rs
@@ -7,9 +7,12 @@ fn main() {
// lint here
let mut k = (|m| m + 1)(i);
+ //~^ ERROR: try not to call a closure in the expression where it is declared
+ //~| NOTE: `-D clippy::redundant-closure-call` implied by `-D warnings`
// lint here
k = (|a, b| a * b)(1, 5);
+ //~^ ERROR: try not to call a closure in the expression where it is declared
// don't lint these
#[allow(clippy::needless_return)]
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_early.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_early.stderr
index 2735e4173..be7a981dc 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_early.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_early.stderr
@@ -5,9 +5,10 @@ LL | let mut k = (|m| m + 1)(i);
| ^^^^^^^^^^^^^^
|
= note: `-D clippy::redundant-closure-call` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_early.rs:12:9
+ --> $DIR/redundant_closure_call_early.rs:14:9
|
LL | k = (|a, b| a * b)(1, 5);
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index f3669a669..bf268d0b5 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(clippy::redundant_async_block)]
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
index db8c7f80d..c8a91049d 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(clippy::redundant_async_block)]
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
index 618f5e071..a7cdb4369 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
@@ -1,13 +1,14 @@
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:18:13
+ --> $DIR/redundant_closure_call_fixable.rs:16:13
|
LL | let a = (|| 42)();
| ^^^^^^^^^ help: try doing something like: `42`
|
= note: `-D clippy::redundant-closure-call` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:19:13
+ --> $DIR/redundant_closure_call_fixable.rs:17:13
|
LL | let b = (async || {
| _____________^
@@ -27,7 +28,7 @@ LL ~ };
|
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:24:13
+ --> $DIR/redundant_closure_call_fixable.rs:22:13
|
LL | let c = (|| {
| _____________^
@@ -47,13 +48,13 @@ LL ~ };
|
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:29:13
+ --> $DIR/redundant_closure_call_fixable.rs:27:13
|
LL | let d = (async || something().await)();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:38:13
+ --> $DIR/redundant_closure_call_fixable.rs:36:13
|
LL | (|| m!())()
| ^^^^^^^^^^^ help: try doing something like: `m!()`
@@ -64,7 +65,7 @@ LL | m2!();
= note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:33:13
+ --> $DIR/redundant_closure_call_fixable.rs:31:13
|
LL | (|| 0)()
| ^^^^^^^^ help: try doing something like: `0`
@@ -75,49 +76,49 @@ LL | m2!();
= 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)
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:46:16
+ --> $DIR/redundant_closure_call_fixable.rs:44:16
|
LL | assert_eq!((|| || 43)()(), 42);
| ^^^^^^^^^^^^^^ help: try doing something like: `43`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:55:10
+ --> $DIR/redundant_closure_call_fixable.rs:53:10
|
LL | dbg!((|| 42)());
| ^^^^^^^^^ help: try doing something like: `42`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:58:13
+ --> $DIR/redundant_closure_call_fixable.rs:56:13
|
LL | let a = (|| || || 123)();
| ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:62:13
+ --> $DIR/redundant_closure_call_fixable.rs:60:13
|
LL | let a = (|| || || || async || 1)()()()()();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:71:13
+ --> $DIR/redundant_closure_call_fixable.rs:69:13
|
LL | let a = (|| echo!(|| echo!(|| 1)))()()();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:73:13
+ --> $DIR/redundant_closure_call_fixable.rs:71:13
|
LL | let a = (|| echo!((|| 123)))()();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:86:11
+ --> $DIR/redundant_closure_call_fixable.rs:84:11
|
LL | bar()((|| || 42)()(), 5);
| ^^^^^^^^^^^^^^ help: try doing something like: `42`
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:87:9
+ --> $DIR/redundant_closure_call_fixable.rs:85:9
|
LL | foo((|| || 42)()(), 5);
| ^^^^^^^^^^^^^^ help: try doing something like: `42`
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_late.rs b/src/tools/clippy/tests/ui/redundant_closure_call_late.rs
index 5612827bd..dc369c3bc 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_late.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_late.rs
@@ -14,12 +14,16 @@ fn main() {
// lint here
let redun_closure = || 1;
i = redun_closure();
+ //~^ ERROR: closure called just once immediately after it was declared
+ //~| NOTE: `-D clippy::redundant-closure-call` implied by `-D warnings`
// shadowed closures are supported, lint here
let shadowed_closure = || 1;
i = shadowed_closure();
+ //~^ ERROR: closure called just once immediately after it was declared
let shadowed_closure = || 2;
i = shadowed_closure();
+ //~^ ERROR: closure called just once immediately after it was declared
// don't lint here
let shadowed_closure = || 2;
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_late.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_late.stderr
index 4eca43a2b..a89bfc770 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_late.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_late.stderr
@@ -5,15 +5,16 @@ LL | i = redun_closure();
| ^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::redundant-closure-call` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`
error: closure called just once immediately after it was declared
- --> $DIR/redundant_closure_call_late.rs:20:5
+ --> $DIR/redundant_closure_call_late.rs:22:5
|
LL | i = shadowed_closure();
| ^^^^^^^^^^^^^^^^^^^^^^
error: closure called just once immediately after it was declared
- --> $DIR/redundant_closure_call_late.rs:22:5
+ --> $DIR/redundant_closure_call_late.rs:25:5
|
LL | i = shadowed_closure();
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/redundant_else.rs b/src/tools/clippy/tests/ui/redundant_else.rs
index 64f566735..8bcf2ce52 100644
--- a/src/tools/clippy/tests/ui/redundant_else.rs
+++ b/src/tools/clippy/tests/ui/redundant_else.rs
@@ -8,6 +8,7 @@ fn main() {
println!("Love your neighbor;");
break;
} else {
+ //~^ ERROR: redundant else block
println!("yet don't pull down your hedge.");
}
// continue
@@ -15,6 +16,7 @@ fn main() {
println!("He that lies down with Dogs,");
continue;
} else {
+ //~^ ERROR: redundant else block
println!("shall rise up with fleas.");
}
// match block
@@ -24,6 +26,7 @@ fn main() {
_ => return,
}
} else {
+ //~^ ERROR: redundant else block
println!("You may delay, but time will not.");
}
}
@@ -33,6 +36,7 @@ fn main() {
} else if foo() {
return;
} else {
+ //~^ ERROR: redundant else block
println!("A fat kitchen makes a lean will.");
}
// let binding outside of block
@@ -40,6 +44,7 @@ fn main() {
if foo() {
return;
} else {
+ //~^ ERROR: redundant else block
1
}
};
@@ -50,6 +55,7 @@ fn main() {
} else if foo() {
return;
} else {
+ //~^ ERROR: redundant else block
2
}
};
@@ -59,6 +65,7 @@ fn main() {
if foo() {
return;
} else {
+ //~^ ERROR: redundant else block
1
}
} else {
diff --git a/src/tools/clippy/tests/ui/redundant_else.stderr b/src/tools/clippy/tests/ui/redundant_else.stderr
index de9d00a60..af33e05a6 100644
--- a/src/tools/clippy/tests/ui/redundant_else.stderr
+++ b/src/tools/clippy/tests/ui/redundant_else.stderr
@@ -3,18 +3,21 @@ error: redundant else block
|
LL | } else {
| ________________^
+LL | |
LL | | println!("yet don't pull down your hedge.");
LL | | }
| |_________^
|
= help: remove the `else` block and move the contents out
= note: `-D clippy::redundant-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_else)]`
error: redundant else block
- --> $DIR/redundant_else.rs:17:16
+ --> $DIR/redundant_else.rs:18:16
|
LL | } else {
| ________________^
+LL | |
LL | | println!("shall rise up with fleas.");
LL | | }
| |_________^
@@ -22,10 +25,11 @@ LL | | }
= help: remove the `else` block and move the contents out
error: redundant else block
- --> $DIR/redundant_else.rs:26:16
+ --> $DIR/redundant_else.rs:28:16
|
LL | } else {
| ________________^
+LL | |
LL | | println!("You may delay, but time will not.");
LL | | }
| |_________^
@@ -33,10 +37,11 @@ LL | | }
= help: remove the `else` block and move the contents out
error: redundant else block
- --> $DIR/redundant_else.rs:35:12
+ --> $DIR/redundant_else.rs:38:12
|
LL | } else {
| ____________^
+LL | |
LL | | println!("A fat kitchen makes a lean will.");
LL | | }
| |_____^
@@ -44,10 +49,11 @@ LL | | }
= help: remove the `else` block and move the contents out
error: redundant else block
- --> $DIR/redundant_else.rs:42:16
+ --> $DIR/redundant_else.rs:46:16
|
LL | } else {
| ________________^
+LL | |
LL | | 1
LL | | }
| |_________^
@@ -55,10 +61,11 @@ LL | | }
= help: remove the `else` block and move the contents out
error: redundant else block
- --> $DIR/redundant_else.rs:52:16
+ --> $DIR/redundant_else.rs:57:16
|
LL | } else {
| ________________^
+LL | |
LL | | 2
LL | | }
| |_________^
@@ -66,10 +73,11 @@ LL | | }
= help: remove the `else` block and move the contents out
error: redundant else block
- --> $DIR/redundant_else.rs:61:16
+ --> $DIR/redundant_else.rs:67:16
|
LL | } else {
| ________________^
+LL | |
LL | | 1
LL | | }
| |_________^
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed
index d2a65399d..c578e7864 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.fixed
+++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed
@@ -1,10 +1,9 @@
-//@run-rustfix
-
+//@aux-build:proc_macros.rs
#![warn(clippy::redundant_field_names)]
#![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]
#[macro_use]
-extern crate derive_new;
+extern crate proc_macros;
use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
@@ -20,7 +19,6 @@ struct Person {
foo: u8,
}
-#[derive(new)]
pub struct S {
v: String,
}
@@ -59,6 +57,13 @@ fn main() {
let _ = Range { start, end };
let _ = RangeInclusive::new(start, end);
let _ = RangeToInclusive { end };
+
+ external! {
+ let v = String::new();
+ let _ = S {
+ v: v
+ };
+ }
}
fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.rs b/src/tools/clippy/tests/ui/redundant_field_names.rs
index 605ffd21e..d8c2286d5 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.rs
+++ b/src/tools/clippy/tests/ui/redundant_field_names.rs
@@ -1,10 +1,9 @@
-//@run-rustfix
-
+//@aux-build:proc_macros.rs
#![warn(clippy::redundant_field_names)]
#![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]
#[macro_use]
-extern crate derive_new;
+extern crate proc_macros;
use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
@@ -20,7 +19,6 @@ struct Person {
foo: u8,
}
-#[derive(new)]
pub struct S {
v: String,
}
@@ -59,6 +57,13 @@ fn main() {
let _ = Range { start: start, end: end };
let _ = RangeInclusive::new(start, end);
let _ = RangeToInclusive { end: end };
+
+ external! {
+ let v = String::new();
+ let _ = S {
+ v: v
+ };
+ }
}
fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.stderr b/src/tools/clippy/tests/ui/redundant_field_names.stderr
index 00a72c50c..6eb1cc753 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.stderr
+++ b/src/tools/clippy/tests/ui/redundant_field_names.stderr
@@ -1,49 +1,50 @@
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:35:9
+ --> $DIR/redundant_field_names.rs:33:9
|
LL | gender: gender,
| ^^^^^^^^^^^^^^ help: replace it with: `gender`
|
= note: `-D clippy::redundant-field-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_field_names)]`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:36:9
+ --> $DIR/redundant_field_names.rs:34:9
|
LL | age: age,
| ^^^^^^^^ help: replace it with: `age`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:57:25
+ --> $DIR/redundant_field_names.rs:55:25
|
LL | let _ = RangeFrom { start: start };
| ^^^^^^^^^^^^ help: replace it with: `start`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:58:23
+ --> $DIR/redundant_field_names.rs:56:23
|
LL | let _ = RangeTo { end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:59:21
+ --> $DIR/redundant_field_names.rs:57:21
|
LL | let _ = Range { start: start, end: end };
| ^^^^^^^^^^^^ help: replace it with: `start`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:59:35
+ --> $DIR/redundant_field_names.rs:57:35
|
LL | let _ = Range { start: start, end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:61:32
+ --> $DIR/redundant_field_names.rs:59:32
|
LL | let _ = RangeToInclusive { end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:83:25
+ --> $DIR/redundant_field_names.rs:88:25
|
LL | let _ = RangeFrom { start: start };
| ^^^^^^^^^^^^ help: replace it with: `start`
diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed
index 49d7336ee..f23116a7e 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.fixed
+++ b/src/tools/clippy/tests/ui/redundant_guards.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(if_let_guard)]
#![allow(clippy::no_effect, unused)]
#![warn(clippy::redundant_guards)]
@@ -44,6 +43,7 @@ fn main() {
},
Some(Some(1)) => ..,
Some(Some(2)) => ..,
+ Some(Some(2)) => ..,
// Don't lint, since x is used in the body
Some(x) if let Some(1) = x => {
x;
@@ -57,11 +57,13 @@ fn main() {
Some(x) if matches!(y, 1 if true) => ..,
Some(x) if let 1 = y => ..,
Some(x) if y == 2 => ..,
+ Some(x) if 2 == y => ..,
_ => todo!(),
};
let a = A(1);
match a {
_ if a.0 == 1 => {},
+ _ if 1 == a.0 => {},
_ => todo!(),
}
let b = B { e: Some(A(0)) };
@@ -120,6 +122,7 @@ fn h(v: Option<u32>) {
fn f(s: Option<std::ffi::OsString>) {
match s {
Some(x) if x == "a" => {},
+ Some(x) if "a" == x => {},
_ => {},
}
}
@@ -141,6 +144,52 @@ static CONST_S: S = S { a: 1 };
fn g(opt_s: Option<S>) {
match opt_s {
Some(x) if x == CONST_S => {},
+ Some(x) if CONST_S == x => {},
_ => {},
}
}
+
+mod issue11465 {
+ enum A {
+ Foo([u8; 3]),
+ }
+
+ struct B {
+ b: String,
+ c: i32,
+ }
+
+ fn issue11465() {
+ let c = Some(1);
+ match c {
+ Some(1) => {},
+ Some(1) => {},
+ Some(2) => {},
+ Some(3) => {},
+ _ => {},
+ };
+
+ let enum_a = A::Foo([98, 97, 114]);
+ match enum_a {
+ A::Foo(ref arr) if arr == b"foo" => {},
+ A::Foo(ref arr) if b"foo" == arr => {},
+ A::Foo(ref arr) if let b"bar" = arr => {},
+ A::Foo(ref arr) if matches!(arr, b"baz") => {},
+ _ => {},
+ };
+
+ let struct_b = B {
+ b: "bar".to_string(),
+ c: 42,
+ };
+ match struct_b {
+ B { ref b, .. } if b == "bar" => {},
+ B { ref b, .. } if "bar" == b => {},
+ B { c: 1, .. } => {},
+ B { c: 1, .. } => {},
+ B { c: 1, .. } => {},
+ B { c: 1, .. } => {},
+ _ => {},
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs
index 87761010d..c0206b4ce 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.rs
+++ b/src/tools/clippy/tests/ui/redundant_guards.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(if_let_guard)]
#![allow(clippy::no_effect, unused)]
#![warn(clippy::redundant_guards)]
@@ -44,6 +43,7 @@ fn main() {
},
Some(x) if let Some(1) = x => ..,
Some(x) if x == Some(2) => ..,
+ Some(x) if Some(2) == x => ..,
// Don't lint, since x is used in the body
Some(x) if let Some(1) = x => {
x;
@@ -57,11 +57,13 @@ fn main() {
Some(x) if matches!(y, 1 if true) => ..,
Some(x) if let 1 = y => ..,
Some(x) if y == 2 => ..,
+ Some(x) if 2 == y => ..,
_ => todo!(),
};
let a = A(1);
match a {
_ if a.0 == 1 => {},
+ _ if 1 == a.0 => {},
_ => todo!(),
}
let b = B { e: Some(A(0)) };
@@ -120,6 +122,7 @@ fn h(v: Option<u32>) {
fn f(s: Option<std::ffi::OsString>) {
match s {
Some(x) if x == "a" => {},
+ Some(x) if "a" == x => {},
_ => {},
}
}
@@ -141,6 +144,52 @@ static CONST_S: S = S { a: 1 };
fn g(opt_s: Option<S>) {
match opt_s {
Some(x) if x == CONST_S => {},
+ Some(x) if CONST_S == x => {},
_ => {},
}
}
+
+mod issue11465 {
+ enum A {
+ Foo([u8; 3]),
+ }
+
+ struct B {
+ b: String,
+ c: i32,
+ }
+
+ fn issue11465() {
+ let c = Some(1);
+ match c {
+ Some(ref x) if x == &1 => {},
+ Some(ref x) if &1 == x => {},
+ Some(ref x) if let &2 = x => {},
+ Some(ref x) if matches!(x, &3) => {},
+ _ => {},
+ };
+
+ let enum_a = A::Foo([98, 97, 114]);
+ match enum_a {
+ A::Foo(ref arr) if arr == b"foo" => {},
+ A::Foo(ref arr) if b"foo" == arr => {},
+ A::Foo(ref arr) if let b"bar" = arr => {},
+ A::Foo(ref arr) if matches!(arr, b"baz") => {},
+ _ => {},
+ };
+
+ let struct_b = B {
+ b: "bar".to_string(),
+ c: 42,
+ };
+ match struct_b {
+ B { ref b, .. } if b == "bar" => {},
+ B { ref b, .. } if "bar" == b => {},
+ B { ref c, .. } if c == &1 => {},
+ B { ref c, .. } if &1 == c => {},
+ B { ref c, .. } if let &1 = c => {},
+ B { ref c, .. } if matches!(c, &1) => {},
+ _ => {},
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr
index 5bdf43d23..b8d7834e3 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.stderr
+++ b/src/tools/clippy/tests/ui/redundant_guards.stderr
@@ -1,10 +1,11 @@
error: redundant guard
- --> $DIR/redundant_guards.rs:34:20
+ --> $DIR/redundant_guards.rs:33:20
|
LL | C(x, y) if let 1 = y => ..,
| ^^^^^^^^^
|
= note: `-D clippy::redundant-guards` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_guards)]`
help: try
|
LL - C(x, y) if let 1 = y => ..,
@@ -12,7 +13,7 @@ LL + C(x, 1) => ..,
|
error: redundant guard
- --> $DIR/redundant_guards.rs:40:20
+ --> $DIR/redundant_guards.rs:39:20
|
LL | Some(x) if matches!(x, Some(1) if true) => ..,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +24,7 @@ LL | Some(Some(1)) if true => ..,
| ~~~~~~~ ~~~~~~~
error: redundant guard
- --> $DIR/redundant_guards.rs:41:20
+ --> $DIR/redundant_guards.rs:40:20
|
LL | Some(x) if matches!(x, Some(1)) => {
| ^^^^^^^^^^^^^^^^^^^^
@@ -35,7 +36,7 @@ LL + Some(Some(1)) => {
|
error: redundant guard
- --> $DIR/redundant_guards.rs:45:20
+ --> $DIR/redundant_guards.rs:44:20
|
LL | Some(x) if let Some(1) = x => ..,
| ^^^^^^^^^^^^^^^
@@ -47,7 +48,7 @@ LL + Some(Some(1)) => ..,
|
error: redundant guard
- --> $DIR/redundant_guards.rs:46:20
+ --> $DIR/redundant_guards.rs:45:20
|
LL | Some(x) if x == Some(2) => ..,
| ^^^^^^^^^^^^
@@ -59,7 +60,19 @@ LL + Some(Some(2)) => ..,
|
error: redundant guard
- --> $DIR/redundant_guards.rs:69:20
+ --> $DIR/redundant_guards.rs:46:20
+ |
+LL | Some(x) if Some(2) == x => ..,
+ | ^^^^^^^^^^^^
+ |
+help: try
+ |
+LL - Some(x) if Some(2) == x => ..,
+LL + Some(Some(2)) => ..,
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:71:20
|
LL | B { e } if matches!(e, Some(A(2))) => ..,
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,7 +84,7 @@ LL + B { e: Some(A(2)) } => ..,
|
error: redundant guard
- --> $DIR/redundant_guards.rs:106:20
+ --> $DIR/redundant_guards.rs:108:20
|
LL | E::A(y) if y == "not from an or pattern" => {},
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -83,7 +96,7 @@ LL + E::A("not from an or pattern") => {},
|
error: redundant guard
- --> $DIR/redundant_guards.rs:113:14
+ --> $DIR/redundant_guards.rs:115:14
|
LL | x if matches!(x, Some(0)) => ..,
| ^^^^^^^^^^^^^^^^^^^^
@@ -94,5 +107,101 @@ LL - x if matches!(x, Some(0)) => ..,
LL + Some(0) => ..,
|
-error: aborting due to 8 previous errors
+error: redundant guard
+ --> $DIR/redundant_guards.rs:165:28
+ |
+LL | Some(ref x) if x == &1 => {},
+ | ^^^^^^^
+ |
+help: try
+ |
+LL - Some(ref x) if x == &1 => {},
+LL + Some(1) => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:166:28
+ |
+LL | Some(ref x) if &1 == x => {},
+ | ^^^^^^^
+ |
+help: try
+ |
+LL - Some(ref x) if &1 == x => {},
+LL + Some(1) => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:167:28
+ |
+LL | Some(ref x) if let &2 = x => {},
+ | ^^^^^^^^^^
+ |
+help: try
+ |
+LL - Some(ref x) if let &2 = x => {},
+LL + Some(2) => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:168:28
+ |
+LL | Some(ref x) if matches!(x, &3) => {},
+ | ^^^^^^^^^^^^^^^
+ |
+help: try
+ |
+LL - Some(ref x) if matches!(x, &3) => {},
+LL + Some(3) => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:188:32
+ |
+LL | B { ref c, .. } if c == &1 => {},
+ | ^^^^^^^
+ |
+help: try
+ |
+LL - B { ref c, .. } if c == &1 => {},
+LL + B { c: 1, .. } => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:189:32
+ |
+LL | B { ref c, .. } if &1 == c => {},
+ | ^^^^^^^
+ |
+help: try
+ |
+LL - B { ref c, .. } if &1 == c => {},
+LL + B { c: 1, .. } => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:190:32
+ |
+LL | B { ref c, .. } if let &1 = c => {},
+ | ^^^^^^^^^^
+ |
+help: try
+ |
+LL - B { ref c, .. } if let &1 = c => {},
+LL + B { c: 1, .. } => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:191:32
+ |
+LL | B { ref c, .. } if matches!(c, &1) => {},
+ | ^^^^^^^^^^^^^^^
+ |
+help: try
+ |
+LL - B { ref c, .. } if matches!(c, &1) => {},
+LL + B { c: 1, .. } => {},
+ |
+
+error: aborting due to 17 previous errors
diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs
index 80af38f47..c5d93e436 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.rs
+++ b/src/tools/clippy/tests/ui/redundant_locals.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)]
#![warn(clippy::redundant_locals)]
diff --git a/src/tools/clippy/tests/ui/redundant_locals.stderr b/src/tools/clippy/tests/ui/redundant_locals.stderr
index 587de0575..13b872e95 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.stderr
+++ b/src/tools/clippy/tests/ui/redundant_locals.stderr
@@ -8,6 +8,7 @@ LL | let x = x;
|
= help: remove the redefinition of `x`
= note: `-D clippy::redundant-locals` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_locals)]`
error: redundant redefinition of a binding
--> $DIR/redundant_locals.rs:16:9
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed
index d1134de5a..148eaa4b3 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
// Issue #5746
#![warn(clippy::redundant_pattern_matching)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs
index d144086e7..5bc06f3cc 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
// Issue #5746
#![warn(clippy::redundant_pattern_matching)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr
index 28f33f0c9..28f0244b9 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr
@@ -1,5 +1,5 @@
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:17:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:15:12
|
LL | if let Ok(_) = m.lock() {}
| -------^^^^^----------- help: try: `if m.lock().is_ok()`
@@ -7,9 +7,10 @@ LL | if let Ok(_) = m.lock() {}
= note: this will change drop order of the result, as well as all temporaries
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:18:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:16:12
|
LL | if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {}
| -------^^^^^^------------------------------------ help: try: `if Err::<(), _>(m.lock().unwrap().0).is_err()`
@@ -18,7 +19,7 @@ LL | if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:21:16
+ --> $DIR/redundant_pattern_matching_drop_order.rs:19:16
|
LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {}
| -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()`
@@ -27,7 +28,7 @@ LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:23:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:21:12
|
LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {
| -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()`
@@ -36,31 +37,31 @@ LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:26:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:24:12
|
LL | if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {}
| -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:27:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:25:12
|
LL | if let Err(_) = Err::<std::sync::MutexGuard<()>, _>(()) {}
| -------^^^^^^------------------------------------------ help: try: `if Err::<std::sync::MutexGuard<()>, _>(()).is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:29:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:27:12
|
LL | if let Ok(_) = Ok::<_, ()>(String::new()) {}
| -------^^^^^----------------------------- help: try: `if Ok::<_, ()>(String::new()).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:30:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:28:12
|
LL | if let Err(_) = Err::<(), _>((String::new(), ())) {}
| -------^^^^^^------------------------------------ help: try: `if Err::<(), _>((String::new(), ())).is_err()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:33:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:31:12
|
LL | if let Some(_) = Some(m.lock()) {}
| -------^^^^^^^----------------- help: try: `if Some(m.lock()).is_some()`
@@ -69,7 +70,7 @@ LL | if let Some(_) = Some(m.lock()) {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:34:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:32:12
|
LL | if let Some(_) = Some(m.lock().unwrap().0) {}
| -------^^^^^^^---------------------------- help: try: `if Some(m.lock().unwrap().0).is_some()`
@@ -78,7 +79,7 @@ LL | if let Some(_) = Some(m.lock().unwrap().0) {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:37:16
+ --> $DIR/redundant_pattern_matching_drop_order.rs:35:16
|
LL | if let None = None::<std::sync::MutexGuard<()>> {}
| -------^^^^------------------------------------ help: try: `if None::<std::sync::MutexGuard<()>>.is_none()`
@@ -87,7 +88,7 @@ LL | if let None = None::<std::sync::MutexGuard<()>> {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:39:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:37:12
|
LL | if let None = None::<std::sync::MutexGuard<()>> {
| -------^^^^------------------------------------ help: try: `if None::<std::sync::MutexGuard<()>>.is_none()`
@@ -96,25 +97,25 @@ LL | if let None = None::<std::sync::MutexGuard<()>> {
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:43:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:41:12
|
LL | if let None = None::<std::sync::MutexGuard<()>> {}
| -------^^^^------------------------------------ help: try: `if None::<std::sync::MutexGuard<()>>.is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:45:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:43:12
|
LL | if let Some(_) = Some(String::new()) {}
| -------^^^^^^^---------------------- help: try: `if Some(String::new()).is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:46:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:44:12
|
LL | if let Some(_) = Some((String::new(), ())) {}
| -------^^^^^^^---------------------------- help: try: `if Some((String::new(), ())).is_some()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:49:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:47:12
|
LL | if let Ready(_) = Ready(m.lock()) {}
| -------^^^^^^^^------------------ help: try: `if Ready(m.lock()).is_ready()`
@@ -123,7 +124,7 @@ LL | if let Ready(_) = Ready(m.lock()) {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:50:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:48:12
|
LL | if let Ready(_) = Ready(m.lock().unwrap().0) {}
| -------^^^^^^^^----------------------------- help: try: `if Ready(m.lock().unwrap().0).is_ready()`
@@ -132,7 +133,7 @@ LL | if let Ready(_) = Ready(m.lock().unwrap().0) {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:53:16
+ --> $DIR/redundant_pattern_matching_drop_order.rs:51:16
|
LL | if let Pending = Pending::<std::sync::MutexGuard<()>> {}
| -------^^^^^^^--------------------------------------- help: try: `if Pending::<std::sync::MutexGuard<()>>.is_pending()`
@@ -141,7 +142,7 @@ LL | if let Pending = Pending::<std::sync::MutexGuard<()>> {}
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:55:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:53:12
|
LL | if let Pending = Pending::<std::sync::MutexGuard<()>> {
| -------^^^^^^^--------------------------------------- help: try: `if Pending::<std::sync::MutexGuard<()>>.is_pending()`
@@ -150,19 +151,19 @@ LL | if let Pending = Pending::<std::sync::MutexGuard<()>> {
= note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:59:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:57:12
|
LL | if let Pending = Pending::<std::sync::MutexGuard<()>> {}
| -------^^^^^^^--------------------------------------- help: try: `if Pending::<std::sync::MutexGuard<()>>.is_pending()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:61:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:59:12
|
LL | if let Ready(_) = Ready(String::new()) {}
| -------^^^^^^^^----------------------- help: try: `if Ready(String::new()).is_ready()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_drop_order.rs:62:12
+ --> $DIR/redundant_pattern_matching_drop_order.rs:60:12
|
LL | if let Ready(_) = Ready((String::new(), ())) {}
| -------^^^^^^^^----------------------------- help: try: `if Ready((String::new(), ())).is_ready()`
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed
index 02f197aa2..70dd9fc25 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::all, clippy::redundant_pattern_matching)]
#![allow(unused_must_use)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs
index 5c1e1810f..6e2a2f7b6 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::all, clippy::redundant_pattern_matching)]
#![allow(unused_must_use)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.stderr
index bec8d3088..d36129a2b 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.stderr
@@ -1,37 +1,38 @@
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:16:12
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:15:12
|
LL | if let V4(_) = &ipaddr {}
| -------^^^^^---------- help: try: `if ipaddr.is_ipv4()`
|
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:18:12
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:17:12
|
LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
| -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:20:12
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:19:12
|
LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
| -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:22:15
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:21:15
|
LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
| ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:24:15
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:23:15
|
LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
| ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:34:5
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:33:5
|
LL | / match V4(Ipv4Addr::LOCALHOST) {
LL | | V4(_) => true,
@@ -40,7 +41,7 @@ LL | | };
| |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:39:5
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:38:5
|
LL | / match V4(Ipv4Addr::LOCALHOST) {
LL | | V4(_) => false,
@@ -49,7 +50,7 @@ LL | | };
| |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv6()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:44:5
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:43:5
|
LL | / match V6(Ipv6Addr::LOCALHOST) {
LL | | V4(_) => false,
@@ -58,7 +59,7 @@ LL | | };
| |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:49:5
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:48:5
|
LL | / match V6(Ipv6Addr::LOCALHOST) {
LL | | V4(_) => true,
@@ -67,49 +68,49 @@ LL | | };
| |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:54:20
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:53:20
|
LL | let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) {
| -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:62:20
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:61:20
|
LL | let _ = if let V4(_) = gen_ipaddr() {
| -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv4()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:64:19
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:63:19
|
LL | } else if let V6(_) = gen_ipaddr() {
| -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv6()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:76:12
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:75:12
|
LL | if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
| -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:78:12
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:77:12
|
LL | if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
| -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:80:15
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:79:15
|
LL | while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}
| ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:82:15
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:81:15
|
LL | while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}
| ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()`
error: redundant pattern matching, consider using `is_ipv4()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:84:5
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:83:5
|
LL | / match V4(Ipv4Addr::LOCALHOST) {
LL | | V4(_) => true,
@@ -118,7 +119,7 @@ LL | | };
| |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()`
error: redundant pattern matching, consider using `is_ipv6()`
- --> $DIR/redundant_pattern_matching_ipaddr.rs:89:5
+ --> $DIR/redundant_pattern_matching_ipaddr.rs:88:5
|
LL | / match V6(Ipv6Addr::LOCALHOST) {
LL | | V4(_) => false,
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed
index d9fcd98c5..60f9fb6d4 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs
index cbd9494f1..94bbb569c 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr
index b0e43924d..fdf395d82 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.stderr
@@ -1,61 +1,62 @@
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:16:5
+ --> $DIR/redundant_pattern_matching_option.rs:14:5
|
LL | matches!(maybe_some, None if !boolean)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (!boolean)`
|
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:20:13
+ --> $DIR/redundant_pattern_matching_option.rs:18:13
|
LL | let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (boolean || boolean2)`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:29:12
+ --> $DIR/redundant_pattern_matching_option.rs:27:12
|
LL | if let None = None::<()> {}
| -------^^^^------------- help: try: `if None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:31:12
+ --> $DIR/redundant_pattern_matching_option.rs:29:12
|
LL | if let Some(_) = Some(42) {}
| -------^^^^^^^----------- help: try: `if Some(42).is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:33:12
+ --> $DIR/redundant_pattern_matching_option.rs:31:12
|
LL | if let Some(_) = Some(42) {
| -------^^^^^^^----------- help: try: `if Some(42).is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:39:15
+ --> $DIR/redundant_pattern_matching_option.rs:37:15
|
LL | while let Some(_) = Some(42) {}
| ----------^^^^^^^----------- help: try: `while Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:41:15
+ --> $DIR/redundant_pattern_matching_option.rs:39:15
|
LL | while let None = Some(42) {}
| ----------^^^^----------- help: try: `while Some(42).is_none()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:43:15
+ --> $DIR/redundant_pattern_matching_option.rs:41:15
|
LL | while let None = None::<()> {}
| ----------^^^^------------- help: try: `while None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:46:15
+ --> $DIR/redundant_pattern_matching_option.rs:44:15
|
LL | while let Some(_) = v.pop() {
| ----------^^^^^^^---------- help: try: `while v.pop().is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:54:5
+ --> $DIR/redundant_pattern_matching_option.rs:52:5
|
LL | / match Some(42) {
LL | | Some(_) => true,
@@ -64,7 +65,7 @@ LL | | };
| |_____^ help: try: `Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:59:5
+ --> $DIR/redundant_pattern_matching_option.rs:57:5
|
LL | / match None::<()> {
LL | | Some(_) => false,
@@ -73,7 +74,7 @@ LL | | };
| |_____^ help: try: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:64:13
+ --> $DIR/redundant_pattern_matching_option.rs:62:13
|
LL | let _ = match None::<()> {
| _____________^
@@ -83,55 +84,55 @@ LL | | };
| |_____^ help: try: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:70:20
+ --> $DIR/redundant_pattern_matching_option.rs:68:20
|
LL | let _ = if let Some(_) = opt { true } else { false };
| -------^^^^^^^------ help: try: `if opt.is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:76:20
+ --> $DIR/redundant_pattern_matching_option.rs:74:20
|
LL | let _ = if let Some(_) = gen_opt() {
| -------^^^^^^^------------ help: try: `if gen_opt().is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:78:19
+ --> $DIR/redundant_pattern_matching_option.rs:76:19
|
LL | } else if let None = gen_opt() {
| -------^^^^------------ help: try: `if gen_opt().is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:84:12
+ --> $DIR/redundant_pattern_matching_option.rs:82:12
|
LL | if let Some(..) = gen_opt() {}
| -------^^^^^^^^------------ help: try: `if gen_opt().is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:99:12
+ --> $DIR/redundant_pattern_matching_option.rs:97:12
|
LL | if let Some(_) = Some(42) {}
| -------^^^^^^^----------- help: try: `if Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:101:12
+ --> $DIR/redundant_pattern_matching_option.rs:99:12
|
LL | if let None = None::<()> {}
| -------^^^^------------- help: try: `if None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:103:15
+ --> $DIR/redundant_pattern_matching_option.rs:101:15
|
LL | while let Some(_) = Some(42) {}
| ----------^^^^^^^----------- help: try: `while Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:105:15
+ --> $DIR/redundant_pattern_matching_option.rs:103:15
|
LL | while let None = None::<()> {}
| ----------^^^^------------- help: try: `while None::<()>.is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:107:5
+ --> $DIR/redundant_pattern_matching_option.rs:105:5
|
LL | / match Some(42) {
LL | | Some(_) => true,
@@ -140,7 +141,7 @@ LL | | };
| |_____^ help: try: `Some(42).is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:112:5
+ --> $DIR/redundant_pattern_matching_option.rs:110:5
|
LL | / match None::<()> {
LL | | Some(_) => false,
@@ -149,19 +150,19 @@ LL | | };
| |_____^ help: try: `None::<()>.is_none()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:120:12
+ --> $DIR/redundant_pattern_matching_option.rs:118:12
|
LL | if let None = *(&None::<()>) {}
| -------^^^^----------------- help: try: `if (&None::<()>).is_none()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:121:12
+ --> $DIR/redundant_pattern_matching_option.rs:119:12
|
LL | if let None = *&None::<()> {}
| -------^^^^--------------- help: try: `if (&None::<()>).is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:127:5
+ --> $DIR/redundant_pattern_matching_option.rs:125:5
|
LL | / match x {
LL | | Some(_) => true,
@@ -170,7 +171,7 @@ LL | | };
| |_____^ help: try: `x.is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:132:5
+ --> $DIR/redundant_pattern_matching_option.rs:130:5
|
LL | / match x {
LL | | None => true,
@@ -179,7 +180,7 @@ LL | | };
| |_____^ help: try: `x.is_none()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:137:5
+ --> $DIR/redundant_pattern_matching_option.rs:135:5
|
LL | / match x {
LL | | Some(_) => false,
@@ -188,7 +189,7 @@ LL | | };
| |_____^ help: try: `x.is_none()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:142:5
+ --> $DIR/redundant_pattern_matching_option.rs:140:5
|
LL | / match x {
LL | | None => false,
@@ -197,13 +198,13 @@ LL | | };
| |_____^ help: try: `x.is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_option.rs:157:13
+ --> $DIR/redundant_pattern_matching_option.rs:155:13
|
LL | let _ = matches!(x, Some(_));
| ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/redundant_pattern_matching_option.rs:159:13
+ --> $DIR/redundant_pattern_matching_option.rs:157:13
|
LL | let _ = matches!(x, None);
| ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()`
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed
index f739deaf5..718c2f8ea 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs
index 88dde02b3..daa4761af 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.stderr
index 28d3606c4..c010c3c44 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.stderr
@@ -1,43 +1,44 @@
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:17:12
+ --> $DIR/redundant_pattern_matching_poll.rs:15:12
|
LL | if let Pending = Pending::<()> {}
| -------^^^^^^^---------------- help: try: `if Pending::<()>.is_pending()`
|
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:19:12
+ --> $DIR/redundant_pattern_matching_poll.rs:17:12
|
LL | if let Ready(_) = Ready(42) {}
| -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:21:12
+ --> $DIR/redundant_pattern_matching_poll.rs:19:12
|
LL | if let Ready(_) = Ready(42) {
| -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:27:15
+ --> $DIR/redundant_pattern_matching_poll.rs:25:15
|
LL | while let Ready(_) = Ready(42) {}
| ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:29:15
+ --> $DIR/redundant_pattern_matching_poll.rs:27:15
|
LL | while let Pending = Ready(42) {}
| ----------^^^^^^^------------ help: try: `while Ready(42).is_pending()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:31:15
+ --> $DIR/redundant_pattern_matching_poll.rs:29:15
|
LL | while let Pending = Pending::<()> {}
| ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:37:5
+ --> $DIR/redundant_pattern_matching_poll.rs:35:5
|
LL | / match Ready(42) {
LL | | Ready(_) => true,
@@ -46,7 +47,7 @@ LL | | };
| |_____^ help: try: `Ready(42).is_ready()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:42:5
+ --> $DIR/redundant_pattern_matching_poll.rs:40:5
|
LL | / match Pending::<()> {
LL | | Ready(_) => false,
@@ -55,7 +56,7 @@ LL | | };
| |_____^ help: try: `Pending::<()>.is_pending()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:47:13
+ --> $DIR/redundant_pattern_matching_poll.rs:45:13
|
LL | let _ = match Pending::<()> {
| _____________^
@@ -65,49 +66,49 @@ LL | | };
| |_____^ help: try: `Pending::<()>.is_pending()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:53:20
+ --> $DIR/redundant_pattern_matching_poll.rs:51:20
|
LL | let _ = if let Ready(_) = poll { true } else { false };
| -------^^^^^^^^------- help: try: `if poll.is_ready()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:57:20
+ --> $DIR/redundant_pattern_matching_poll.rs:55:20
|
LL | let _ = if let Ready(_) = gen_poll() {
| -------^^^^^^^^------------- help: try: `if gen_poll().is_ready()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:59:19
+ --> $DIR/redundant_pattern_matching_poll.rs:57:19
|
LL | } else if let Pending = gen_poll() {
| -------^^^^^^^------------- help: try: `if gen_poll().is_pending()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:75:12
+ --> $DIR/redundant_pattern_matching_poll.rs:73:12
|
LL | if let Ready(_) = Ready(42) {}
| -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:77:12
+ --> $DIR/redundant_pattern_matching_poll.rs:75:12
|
LL | if let Pending = Pending::<()> {}
| -------^^^^^^^---------------- help: try: `if Pending::<()>.is_pending()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:79:15
+ --> $DIR/redundant_pattern_matching_poll.rs:77:15
|
LL | while let Ready(_) = Ready(42) {}
| ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:81:15
+ --> $DIR/redundant_pattern_matching_poll.rs:79:15
|
LL | while let Pending = Pending::<()> {}
| ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()`
error: redundant pattern matching, consider using `is_ready()`
- --> $DIR/redundant_pattern_matching_poll.rs:83:5
+ --> $DIR/redundant_pattern_matching_poll.rs:81:5
|
LL | / match Ready(42) {
LL | | Ready(_) => true,
@@ -116,7 +117,7 @@ LL | | };
| |_____^ help: try: `Ready(42).is_ready()`
error: redundant pattern matching, consider using `is_pending()`
- --> $DIR/redundant_pattern_matching_poll.rs:88:5
+ --> $DIR/redundant_pattern_matching_poll.rs:86:5
|
LL | / match Pending::<()> {
LL | | Ready(_) => false,
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed
index 343e0d043..9571aaee7 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(deprecated, unused_must_use)]
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs
index 4d64eafe5..4fc65aa70 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::all)]
#![warn(clippy::redundant_pattern_matching)]
#![allow(deprecated, unused_must_use)]
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr
index 2b1ce9f54..19e7f8229 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.stderr
@@ -1,37 +1,38 @@
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:16:12
+ --> $DIR/redundant_pattern_matching_result.rs:15:12
|
LL | if let Ok(_) = &result {}
| -------^^^^^---------- help: try: `if result.is_ok()`
|
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:18:12
+ --> $DIR/redundant_pattern_matching_result.rs:17:12
|
LL | if let Ok(_) = Ok::<i32, i32>(42) {}
| -------^^^^^--------------------- help: try: `if Ok::<i32, i32>(42).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:20:12
+ --> $DIR/redundant_pattern_matching_result.rs:19:12
|
LL | if let Err(_) = Err::<i32, i32>(42) {}
| -------^^^^^^---------------------- help: try: `if Err::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:22:15
+ --> $DIR/redundant_pattern_matching_result.rs:21:15
|
LL | while let Ok(_) = Ok::<i32, i32>(10) {}
| ----------^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:24:15
+ --> $DIR/redundant_pattern_matching_result.rs:23:15
|
LL | while let Err(_) = Ok::<i32, i32>(10) {}
| ----------^^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:34:5
+ --> $DIR/redundant_pattern_matching_result.rs:33:5
|
LL | / match Ok::<i32, i32>(42) {
LL | | Ok(_) => true,
@@ -40,7 +41,7 @@ LL | | };
| |_____^ help: try: `Ok::<i32, i32>(42).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:39:5
+ --> $DIR/redundant_pattern_matching_result.rs:38:5
|
LL | / match Ok::<i32, i32>(42) {
LL | | Ok(_) => false,
@@ -49,7 +50,7 @@ LL | | };
| |_____^ help: try: `Ok::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:44:5
+ --> $DIR/redundant_pattern_matching_result.rs:43:5
|
LL | / match Err::<i32, i32>(42) {
LL | | Ok(_) => false,
@@ -58,7 +59,7 @@ LL | | };
| |_____^ help: try: `Err::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:49:5
+ --> $DIR/redundant_pattern_matching_result.rs:48:5
|
LL | / match Err::<i32, i32>(42) {
LL | | Ok(_) => true,
@@ -67,73 +68,73 @@ LL | | };
| |_____^ help: try: `Err::<i32, i32>(42).is_ok()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:54:20
+ --> $DIR/redundant_pattern_matching_result.rs:53:20
|
LL | let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };
| -------^^^^^--------------------- help: try: `if Ok::<usize, ()>(4).is_ok()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:62:20
+ --> $DIR/redundant_pattern_matching_result.rs:61:20
|
LL | let _ = if let Ok(_) = gen_res() {
| -------^^^^^------------ help: try: `if gen_res().is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:64:19
+ --> $DIR/redundant_pattern_matching_result.rs:63:19
|
LL | } else if let Err(_) = gen_res() {
| -------^^^^^^------------ help: try: `if gen_res().is_err()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_result.rs:87:19
+ --> $DIR/redundant_pattern_matching_result.rs:86:19
|
LL | while let Some(_) = r#try!(result_opt()) {}
| ----------^^^^^^^----------------------- help: try: `while r#try!(result_opt()).is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_result.rs:88:16
+ --> $DIR/redundant_pattern_matching_result.rs:87:16
|
LL | if let Some(_) = r#try!(result_opt()) {}
| -------^^^^^^^----------------------- help: try: `if r#try!(result_opt()).is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_result.rs:94:12
+ --> $DIR/redundant_pattern_matching_result.rs:93:12
|
LL | if let Some(_) = m!() {}
| -------^^^^^^^------- help: try: `if m!().is_some()`
error: redundant pattern matching, consider using `is_some()`
- --> $DIR/redundant_pattern_matching_result.rs:95:15
+ --> $DIR/redundant_pattern_matching_result.rs:94:15
|
LL | while let Some(_) = m!() {}
| ----------^^^^^^^------- help: try: `while m!().is_some()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:113:12
+ --> $DIR/redundant_pattern_matching_result.rs:112:12
|
LL | if let Ok(_) = Ok::<i32, i32>(42) {}
| -------^^^^^--------------------- help: try: `if Ok::<i32, i32>(42).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:115:12
+ --> $DIR/redundant_pattern_matching_result.rs:114:12
|
LL | if let Err(_) = Err::<i32, i32>(42) {}
| -------^^^^^^---------------------- help: try: `if Err::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:117:15
+ --> $DIR/redundant_pattern_matching_result.rs:116:15
|
LL | while let Ok(_) = Ok::<i32, i32>(10) {}
| ----------^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:119:15
+ --> $DIR/redundant_pattern_matching_result.rs:118:15
|
LL | while let Err(_) = Ok::<i32, i32>(10) {}
| ----------^^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:121:5
+ --> $DIR/redundant_pattern_matching_result.rs:120:5
|
LL | / match Ok::<i32, i32>(42) {
LL | | Ok(_) => true,
@@ -142,7 +143,7 @@ LL | | };
| |_____^ help: try: `Ok::<i32, i32>(42).is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:126:5
+ --> $DIR/redundant_pattern_matching_result.rs:125:5
|
LL | / match Err::<i32, i32>(42) {
LL | | Ok(_) => false,
@@ -151,7 +152,7 @@ LL | | };
| |_____^ help: try: `Err::<i32, i32>(42).is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:136:5
+ --> $DIR/redundant_pattern_matching_result.rs:135:5
|
LL | / match x {
LL | | Ok(_) => true,
@@ -160,7 +161,7 @@ LL | | };
| |_____^ help: try: `x.is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:141:5
+ --> $DIR/redundant_pattern_matching_result.rs:140:5
|
LL | / match x {
LL | | Ok(_) => false,
@@ -169,7 +170,7 @@ LL | | };
| |_____^ help: try: `x.is_err()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:146:5
+ --> $DIR/redundant_pattern_matching_result.rs:145:5
|
LL | / match x {
LL | | Err(_) => true,
@@ -178,7 +179,7 @@ LL | | };
| |_____^ help: try: `x.is_err()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:151:5
+ --> $DIR/redundant_pattern_matching_result.rs:150:5
|
LL | / match x {
LL | | Err(_) => false,
@@ -187,13 +188,13 @@ LL | | };
| |_____^ help: try: `x.is_ok()`
error: redundant pattern matching, consider using `is_ok()`
- --> $DIR/redundant_pattern_matching_result.rs:172:13
+ --> $DIR/redundant_pattern_matching_result.rs:171:13
|
LL | let _ = matches!(x, Ok(_));
| ^^^^^^^^^^^^^^^^^^ help: try: `x.is_ok()`
error: redundant pattern matching, consider using `is_err()`
- --> $DIR/redundant_pattern_matching_result.rs:174:13
+ --> $DIR/redundant_pattern_matching_result.rs:173:13
|
LL | let _ = matches!(x, Err(_));
| ^^^^^^^^^^^^^^^^^^^ help: try: `x.is_err()`
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
index a1ed491bb..e1d845721 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![warn(clippy::redundant_pub_crate)]
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.rs b/src/tools/clippy/tests/ui/redundant_pub_crate.rs
index 9accd297f..4d7f44892 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.rs
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#![warn(clippy::redundant_pub_crate)]
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.stderr b/src/tools/clippy/tests/ui/redundant_pub_crate.stderr
index 6fccdaa4e..5d7744aa8 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.stderr
@@ -1,5 +1,5 @@
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:7:5
+ --> $DIR/redundant_pub_crate.rs:6:5
|
LL | pub(crate) fn g() {} // private due to m1
| ----------^^^^^
@@ -7,9 +7,10 @@ LL | pub(crate) fn g() {} // private due to m1
| help: consider using: `pub`
|
= note: `-D clippy::redundant-pub-crate` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_pub_crate)]`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:12:9
+ --> $DIR/redundant_pub_crate.rs:11:9
|
LL | pub(crate) fn g() {} // private due to m1_1 and m1
| ----------^^^^^
@@ -17,7 +18,7 @@ LL | pub(crate) fn g() {} // private due to m1_1 and m1
| help: consider using: `pub`
error: pub(crate) module inside private module
- --> $DIR/redundant_pub_crate.rs:16:5
+ --> $DIR/redundant_pub_crate.rs:15:5
|
LL | pub(crate) mod m1_2 {
| ----------^^^^^^^^^
@@ -25,7 +26,7 @@ LL | pub(crate) mod m1_2 {
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:19:9
+ --> $DIR/redundant_pub_crate.rs:18:9
|
LL | pub(crate) fn g() {} // private due to m1_2 and m1
| ----------^^^^^
@@ -33,7 +34,7 @@ LL | pub(crate) fn g() {} // private due to m1_2 and m1
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:25:9
+ --> $DIR/redundant_pub_crate.rs:24:9
|
LL | pub(crate) fn g() {} // private due to m1
| ----------^^^^^
@@ -41,7 +42,7 @@ LL | pub(crate) fn g() {} // private due to m1
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:32:5
+ --> $DIR/redundant_pub_crate.rs:31:5
|
LL | pub(crate) fn g() {} // already crate visible due to m2
| ----------^^^^^
@@ -49,7 +50,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:37:9
+ --> $DIR/redundant_pub_crate.rs:36:9
|
LL | pub(crate) fn g() {} // private due to m2_1
| ----------^^^^^
@@ -57,7 +58,7 @@ LL | pub(crate) fn g() {} // private due to m2_1
| help: consider using: `pub`
error: pub(crate) module inside private module
- --> $DIR/redundant_pub_crate.rs:41:5
+ --> $DIR/redundant_pub_crate.rs:40:5
|
LL | pub(crate) mod m2_2 {
| ----------^^^^^^^^^
@@ -65,7 +66,7 @@ LL | pub(crate) mod m2_2 {
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:44:9
+ --> $DIR/redundant_pub_crate.rs:43:9
|
LL | pub(crate) fn g() {} // already crate visible due to m2_2 and m2
| ----------^^^^^
@@ -73,7 +74,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2_2 and m2
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:50:9
+ --> $DIR/redundant_pub_crate.rs:49:9
|
LL | pub(crate) fn g() {} // already crate visible due to m2
| ----------^^^^^
@@ -81,7 +82,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m2
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:62:9
+ --> $DIR/redundant_pub_crate.rs:61:9
|
LL | pub(crate) fn g() {} // private due to m3_1
| ----------^^^^^
@@ -89,7 +90,7 @@ LL | pub(crate) fn g() {} // private due to m3_1
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:69:9
+ --> $DIR/redundant_pub_crate.rs:68:9
|
LL | pub(crate) fn g() {} // already crate visible due to m3_2
| ----------^^^^^
@@ -97,7 +98,7 @@ LL | pub(crate) fn g() {} // already crate visible due to m3_2
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:82:5
+ --> $DIR/redundant_pub_crate.rs:81:5
|
LL | pub(crate) fn g() {} // private: not re-exported by `pub use m4::*`
| ----------^^^^^
@@ -105,7 +106,7 @@ LL | pub(crate) fn g() {} // private: not re-exported by `pub use m4::*`
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:87:9
+ --> $DIR/redundant_pub_crate.rs:86:9
|
LL | pub(crate) fn g() {} // private due to m4_1
| ----------^^^^^
@@ -113,7 +114,7 @@ LL | pub(crate) fn g() {} // private due to m4_1
| help: consider using: `pub`
error: pub(crate) module inside private module
- --> $DIR/redundant_pub_crate.rs:91:5
+ --> $DIR/redundant_pub_crate.rs:90:5
|
LL | pub(crate) mod m4_2 {
| ----------^^^^^^^^^
@@ -121,7 +122,7 @@ LL | pub(crate) mod m4_2 {
| help: consider using: `pub`
error: pub(crate) function inside private module
- --> $DIR/redundant_pub_crate.rs:94:9
+ --> $DIR/redundant_pub_crate.rs:93:9
|
LL | pub(crate) fn g() {} // private due to m4_2
| ----------^^^^^
diff --git a/src/tools/clippy/tests/ui/redundant_slicing.fixed b/src/tools/clippy/tests/ui/redundant_slicing.fixed
index 56ddca719..a4c035ba8 100644
--- a/src/tools/clippy/tests/ui/redundant_slicing.fixed
+++ b/src/tools/clippy/tests/ui/redundant_slicing.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::deref_by_slicing)]
#![warn(clippy::redundant_slicing)]
diff --git a/src/tools/clippy/tests/ui/redundant_slicing.rs b/src/tools/clippy/tests/ui/redundant_slicing.rs
index d67b6665e..67fe702ac 100644
--- a/src/tools/clippy/tests/ui/redundant_slicing.rs
+++ b/src/tools/clippy/tests/ui/redundant_slicing.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused, clippy::deref_by_slicing)]
#![warn(clippy::redundant_slicing)]
diff --git a/src/tools/clippy/tests/ui/redundant_slicing.stderr b/src/tools/clippy/tests/ui/redundant_slicing.stderr
index 82367143c..05287c882 100644
--- a/src/tools/clippy/tests/ui/redundant_slicing.stderr
+++ b/src/tools/clippy/tests/ui/redundant_slicing.stderr
@@ -1,19 +1,20 @@
error: redundant slicing of the whole range
- --> $DIR/redundant_slicing.rs:10:13
+ --> $DIR/redundant_slicing.rs:8:13
|
LL | let _ = &slice[..]; // Redundant slice
| ^^^^^^^^^^ help: use the original value instead: `slice`
|
= note: `-D clippy::redundant-slicing` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_slicing)]`
error: redundant slicing of the whole range
- --> $DIR/redundant_slicing.rs:14:13
+ --> $DIR/redundant_slicing.rs:12:13
|
LL | let _ = &(&*v)[..]; // Outer borrow is redundant
| ^^^^^^^^^^ help: use the original value instead: `(&*v)`
error: redundant slicing of the whole range
- --> $DIR/redundant_slicing.rs:31:13
+ --> $DIR/redundant_slicing.rs:29:13
|
LL | let _ = &m!(slice)[..];
| ^^^^^^^^^^^^^^ help: use the original value instead: `slice`
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
index a83699ec6..9787bb635 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#[derive(Debug)]
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
index b165cbaa3..b5a4827fa 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused)]
#[derive(Debug)]
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr b/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
index a13e5eadf..26f503453 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
@@ -1,109 +1,110 @@
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:8:17
+ --> $DIR/redundant_static_lifetimes.rs:6:17
|
LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removing 'static.
| -^^^^^^^---- help: consider removing `'static`: `&str`
|
= note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:12:21
+ --> $DIR/redundant_static_lifetimes.rs:10:21
|
LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:14:32
+ --> $DIR/redundant_static_lifetimes.rs:12:32
|
LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:14:47
+ --> $DIR/redundant_static_lifetimes.rs:12:47
|
LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:16:17
+ --> $DIR/redundant_static_lifetimes.rs:14:17
|
LL | const VAR_SIX: &'static u8 = &5;
| -^^^^^^^--- help: consider removing `'static`: `&u8`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:18:20
+ --> $DIR/redundant_static_lifetimes.rs:16:20
|
LL | const VAR_HEIGHT: &'static Foo = &Foo {};
| -^^^^^^^---- help: consider removing `'static`: `&Foo`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:20:19
+ --> $DIR/redundant_static_lifetimes.rs:18:19
|
LL | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static.
| -^^^^^^^----- help: consider removing `'static`: `&[u8]`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:22:19
+ --> $DIR/redundant_static_lifetimes.rs:20:19
|
LL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.
| -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:24:19
+ --> $DIR/redundant_static_lifetimes.rs:22:19
|
LL | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static.
| -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:26:25
+ --> $DIR/redundant_static_lifetimes.rs:24:25
|
LL | static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static.
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:30:29
+ --> $DIR/redundant_static_lifetimes.rs:28:29
|
LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:32:25
+ --> $DIR/redundant_static_lifetimes.rs:30:25
|
LL | static STATIC_VAR_SIX: &'static u8 = &5;
| -^^^^^^^--- help: consider removing `'static`: `&u8`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:34:28
+ --> $DIR/redundant_static_lifetimes.rs:32:28
|
LL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {};
| -^^^^^^^---- help: consider removing `'static`: `&Foo`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:36:27
+ --> $DIR/redundant_static_lifetimes.rs:34:27
|
LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static.
| -^^^^^^^----- help: consider removing `'static`: `&[u8]`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:38:27
+ --> $DIR/redundant_static_lifetimes.rs:36:27
|
LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.
| -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:40:27
+ --> $DIR/redundant_static_lifetimes.rs:38:27
|
LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static.
| -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:42:31
+ --> $DIR/redundant_static_lifetimes.rs:40:31
|
LL | static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0];
| -^^^^^^^---------- help: consider removing `'static`: `&mut [u32]`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:71:16
+ --> $DIR/redundant_static_lifetimes.rs:69:16
|
LL | static V: &'static u8 = &17;
| -^^^^^^^--- help: consider removing `'static`: `&u8`
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.rs b/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.rs
index b3f263a7d..bfcab420b 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.rs
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.rs
@@ -1,13 +1,25 @@
+//@no-rustfix: overlapping suggestions
// these are rustfixable, but run-rustfix tests cannot handle them
const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static
+//~^ ERROR: constants have by default a `'static` lifetime
+//~| NOTE: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`
+//~| ERROR: constants have by default a `'static` lifetime
const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
+//~^ ERROR: constants have by default a `'static` lifetime
+//~| ERROR: constants have by default a `'static` lifetime
static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
+//~^ ERROR: statics have by default a `'static` lifetime
+//~| ERROR: statics have by default a `'static` lifetime
static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static
+//~^ ERROR: statics have by default a `'static` lifetime
+//~| ERROR: statics have by default a `'static` lifetime
static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
+//~^ ERROR: statics have by default a `'static` lifetime
+//~| ERROR: statics have by default a `'static` lifetime
fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.stderr b/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.stderr
index 4e7500903..bf4d21120 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.stderr
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes_multiple.stderr
@@ -1,61 +1,62 @@
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:3:18
+ --> $DIR/redundant_static_lifetimes_multiple.rs:4:18
|
LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static
| -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`
|
= note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:3:30
+ --> $DIR/redundant_static_lifetimes_multiple.rs:4:30
|
LL | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:5:29
+ --> $DIR/redundant_static_lifetimes_multiple.rs:9:29
|
LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:5:39
+ --> $DIR/redundant_static_lifetimes_multiple.rs:9:39
|
LL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:7:40
+ --> $DIR/redundant_static_lifetimes_multiple.rs:13:40
|
LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:7:55
+ --> $DIR/redundant_static_lifetimes_multiple.rs:13:55
|
LL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:9:26
+ --> $DIR/redundant_static_lifetimes_multiple.rs:17:26
|
LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static
| -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:9:38
+ --> $DIR/redundant_static_lifetimes_multiple.rs:17:38
|
LL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR: Consider removing 'static
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:11:37
+ --> $DIR/redundant_static_lifetimes_multiple.rs:21:37
|
LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
error: statics have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes_multiple.rs:11:47
+ --> $DIR/redundant_static_lifetimes_multiple.rs:21:47
|
LL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
| -^^^^^^^---- help: consider removing `'static`: `&str`
diff --git a/src/tools/clippy/tests/ui/redundant_type_annotations.rs b/src/tools/clippy/tests/ui/redundant_type_annotations.rs
index 09dbd3c9b..acf53fea2 100644
--- a/src/tools/clippy/tests/ui/redundant_type_annotations.rs
+++ b/src/tools/clippy/tests/ui/redundant_type_annotations.rs
@@ -79,8 +79,12 @@ impl Pie {
// Everything here should be lint
let v: u32 = self.return_an_int();
+ //~^ ERROR: redundant type annotation
+ //~| NOTE: `-D clippy::redundant-type-annotations` implied by `-D warnings`
let v: &u32 = self.return_a_ref();
+ //~^ ERROR: redundant type annotation
let v: &Slice = self.return_a_ref_to_struct();
+ //~^ ERROR: redundant type annotation
}
}
@@ -153,36 +157,50 @@ fn test_functions() {
// Everything here should be lint
let _return: String = return_a_string();
+ //~^ ERROR: redundant type annotation
let _return: Pie = return_a_struct();
+ //~^ ERROR: redundant type annotation
let _return: Pizza = return_an_enum();
+ //~^ ERROR: redundant type annotation
let _return: u32 = return_an_int();
+ //~^ ERROR: redundant type annotation
let _return: String = String::new();
+ //~^ ERROR: redundant type annotation
let new_pie: Pie = Pie::new();
+ //~^ ERROR: redundant type annotation
let _return: u32 = new_pie.return_an_int();
+ //~^ ERROR: redundant type annotation
let _return: u32 = Pie::associated_return_an_int();
+ //~^ ERROR: redundant type annotation
let _return: String = Pie::associated_return_a_string();
+ //~^ ERROR: redundant type annotation
}
fn test_simple_types() {
// Everything here should be lint
let _var: u32 = u32::MAX;
+ //~^ ERROR: redundant type annotation
let _var: u32 = 5_u32;
+ //~^ ERROR: redundant type annotation
let _var: &str = "test";
+ //~^ ERROR: redundant type annotation
let _var: &[u8] = b"test";
+ //~^ ERROR: redundant type annotation
let _var: bool = false;
+ //~^ ERROR: redundant type annotation
}
fn issue11190() {}
diff --git a/src/tools/clippy/tests/ui/redundant_type_annotations.stderr b/src/tools/clippy/tests/ui/redundant_type_annotations.stderr
index 988ebe637..d1f26f183 100644
--- a/src/tools/clippy/tests/ui/redundant_type_annotations.stderr
+++ b/src/tools/clippy/tests/ui/redundant_type_annotations.stderr
@@ -5,99 +5,100 @@ LL | let v: u32 = self.return_an_int();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::redundant-type-annotations` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_type_annotations)]`
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:82:9
+ --> $DIR/redundant_type_annotations.rs:84:9
|
LL | let v: &u32 = self.return_a_ref();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:83:9
+ --> $DIR/redundant_type_annotations.rs:86:9
|
LL | let v: &Slice = self.return_a_ref_to_struct();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:155:5
+ --> $DIR/redundant_type_annotations.rs:159:5
|
LL | let _return: String = return_a_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:157:5
+ --> $DIR/redundant_type_annotations.rs:162:5
|
LL | let _return: Pie = return_a_struct();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:159:5
+ --> $DIR/redundant_type_annotations.rs:165:5
|
LL | let _return: Pizza = return_an_enum();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:161:5
+ --> $DIR/redundant_type_annotations.rs:168:5
|
LL | let _return: u32 = return_an_int();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:163:5
+ --> $DIR/redundant_type_annotations.rs:171:5
|
LL | let _return: String = String::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:165:5
+ --> $DIR/redundant_type_annotations.rs:174:5
|
LL | let new_pie: Pie = Pie::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:167:5
+ --> $DIR/redundant_type_annotations.rs:177:5
|
LL | let _return: u32 = new_pie.return_an_int();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:169:5
+ --> $DIR/redundant_type_annotations.rs:180:5
|
LL | let _return: u32 = Pie::associated_return_an_int();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:171:5
+ --> $DIR/redundant_type_annotations.rs:183:5
|
LL | let _return: String = Pie::associated_return_a_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:177:5
+ --> $DIR/redundant_type_annotations.rs:190:5
|
LL | let _var: u32 = u32::MAX;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:179:5
+ --> $DIR/redundant_type_annotations.rs:193:5
|
LL | let _var: u32 = 5_u32;
| ^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:181:5
+ --> $DIR/redundant_type_annotations.rs:196:5
|
LL | let _var: &str = "test";
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:183:5
+ --> $DIR/redundant_type_annotations.rs:199:5
|
LL | let _var: &[u8] = b"test";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant type annotation
- --> $DIR/redundant_type_annotations.rs:185:5
+ --> $DIR/redundant_type_annotations.rs:202:5
|
LL | let _var: bool = false;
| ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs
index c8d0e56b1..a4444c95e 100644
--- a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs
+++ b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs
@@ -1,5 +1,5 @@
// FIXME: run-rustfix waiting on multi-span suggestions
-
+//@no-rustfix
#![feature(lint_reasons)]
#![warn(clippy::ref_binding_to_reference)]
#![allow(clippy::needless_borrowed_reference, clippy::explicit_auto_deref)]
@@ -29,12 +29,15 @@ fn main() {
// Err, reference to a &String
let _: &&String = match Some(&x) {
Some(ref x) => x,
+ //~^ ERROR: this pattern creates a reference to a reference
+ //~| NOTE: `-D clippy::ref-binding-to-reference` implied by `-D warnings`
None => return,
};
// Err, reference to a &String
let _: &&String = match Some(&x) {
Some(ref x) => {
+ //~^ ERROR: this pattern creates a reference to a reference
f1(x);
f1(*x);
x
@@ -45,17 +48,20 @@ fn main() {
// Err, reference to a &String
match Some(&x) {
Some(ref x) => m2!(x),
+ //~^ ERROR: this pattern creates a reference to a reference
None => return,
}
// Err, reference to a &String
let _ = |&ref x: &&String| {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &&String = x;
};
}
// Err, reference to a &String
fn f2<'a>(&ref x: &&'a String) -> &'a String {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &&String = x;
*x
}
@@ -63,6 +69,7 @@ fn f2<'a>(&ref x: &&'a String) -> &'a String {
trait T1 {
// Err, reference to a &String
fn f(&ref x: &&String) {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &&String = x;
}
}
@@ -71,6 +78,7 @@ struct S;
impl T1 for S {
// Err, reference to a &String
fn f(&ref x: &&String) {
+ //~^ ERROR: this pattern creates a reference to a reference
let _: &&String = x;
}
}
diff --git a/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr b/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr
index 016feb103..6e8b43a3e 100644
--- a/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr
+++ b/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr
@@ -5,13 +5,14 @@ LL | Some(ref x) => x,
| ^^^^^
|
= note: `-D clippy::ref-binding-to-reference` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ref_binding_to_reference)]`
help: try
|
LL | Some(x) => &x,
| ~ ~~
error: this pattern creates a reference to a reference
- --> $DIR/ref_binding_to_reference.rs:37:14
+ --> $DIR/ref_binding_to_reference.rs:39:14
|
LL | Some(ref x) => {
| ^^^^^
@@ -19,13 +20,14 @@ LL | Some(ref x) => {
help: try
|
LL ~ Some(x) => {
+LL |
LL | f1(x);
LL ~ f1(x);
LL ~ &x
|
error: this pattern creates a reference to a reference
- --> $DIR/ref_binding_to_reference.rs:47:14
+ --> $DIR/ref_binding_to_reference.rs:50:14
|
LL | Some(ref x) => m2!(x),
| ^^^^^
@@ -36,7 +38,7 @@ LL | Some(x) => m2!(&x),
| ~ ~~
error: this pattern creates a reference to a reference
- --> $DIR/ref_binding_to_reference.rs:52:15
+ --> $DIR/ref_binding_to_reference.rs:56:15
|
LL | let _ = |&ref x: &&String| {
| ^^^^^
@@ -44,11 +46,12 @@ LL | let _ = |&ref x: &&String| {
help: try
|
LL ~ let _ = |&x: &&String| {
+LL |
LL ~ let _: &&String = &x;
|
error: this pattern creates a reference to a reference
- --> $DIR/ref_binding_to_reference.rs:58:12
+ --> $DIR/ref_binding_to_reference.rs:63:12
|
LL | fn f2<'a>(&ref x: &&'a String) -> &'a String {
| ^^^^^
@@ -56,12 +59,13 @@ LL | fn f2<'a>(&ref x: &&'a String) -> &'a String {
help: try
|
LL ~ fn f2<'a>(&x: &&'a String) -> &'a String {
+LL |
LL ~ let _: &&String = &x;
LL ~ x
|
error: this pattern creates a reference to a reference
- --> $DIR/ref_binding_to_reference.rs:65:11
+ --> $DIR/ref_binding_to_reference.rs:71:11
|
LL | fn f(&ref x: &&String) {
| ^^^^^
@@ -69,11 +73,12 @@ LL | fn f(&ref x: &&String) {
help: try
|
LL ~ fn f(&x: &&String) {
+LL |
LL ~ let _: &&String = &x;
|
error: this pattern creates a reference to a reference
- --> $DIR/ref_binding_to_reference.rs:73:11
+ --> $DIR/ref_binding_to_reference.rs:80:11
|
LL | fn f(&ref x: &&String) {
| ^^^^^
@@ -81,6 +86,7 @@ LL | fn f(&ref x: &&String) {
help: try
|
LL ~ fn f(&x: &&String) {
+LL |
LL ~ let _: &&String = &x;
|
diff --git a/src/tools/clippy/tests/ui/ref_option_ref.rs b/src/tools/clippy/tests/ui/ref_option_ref.rs
index e487799e1..44001c45e 100644
--- a/src/tools/clippy/tests/ui/ref_option_ref.rs
+++ b/src/tools/clippy/tests/ui/ref_option_ref.rs
@@ -1,6 +1,6 @@
#![allow(unused)]
#![warn(clippy::ref_option_ref)]
-
+//@no-rustfix
// This lint is not tagged as run-rustfix because automatically
// changing the type of a variable would also means changing
// all usages of this variable to match and This is not handled
@@ -8,27 +8,37 @@
static THRESHOLD: i32 = 10;
static REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD);
+//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt
+//~| NOTE: `-D clippy::ref-option-ref` implied by `-D warnings`
const CONST_THRESHOLD: &i32 = &10;
const REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD);
+//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt
type RefOptRefU32<'a> = &'a Option<&'a u32>;
+//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt
type RefOptRef<'a, T> = &'a Option<&'a T>;
+//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt
fn foo(data: &Option<&u32>) {}
+//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt
fn bar(data: &u32) -> &Option<&u32> {
+ //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt
&None
}
struct StructRef<'a> {
data: &'a Option<&'a u32>,
+ //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to
}
struct StructTupleRef<'a>(u32, &'a Option<&'a u32>);
+//~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Opt
enum EnumRef<'a> {
Variant1(u32),
Variant2(&'a Option<&'a u32>),
+ //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to
}
trait RefOptTrait {
@@ -38,12 +48,14 @@ trait RefOptTrait {
impl RefOptTrait for u32 {
type A = &'static Option<&'static Self>;
+ //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to
fn foo(&self, _: Self::A) {}
}
fn main() {
let x: &Option<&u32> = &None;
+ //~^ ERROR: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to
}
fn issue9682(arg: &Option<&mut String>) {
diff --git a/src/tools/clippy/tests/ui/ref_option_ref.stderr b/src/tools/clippy/tests/ui/ref_option_ref.stderr
index b61334758..6a28a68dc 100644
--- a/src/tools/clippy/tests/ui/ref_option_ref.stderr
+++ b/src/tools/clippy/tests/ui/ref_option_ref.stderr
@@ -5,63 +5,64 @@ LL | static REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD);
| ^^^^^^^^^^^^^ help: try: `Option<&i32>`
|
= note: `-D clippy::ref-option-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ref_option_ref)]`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:12:18
+ --> $DIR/ref_option_ref.rs:14:18
|
LL | const REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD);
| ^^^^^^^^^^^^^ help: try: `Option<&i32>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:14:25
+ --> $DIR/ref_option_ref.rs:17:25
|
LL | type RefOptRefU32<'a> = &'a Option<&'a u32>;
| ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:15:25
+ --> $DIR/ref_option_ref.rs:19:25
|
LL | type RefOptRef<'a, T> = &'a Option<&'a T>;
| ^^^^^^^^^^^^^^^^^ help: try: `Option<&'a T>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:17:14
+ --> $DIR/ref_option_ref.rs:22:14
|
LL | fn foo(data: &Option<&u32>) {}
| ^^^^^^^^^^^^^ help: try: `Option<&u32>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:19:23
+ --> $DIR/ref_option_ref.rs:25:23
|
LL | fn bar(data: &u32) -> &Option<&u32> {
| ^^^^^^^^^^^^^ help: try: `Option<&u32>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:24:11
+ --> $DIR/ref_option_ref.rs:31:11
|
LL | data: &'a Option<&'a u32>,
| ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:27:32
+ --> $DIR/ref_option_ref.rs:35:32
|
LL | struct StructTupleRef<'a>(u32, &'a Option<&'a u32>);
| ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:31:14
+ --> $DIR/ref_option_ref.rs:40:14
|
LL | Variant2(&'a Option<&'a u32>),
| ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:40:14
+ --> $DIR/ref_option_ref.rs:50:14
|
LL | type A = &'static Option<&'static Self>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'static Self>`
error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`
- --> $DIR/ref_option_ref.rs:46:12
+ --> $DIR/ref_option_ref.rs:57:12
|
LL | let x: &Option<&u32> = &None;
| ^^^^^^^^^^^^^ help: try: `Option<&u32>`
diff --git a/src/tools/clippy/tests/ui/ref_patterns.rs b/src/tools/clippy/tests/ui/ref_patterns.rs
index c51e0bc76..acd42ec89 100644
--- a/src/tools/clippy/tests/ui/ref_patterns.rs
+++ b/src/tools/clippy/tests/ui/ref_patterns.rs
@@ -6,14 +6,17 @@ fn use_in_pattern() {
match opt {
None => {},
Some(ref opt) => {},
+ //~^ ERROR: usage of ref pattern
}
}
fn use_in_binding() {
let x = 5;
let ref y = x;
+ //~^ ERROR: usage of ref pattern
}
fn use_in_parameter(ref x: i32) {}
+//~^ ERROR: usage of ref pattern
fn main() {}
diff --git a/src/tools/clippy/tests/ui/ref_patterns.stderr b/src/tools/clippy/tests/ui/ref_patterns.stderr
index aa0077826..74892bac6 100644
--- a/src/tools/clippy/tests/ui/ref_patterns.stderr
+++ b/src/tools/clippy/tests/ui/ref_patterns.stderr
@@ -6,9 +6,10 @@ LL | Some(ref opt) => {},
|
= help: consider using `&` for clarity instead
= note: `-D clippy::ref-patterns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::ref_patterns)]`
error: usage of ref pattern
- --> $DIR/ref_patterns.rs:14:9
+ --> $DIR/ref_patterns.rs:15:9
|
LL | let ref y = x;
| ^^^^^
@@ -16,7 +17,7 @@ LL | let ref y = x;
= help: consider using `&` for clarity instead
error: usage of ref pattern
- --> $DIR/ref_patterns.rs:17:21
+ --> $DIR/ref_patterns.rs:19:21
|
LL | fn use_in_parameter(ref x: i32) {}
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs
index 89d1d9494..094d9574a 100644
--- a/src/tools/clippy/tests/ui/regex.rs
+++ b/src/tools/clippy/tests/ui/regex.rs
@@ -2,7 +2,8 @@
unused,
clippy::needless_raw_strings,
clippy::needless_raw_string_hashes,
- clippy::needless_borrow
+ clippy::needless_borrow,
+ clippy::needless_borrows_for_generic_args
)]
#![warn(clippy::invalid_regex, clippy::trivial_regex)]
@@ -16,13 +17,19 @@ const NOT_A_REAL_REGEX: &str = "foobar";
fn syntax_error() {
let pipe_in_wrong_position = Regex::new("|");
+ //~^ ERROR: trivial regex
let pipe_in_wrong_position_builder = RegexBuilder::new("|");
+ //~^ ERROR: trivial regex
let wrong_char_ranice = Regex::new("[z-a]");
+ //~^ ERROR: regex syntax error: invalid character class range, the start must be <= th
+ //~| NOTE: `-D clippy::invalid-regex` implied by `-D warnings`
let some_unicode = Regex::new("[é-è]");
+ //~^ ERROR: regex syntax error: invalid character class range, the start must be <= th
let some_regex = Regex::new(OPENING_PAREN);
let binary_pipe_in_wrong_position = BRegex::new("|");
+ //~^ ERROR: trivial regex
let some_binary_regex = BRegex::new(OPENING_PAREN);
let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN);
@@ -47,36 +54,49 @@ fn syntax_error() {
let escaped_string_span = Regex::new("\\b\\c");
let aux_span = Regex::new("(?ixi)");
+ //~^ ERROR: regex syntax error: duplicate flag
let should_not_lint = Regex::new("(?u).");
let should_not_lint = BRegex::new("(?u).");
let invalid_utf8_should_not_lint = BRegex::new("(?-u).");
let invalid_utf8_should_lint = Regex::new("(?-u).");
+ //~^ ERROR: regex syntax error: pattern can match invalid UTF-8
}
fn trivial_regex() {
let trivial_eq = Regex::new("^foobar$");
+ //~^ ERROR: trivial regex
let trivial_eq_builder = RegexBuilder::new("^foobar$");
+ //~^ ERROR: trivial regex
let trivial_starts_with = Regex::new("^foobar");
+ //~^ ERROR: trivial regex
let trivial_ends_with = Regex::new("foobar$");
+ //~^ ERROR: trivial regex
let trivial_contains = Regex::new("foobar");
+ //~^ ERROR: trivial regex
let trivial_contains = Regex::new(NOT_A_REAL_REGEX);
+ //~^ ERROR: trivial regex
let trivial_backslash = Regex::new("a\\.b");
+ //~^ ERROR: trivial regex
// unlikely corner cases
let trivial_empty = Regex::new("");
+ //~^ ERROR: trivial regex
let trivial_empty = Regex::new("^");
+ //~^ ERROR: trivial regex
let trivial_empty = Regex::new("^$");
+ //~^ ERROR: trivial regex
let binary_trivial_empty = BRegex::new("^$");
+ //~^ ERROR: trivial regex
// non-trivial regexes
let non_trivial_dot = Regex::new("a.b");
diff --git a/src/tools/clippy/tests/ui/regex.stderr b/src/tools/clippy/tests/ui/regex.stderr
index 21f1cb444..6d98d691d 100644
--- a/src/tools/clippy/tests/ui/regex.stderr
+++ b/src/tools/clippy/tests/ui/regex.stderr
@@ -1,14 +1,15 @@
error: trivial regex
- --> $DIR/regex.rs:18:45
+ --> $DIR/regex.rs:19:45
|
LL | let pipe_in_wrong_position = Regex::new("|");
| ^^^
|
= help: the regex is unlikely to be useful as it is
= note: `-D clippy::trivial-regex` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::trivial_regex)]`
error: trivial regex
- --> $DIR/regex.rs:19:60
+ --> $DIR/regex.rs:21:60
|
LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|");
| ^^^
@@ -16,15 +17,16 @@ LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|");
= help: the regex is unlikely to be useful as it is
error: regex syntax error: invalid character class range, the start must be <= the end
- --> $DIR/regex.rs:20:42
+ --> $DIR/regex.rs:23:42
|
LL | let wrong_char_ranice = Regex::new("[z-a]");
| ^^^
|
= note: `-D clippy::invalid-regex` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::invalid_regex)]`
error: regex syntax error: invalid character class range, the start must be <= the end
- --> $DIR/regex.rs:21:37
+ --> $DIR/regex.rs:26:37
|
LL | let some_unicode = Regex::new("[é-è]");
| ^^^
@@ -33,13 +35,13 @@ error: regex parse error:
(
^
error: unclosed group
- --> $DIR/regex.rs:23:33
+ --> $DIR/regex.rs:29:33
|
LL | let some_regex = Regex::new(OPENING_PAREN);
| ^^^^^^^^^^^^^
error: trivial regex
- --> $DIR/regex.rs:25:53
+ --> $DIR/regex.rs:31:53
|
LL | let binary_pipe_in_wrong_position = BRegex::new("|");
| ^^^
@@ -50,7 +52,7 @@ error: regex parse error:
(
^
error: unclosed group
- --> $DIR/regex.rs:26:41
+ --> $DIR/regex.rs:33:41
|
LL | let some_binary_regex = BRegex::new(OPENING_PAREN);
| ^^^^^^^^^^^^^
@@ -59,7 +61,7 @@ error: regex parse error:
(
^
error: unclosed group
- --> $DIR/regex.rs:27:56
+ --> $DIR/regex.rs:34:56
|
LL | let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN);
| ^^^^^^^^^^^^^
@@ -68,45 +70,45 @@ error: regex parse error:
(
^
error: unclosed group
- --> $DIR/regex.rs:39:37
+ --> $DIR/regex.rs:46:37
|
-LL | let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]);
+LL | let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]);
| ^^^^^^^^^^^^^
error: regex parse error:
(
^
error: unclosed group
- --> $DIR/regex.rs:40:39
+ --> $DIR/regex.rs:47:39
|
-LL | let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]);
+LL | let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]);
| ^^^^^^^^^^^^^
error: regex parse error:
- /b/c
+ \b\c
^^
error: unrecognized escape sequence
- --> $DIR/regex.rs:47:42
+ --> $DIR/regex.rs:54:42
|
-LL | let escaped_string_span = Regex::new("//b//c");
+LL | let escaped_string_span = Regex::new("\\b\\c");
| ^^^^^^^^
|
= help: consider using a raw string literal: `r".."`
error: regex syntax error: duplicate flag
- --> $DIR/regex.rs:49:34
+ --> $DIR/regex.rs:56:34
|
LL | let aux_span = Regex::new("(?ixi)");
| ^ ^
error: regex syntax error: pattern can match invalid UTF-8
- --> $DIR/regex.rs:54:53
+ --> $DIR/regex.rs:62:53
|
LL | let invalid_utf8_should_lint = Regex::new("(?-u).");
| ^
error: trivial regex
- --> $DIR/regex.rs:58:33
+ --> $DIR/regex.rs:67:33
|
LL | let trivial_eq = Regex::new("^foobar$");
| ^^^^^^^^^^
@@ -114,7 +116,7 @@ LL | let trivial_eq = Regex::new("^foobar$");
= help: consider using `==` on `str`s
error: trivial regex
- --> $DIR/regex.rs:60:48
+ --> $DIR/regex.rs:70:48
|
LL | let trivial_eq_builder = RegexBuilder::new("^foobar$");
| ^^^^^^^^^^
@@ -122,7 +124,7 @@ LL | let trivial_eq_builder = RegexBuilder::new("^foobar$");
= help: consider using `==` on `str`s
error: trivial regex
- --> $DIR/regex.rs:62:42
+ --> $DIR/regex.rs:73:42
|
LL | let trivial_starts_with = Regex::new("^foobar");
| ^^^^^^^^^
@@ -130,7 +132,7 @@ LL | let trivial_starts_with = Regex::new("^foobar");
= help: consider using `str::starts_with`
error: trivial regex
- --> $DIR/regex.rs:64:40
+ --> $DIR/regex.rs:76:40
|
LL | let trivial_ends_with = Regex::new("foobar$");
| ^^^^^^^^^
@@ -138,7 +140,7 @@ LL | let trivial_ends_with = Regex::new("foobar$");
= help: consider using `str::ends_with`
error: trivial regex
- --> $DIR/regex.rs:66:39
+ --> $DIR/regex.rs:79:39
|
LL | let trivial_contains = Regex::new("foobar");
| ^^^^^^^^
@@ -146,7 +148,7 @@ LL | let trivial_contains = Regex::new("foobar");
= help: consider using `str::contains`
error: trivial regex
- --> $DIR/regex.rs:68:39
+ --> $DIR/regex.rs:82:39
|
LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX);
| ^^^^^^^^^^^^^^^^
@@ -154,15 +156,15 @@ LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX);
= help: consider using `str::contains`
error: trivial regex
- --> $DIR/regex.rs:70:40
+ --> $DIR/regex.rs:85:40
|
-LL | let trivial_backslash = Regex::new("a//.b");
+LL | let trivial_backslash = Regex::new("a\\.b");
| ^^^^^^^
|
= help: consider using `str::contains`
error: trivial regex
- --> $DIR/regex.rs:73:36
+ --> $DIR/regex.rs:89:36
|
LL | let trivial_empty = Regex::new("");
| ^^
@@ -170,7 +172,7 @@ LL | let trivial_empty = Regex::new("");
= help: the regex is unlikely to be useful as it is
error: trivial regex
- --> $DIR/regex.rs:75:36
+ --> $DIR/regex.rs:92:36
|
LL | let trivial_empty = Regex::new("^");
| ^^^
@@ -178,7 +180,7 @@ LL | let trivial_empty = Regex::new("^");
= help: the regex is unlikely to be useful as it is
error: trivial regex
- --> $DIR/regex.rs:77:36
+ --> $DIR/regex.rs:95:36
|
LL | let trivial_empty = Regex::new("^$");
| ^^^^
@@ -186,7 +188,7 @@ LL | let trivial_empty = Regex::new("^$");
= help: consider using `str::is_empty`
error: trivial regex
- --> $DIR/regex.rs:79:44
+ --> $DIR/regex.rs:98:44
|
LL | let binary_trivial_empty = BRegex::new("^$");
| ^^^^
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index e78b9e5c9..4df9be2c2 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -2,8 +2,6 @@
// Use that command to update this file and do not edit by hand.
// Manual edits will be overwritten.
-//@run-rustfix
-
#![allow(clippy::almost_complete_range)]
#![allow(clippy::disallowed_names)]
#![allow(clippy::blocks_in_if_conditions)]
@@ -16,6 +14,8 @@
#![allow(clippy::mixed_read_write_in_expression)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
+#![allow(clippy::non_canonical_clone_impl)]
+#![allow(clippy::non_canonical_partial_ord_impl)]
#![allow(clippy::arithmetic_side_effects)]
#![allow(clippy::overly_complex_bool_expr)]
#![allow(clippy::new_without_default)]
@@ -35,10 +35,10 @@
#![allow(drop_bounds)]
#![allow(dropping_copy_types)]
#![allow(dropping_references)]
+#![allow(useless_ptr_null_checks)]
#![allow(for_loops_over_fallibles)]
#![allow(forgetting_copy_types)]
#![allow(forgetting_references)]
-#![allow(useless_ptr_null_checks)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
@@ -64,6 +64,8 @@
#![warn(clippy::mixed_read_write_in_expression)]
#![warn(clippy::useless_conversion)]
#![warn(clippy::match_result_ok)]
+#![warn(clippy::non_canonical_clone_impl)]
+#![warn(clippy::non_canonical_partial_ord_impl)]
#![warn(clippy::arithmetic_side_effects)]
#![warn(clippy::overly_complex_bool_expr)]
#![warn(clippy::new_without_default)]
@@ -87,12 +89,12 @@
#![warn(drop_bounds)]
#![warn(dropping_copy_types)]
#![warn(dropping_references)]
+#![warn(useless_ptr_null_checks)]
#![warn(for_loops_over_fallibles)]
#![warn(for_loops_over_fallibles)]
#![warn(for_loops_over_fallibles)]
#![warn(forgetting_copy_types)]
#![warn(forgetting_references)]
-#![warn(useless_ptr_null_checks)]
#![warn(array_into_iter)]
#![warn(invalid_atomic_ordering)]
#![warn(invalid_value)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 2e6ef60cb..940e60068 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -2,8 +2,6 @@
// Use that command to update this file and do not edit by hand.
// Manual edits will be overwritten.
-//@run-rustfix
-
#![allow(clippy::almost_complete_range)]
#![allow(clippy::disallowed_names)]
#![allow(clippy::blocks_in_if_conditions)]
@@ -16,6 +14,8 @@
#![allow(clippy::mixed_read_write_in_expression)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
+#![allow(clippy::non_canonical_clone_impl)]
+#![allow(clippy::non_canonical_partial_ord_impl)]
#![allow(clippy::arithmetic_side_effects)]
#![allow(clippy::overly_complex_bool_expr)]
#![allow(clippy::new_without_default)]
@@ -35,10 +35,10 @@
#![allow(drop_bounds)]
#![allow(dropping_copy_types)]
#![allow(dropping_references)]
+#![allow(useless_ptr_null_checks)]
#![allow(for_loops_over_fallibles)]
#![allow(forgetting_copy_types)]
#![allow(forgetting_references)]
-#![allow(useless_ptr_null_checks)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
@@ -64,6 +64,8 @@
#![warn(clippy::eval_order_dependence)]
#![warn(clippy::identity_conversion)]
#![warn(clippy::if_let_some_result)]
+#![warn(clippy::incorrect_clone_impl_on_copy_type)]
+#![warn(clippy::incorrect_partial_ord_impl_on_ord_type)]
#![warn(clippy::integer_arithmetic)]
#![warn(clippy::logic_bug)]
#![warn(clippy::new_without_default_derive)]
@@ -87,12 +89,12 @@
#![warn(clippy::drop_bounds)]
#![warn(clippy::drop_copy)]
#![warn(clippy::drop_ref)]
+#![warn(clippy::fn_null_check)]
#![warn(clippy::for_loop_over_option)]
#![warn(clippy::for_loop_over_result)]
#![warn(clippy::for_loops_over_fallibles)]
#![warn(clippy::forget_copy)]
#![warn(clippy::forget_ref)]
-#![warn(clippy::fn_null_check)]
#![warn(clippy::into_iter_on_array)]
#![warn(clippy::invalid_atomic_ordering)]
#![warn(clippy::invalid_ref)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 57e991e56..30824e154 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -5,6 +5,7 @@ LL | #![warn(clippy::almost_complete_letter_range)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
|
= note: `-D renamed-and-removed-lints` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
--> $DIR/rename.rs:55:9
@@ -78,251 +79,263 @@ error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_resu
LL | #![warn(clippy::if_let_some_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
-error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
+error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl`
--> $DIR/rename.rs:67:9
|
+LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl`
+
+error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl`
+ --> $DIR/rename.rs:68:9
+ |
+LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl`
+
+error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
+ --> $DIR/rename.rs:69:9
+ |
LL | #![warn(clippy::integer_arithmetic)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`
error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
- --> $DIR/rename.rs:68:9
+ --> $DIR/rename.rs:70:9
|
LL | #![warn(clippy::logic_bug)]
| ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
- --> $DIR/rename.rs:69:9
+ --> $DIR/rename.rs:71:9
|
LL | #![warn(clippy::new_without_default_derive)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
- --> $DIR/rename.rs:70:9
+ --> $DIR/rename.rs:72:9
|
LL | #![warn(clippy::option_and_then_some)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
- --> $DIR/rename.rs:71:9
+ --> $DIR/rename.rs:73:9
|
LL | #![warn(clippy::option_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
- --> $DIR/rename.rs:72:9
+ --> $DIR/rename.rs:74:9
|
LL | #![warn(clippy::option_map_unwrap_or)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
- --> $DIR/rename.rs:73:9
+ --> $DIR/rename.rs:75:9
|
LL | #![warn(clippy::option_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
- --> $DIR/rename.rs:74:9
+ --> $DIR/rename.rs:76:9
|
LL | #![warn(clippy::option_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
- --> $DIR/rename.rs:75:9
+ --> $DIR/rename.rs:77:9
|
LL | #![warn(clippy::ref_in_deref)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
- --> $DIR/rename.rs:76:9
+ --> $DIR/rename.rs:78:9
|
LL | #![warn(clippy::result_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
- --> $DIR/rename.rs:77:9
+ --> $DIR/rename.rs:79:9
|
LL | #![warn(clippy::result_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
- --> $DIR/rename.rs:78:9
+ --> $DIR/rename.rs:80:9
|
LL | #![warn(clippy::result_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
- --> $DIR/rename.rs:79:9
+ --> $DIR/rename.rs:81:9
|
LL | #![warn(clippy::single_char_push_str)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
- --> $DIR/rename.rs:80:9
+ --> $DIR/rename.rs:82:9
|
LL | #![warn(clippy::stutter)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
- --> $DIR/rename.rs:81:9
+ --> $DIR/rename.rs:83:9
|
LL | #![warn(clippy::to_string_in_display)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default`
- --> $DIR/rename.rs:82:9
+ --> $DIR/rename.rs:84:9
|
LL | #![warn(clippy::unwrap_or_else_default)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default`
error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
- --> $DIR/rename.rs:83:9
+ --> $DIR/rename.rs:85:9
|
LL | #![warn(clippy::zero_width_space)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting`
- --> $DIR/rename.rs:84:9
+ --> $DIR/rename.rs:86:9
|
LL | #![warn(clippy::cast_ref_to_mut)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting`
error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
- --> $DIR/rename.rs:85:9
+ --> $DIR/rename.rs:87:9
|
LL | #![warn(clippy::clone_double_ref)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`
- --> $DIR/rename.rs:86:9
+ --> $DIR/rename.rs:88:9
|
LL | #![warn(clippy::cmp_nan)]
| ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
- --> $DIR/rename.rs:87:9
+ --> $DIR/rename.rs:89:9
|
LL | #![warn(clippy::drop_bounds)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
- --> $DIR/rename.rs:88:9
+ --> $DIR/rename.rs:90:9
|
LL | #![warn(clippy::drop_copy)]
| ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
error: lint `clippy::drop_ref` has been renamed to `dropping_references`
- --> $DIR/rename.rs:89:9
+ --> $DIR/rename.rs:91:9
|
LL | #![warn(clippy::drop_ref)]
| ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
+error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`
+ --> $DIR/rename.rs:92:9
+ |
+LL | #![warn(clippy::fn_null_check)]
+ | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks`
+
error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
- --> $DIR/rename.rs:90:9
+ --> $DIR/rename.rs:93:9
|
LL | #![warn(clippy::for_loop_over_option)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
- --> $DIR/rename.rs:91:9
+ --> $DIR/rename.rs:94:9
|
LL | #![warn(clippy::for_loop_over_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
- --> $DIR/rename.rs:92:9
+ --> $DIR/rename.rs:95:9
|
LL | #![warn(clippy::for_loops_over_fallibles)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
- --> $DIR/rename.rs:93:9
+ --> $DIR/rename.rs:96:9
|
LL | #![warn(clippy::forget_copy)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
- --> $DIR/rename.rs:94:9
+ --> $DIR/rename.rs:97:9
|
LL | #![warn(clippy::forget_ref)]
| ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
-error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`
- --> $DIR/rename.rs:95:9
- |
-LL | #![warn(clippy::fn_null_check)]
- | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks`
-
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
- --> $DIR/rename.rs:96:9
+ --> $DIR/rename.rs:98:9
|
LL | #![warn(clippy::into_iter_on_array)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
- --> $DIR/rename.rs:97:9
+ --> $DIR/rename.rs:99:9
|
LL | #![warn(clippy::invalid_atomic_ordering)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
- --> $DIR/rename.rs:98:9
+ --> $DIR/rename.rs:100:9
|
LL | #![warn(clippy::invalid_ref)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`
- --> $DIR/rename.rs:99:9
+ --> $DIR/rename.rs:101:9
|
LL | #![warn(clippy::invalid_utf8_in_unchecked)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
- --> $DIR/rename.rs:100:9
+ --> $DIR/rename.rs:102:9
|
LL | #![warn(clippy::let_underscore_drop)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
- --> $DIR/rename.rs:101:9
+ --> $DIR/rename.rs:103:9
|
LL | #![warn(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
- --> $DIR/rename.rs:102:9
+ --> $DIR/rename.rs:104:9
|
LL | #![warn(clippy::panic_params)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
- --> $DIR/rename.rs:103:9
+ --> $DIR/rename.rs:105:9
|
LL | #![warn(clippy::positional_named_format_parameters)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
- --> $DIR/rename.rs:104:9
+ --> $DIR/rename.rs:106:9
|
LL | #![warn(clippy::temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
- --> $DIR/rename.rs:105:9
+ --> $DIR/rename.rs:107:9
|
LL | #![warn(clippy::undropped_manually_drops)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
- --> $DIR/rename.rs:106:9
+ --> $DIR/rename.rs:108:9
|
LL | #![warn(clippy::unknown_clippy_lints)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
error: lint `clippy::unused_label` has been renamed to `unused_labels`
- --> $DIR/rename.rs:107:9
+ --> $DIR/rename.rs:109:9
|
LL | #![warn(clippy::unused_label)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
-error: aborting due to 54 previous errors
+error: aborting due to 56 previous errors
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
index 0334c1e1a..bc0552157 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
@@ -1,4 +1,2 @@
-//@run-rustfix
-
#[clippy::cognitive_complexity = "1"]
fn main() {}
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
index d350370c2..fdb425363 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
@@ -1,4 +1,2 @@
-//@run-rustfix
-
#[clippy::cyclomatic_complexity = "1"]
fn main() {}
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
index 880467624..636d88fcd 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
@@ -1,5 +1,5 @@
error: usage of deprecated attribute
- --> $DIR/renamed_builtin_attr.rs:3:11
+ --> $DIR/renamed_builtin_attr.rs:1:11
|
LL | #[clippy::cyclomatic_complexity = "1"]
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity`
diff --git a/src/tools/clippy/tests/ui/repeat_once.fixed b/src/tools/clippy/tests/ui/repeat_once.fixed
index c517bfcc6..72e97350a 100644
--- a/src/tools/clippy/tests/ui/repeat_once.fixed
+++ b/src/tools/clippy/tests/ui/repeat_once.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::repeat_once)]
#[allow(unused, clippy::redundant_clone)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/repeat_once.rs b/src/tools/clippy/tests/ui/repeat_once.rs
index 9a30b4741..7557c4d0b 100644
--- a/src/tools/clippy/tests/ui/repeat_once.rs
+++ b/src/tools/clippy/tests/ui/repeat_once.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::repeat_once)]
#[allow(unused, clippy::redundant_clone)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/repeat_once.stderr b/src/tools/clippy/tests/ui/repeat_once.stderr
index 915eea3bf..895729390 100644
--- a/src/tools/clippy/tests/ui/repeat_once.stderr
+++ b/src/tools/clippy/tests/ui/repeat_once.stderr
@@ -1,37 +1,38 @@
error: calling `repeat(1)` on slice
- --> $DIR/repeat_once.rs:10:13
+ --> $DIR/repeat_once.rs:9:13
|
LL | let a = [1; 5].repeat(1);
| ^^^^^^^^^^^^^^^^ help: consider using `.to_vec()` instead: `[1; 5].to_vec()`
|
= note: `-D clippy::repeat-once` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::repeat_once)]`
error: calling `repeat(1)` on slice
- --> $DIR/repeat_once.rs:11:13
+ --> $DIR/repeat_once.rs:10:13
|
LL | let b = slice.repeat(1);
| ^^^^^^^^^^^^^^^ help: consider using `.to_vec()` instead: `slice.to_vec()`
error: calling `repeat(1)` on str
- --> $DIR/repeat_once.rs:12:13
+ --> $DIR/repeat_once.rs:11:13
|
LL | let c = "hello".repeat(N);
| ^^^^^^^^^^^^^^^^^ help: consider using `.to_string()` instead: `"hello".to_string()`
error: calling `repeat(1)` on str
- --> $DIR/repeat_once.rs:13:13
+ --> $DIR/repeat_once.rs:12:13
|
LL | let d = "hi".repeat(1);
| ^^^^^^^^^^^^^^ help: consider using `.to_string()` instead: `"hi".to_string()`
error: calling `repeat(1)` on str
- --> $DIR/repeat_once.rs:14:13
+ --> $DIR/repeat_once.rs:13:13
|
LL | let e = s.repeat(1);
| ^^^^^^^^^^^ help: consider using `.to_string()` instead: `s.to_string()`
error: calling `repeat(1)` on a string literal
- --> $DIR/repeat_once.rs:15:13
+ --> $DIR/repeat_once.rs:14:13
|
LL | let f = string.repeat(1);
| ^^^^^^^^^^^^^^^^ help: consider using `.clone()` instead: `string.clone()`
diff --git a/src/tools/clippy/tests/ui/repl_uninit.rs b/src/tools/clippy/tests/ui/repl_uninit.rs
index 6c7e2b854..01bdf79e6 100644
--- a/src/tools/clippy/tests/ui/repl_uninit.rs
+++ b/src/tools/clippy/tests/ui/repl_uninit.rs
@@ -1,6 +1,6 @@
#![allow(deprecated, invalid_value, clippy::uninit_assumed_init)]
#![warn(clippy::mem_replace_with_uninit)]
-
+//@no-rustfix
use std::mem;
fn might_panic<X>(x: X) -> X {
@@ -13,18 +13,22 @@ fn main() {
// the following is UB if `might_panic` panics
unsafe {
let taken_v = mem::replace(&mut v, mem::uninitialized());
+ //~^ ERROR: replacing with `mem::uninitialized()`
+ //~| NOTE: `-D clippy::mem-replace-with-uninit` implied by `-D warnings`
let new_v = might_panic(taken_v);
std::mem::forget(mem::replace(&mut v, new_v));
}
unsafe {
let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init());
+ //~^ ERROR: replacing with `mem::MaybeUninit::uninit().assume_init()`
let new_v = might_panic(taken_v);
std::mem::forget(mem::replace(&mut v, new_v));
}
unsafe {
let taken_v = mem::replace(&mut v, mem::zeroed());
+ //~^ ERROR: replacing with `mem::zeroed()`
let new_v = might_panic(taken_v);
std::mem::forget(mem::replace(&mut v, new_v));
}
@@ -37,5 +41,6 @@ fn main() {
// this is still not OK, because uninit
let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) };
+ //~^ ERROR: replacing with `mem::uninitialized()`
*uref = taken_u + 1;
}
diff --git a/src/tools/clippy/tests/ui/repl_uninit.stderr b/src/tools/clippy/tests/ui/repl_uninit.stderr
index 09468eeae..c82f29adb 100644
--- a/src/tools/clippy/tests/ui/repl_uninit.stderr
+++ b/src/tools/clippy/tests/ui/repl_uninit.stderr
@@ -5,15 +5,16 @@ LL | let taken_v = mem::replace(&mut v, mem::uninitialized());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)`
|
= note: `-D clippy::mem-replace-with-uninit` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_uninit)]`
error: replacing with `mem::MaybeUninit::uninit().assume_init()`
- --> $DIR/repl_uninit.rs:21:23
+ --> $DIR/repl_uninit.rs:23:23
|
LL | let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)`
error: replacing with `mem::zeroed()`
- --> $DIR/repl_uninit.rs:27:23
+ --> $DIR/repl_uninit.rs:30:23
|
LL | let taken_v = mem::replace(&mut v, mem::zeroed());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -21,7 +22,7 @@ LL | let taken_v = mem::replace(&mut v, mem::zeroed());
= help: consider using a default value or the `take_mut` crate instead
error: replacing with `mem::uninitialized()`
- --> $DIR/repl_uninit.rs:39:28
+ --> $DIR/repl_uninit.rs:43:28
|
LL | let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(uref)`
diff --git a/src/tools/clippy/tests/ui/reserve_after_initialization.fixed b/src/tools/clippy/tests/ui/reserve_after_initialization.fixed
new file mode 100644
index 000000000..067527784
--- /dev/null
+++ b/src/tools/clippy/tests/ui/reserve_after_initialization.fixed
@@ -0,0 +1,48 @@
+//@aux-build:proc_macros.rs
+#![warn(clippy::reserve_after_initialization)]
+#![no_main]
+
+extern crate proc_macros;
+use proc_macros::{external, with_span};
+
+// Should lint
+fn standard() {
+ let mut v1: Vec<usize> = Vec::with_capacity(10);
+}
+
+// Should lint
+fn capacity_as_expr() {
+ let capacity = 10;
+ let mut v2: Vec<usize> = Vec::with_capacity(capacity);
+}
+
+// Shouldn't lint
+fn vec_init_with_argument() {
+ let mut v3 = vec![1];
+ v3.reserve(10);
+}
+
+// Shouldn't lint
+fn called_with_capacity() {
+ let _v4: Vec<usize> = Vec::with_capacity(10);
+}
+
+// Should lint
+fn assign_expression() {
+ let mut v5: Vec<usize> = Vec::new();
+ v5 = Vec::with_capacity(10);
+}
+
+fn in_macros() {
+ external! {
+ let mut v: Vec<usize> = vec![];
+ v.reserve(10);
+ }
+
+ with_span! {
+ span
+
+ let mut v: Vec<usize> = vec![];
+ v.reserve(10);
+ }
+}
diff --git a/src/tools/clippy/tests/ui/reserve_after_initialization.rs b/src/tools/clippy/tests/ui/reserve_after_initialization.rs
new file mode 100644
index 000000000..b57a8e162
--- /dev/null
+++ b/src/tools/clippy/tests/ui/reserve_after_initialization.rs
@@ -0,0 +1,51 @@
+//@aux-build:proc_macros.rs
+#![warn(clippy::reserve_after_initialization)]
+#![no_main]
+
+extern crate proc_macros;
+use proc_macros::{external, with_span};
+
+// Should lint
+fn standard() {
+ let mut v1: Vec<usize> = vec![];
+ v1.reserve(10);
+}
+
+// Should lint
+fn capacity_as_expr() {
+ let capacity = 10;
+ let mut v2: Vec<usize> = vec![];
+ v2.reserve(capacity);
+}
+
+// Shouldn't lint
+fn vec_init_with_argument() {
+ let mut v3 = vec![1];
+ v3.reserve(10);
+}
+
+// Shouldn't lint
+fn called_with_capacity() {
+ let _v4: Vec<usize> = Vec::with_capacity(10);
+}
+
+// Should lint
+fn assign_expression() {
+ let mut v5: Vec<usize> = Vec::new();
+ v5 = Vec::new();
+ v5.reserve(10);
+}
+
+fn in_macros() {
+ external! {
+ let mut v: Vec<usize> = vec![];
+ v.reserve(10);
+ }
+
+ with_span! {
+ span
+
+ let mut v: Vec<usize> = vec![];
+ v.reserve(10);
+ }
+}
diff --git a/src/tools/clippy/tests/ui/reserve_after_initialization.stderr b/src/tools/clippy/tests/ui/reserve_after_initialization.stderr
new file mode 100644
index 000000000..a91033890
--- /dev/null
+++ b/src/tools/clippy/tests/ui/reserve_after_initialization.stderr
@@ -0,0 +1,26 @@
+error: call to `reserve` immediately after creation
+ --> $DIR/reserve_after_initialization.rs:10:5
+ |
+LL | / let mut v1: Vec<usize> = vec![];
+LL | | v1.reserve(10);
+ | |___________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `let mut v1: Vec<usize> = Vec::with_capacity(10);`
+ |
+ = note: `-D clippy::reserve-after-initialization` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::reserve_after_initialization)]`
+
+error: call to `reserve` immediately after creation
+ --> $DIR/reserve_after_initialization.rs:17:5
+ |
+LL | / let mut v2: Vec<usize> = vec![];
+LL | | v2.reserve(capacity);
+ | |_________________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `let mut v2: Vec<usize> = Vec::with_capacity(capacity);`
+
+error: call to `reserve` immediately after creation
+ --> $DIR/reserve_after_initialization.rs:35:5
+ |
+LL | / v5 = Vec::new();
+LL | | v5.reserve(10);
+ | |___________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `v5 = Vec::with_capacity(10);`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs
index 086331af6..e25609f75 100644
--- a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs
+++ b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs
@@ -20,13 +20,16 @@ fn main() {
match a_struct {
A { a: 5, b: 42, c: "", .. } => {}, // Lint
- A { a: 0, b: 0, c: "", .. } => {}, // Lint
+ //~^ ERROR: unnecessary use of `..` pattern in struct binding. All fields were alr
+ A { a: 0, b: 0, c: "", .. } => {}, // Lint
+ //~^ ERROR: unnecessary use of `..` pattern in struct binding. All fields were alr
_ => {},
}
match a_struct {
A { a: 5, b: 42, .. } => {},
A { a: 0, b: 0, c: "", .. } => {}, // Lint
+ //~^ ERROR: unnecessary use of `..` pattern in struct binding. All fields were alr
_ => {},
}
diff --git a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr
index e15633fb1..2c221b4db 100644
--- a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr
+++ b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr
@@ -6,17 +6,18 @@ LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint
|
= help: consider removing `..` from this binding
= note: `-D clippy::rest-pat-in-fully-bound-structs` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::rest_pat_in_fully_bound_structs)]`
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
- --> $DIR/rest_pat_in_fully_bound_structs.rs:23:9
+ --> $DIR/rest_pat_in_fully_bound_structs.rs:24:9
|
-LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
+LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider removing `..` from this binding
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
- --> $DIR/rest_pat_in_fully_bound_structs.rs:29:9
+ --> $DIR/rest_pat_in_fully_bound_structs.rs:31:9
|
LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/result_large_err.rs b/src/tools/clippy/tests/ui/result_large_err.rs
index 1c12cebfd..b25348bf9 100644
--- a/src/tools/clippy/tests/ui/result_large_err.rs
+++ b/src/tools/clippy/tests/ui/result_large_err.rs
@@ -1,3 +1,5 @@
+//@ignore-32bit
+
#![warn(clippy::result_large_err)]
#![allow(clippy::large_enum_variant)]
@@ -6,6 +8,7 @@ pub fn small_err() -> Result<(), u128> {
}
pub fn large_err() -> Result<(), [u8; 512]> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
@@ -17,16 +20,19 @@ pub struct FullyDefinedLargeError {
impl FullyDefinedLargeError {
pub fn ret() -> Result<(), Self> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
}
pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
type Fdlr<T> = std::result::Result<T, FullyDefinedLargeError>;
pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(x)
}
@@ -35,6 +41,7 @@ pub fn param_small_error<R>() -> Result<(), (R, u128)> {
}
pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
@@ -46,6 +53,7 @@ pub enum LargeErrorVariants<T> {
impl LargeErrorVariants<()> {
pub fn large_enum_error() -> Result<(), Self> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
}
@@ -58,12 +66,14 @@ enum MultipleLargeVariants {
impl MultipleLargeVariants {
fn large_enum_error() -> Result<(), Self> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
}
trait TraitForcesLargeError {
fn large_error() -> Result<(), [u8; 512]> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
}
@@ -83,6 +93,7 @@ pub union FullyDefinedUnionError {
}
pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
@@ -92,6 +103,7 @@ pub union UnionError<T: Copy> {
}
pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
@@ -101,10 +113,12 @@ pub struct ArrayError<T, U> {
}
pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
+ //~^ ERROR: the `Err`-variant returned from this function is very large
Ok(())
}
diff --git a/src/tools/clippy/tests/ui/result_large_err.stderr b/src/tools/clippy/tests/ui/result_large_err.stderr
index c386edfd2..6602f396a 100644
--- a/src/tools/clippy/tests/ui/result_large_err.stderr
+++ b/src/tools/clippy/tests/ui/result_large_err.stderr
@@ -1,14 +1,15 @@
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:8:23
+ --> $DIR/result_large_err.rs:10:23
|
LL | pub fn large_err() -> Result<(), [u8; 512]> {
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
|
= help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
= note: `-D clippy::result-large-err` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_large_err)]`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:19:21
+ --> $DIR/result_large_err.rs:22:21
|
LL | pub fn ret() -> Result<(), Self> {
| ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
@@ -16,7 +17,7 @@ LL | pub fn ret() -> Result<(), Self> {
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:24:26
+ --> $DIR/result_large_err.rs:28:26
|
LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes
@@ -24,7 +25,7 @@ LL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> {
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:29:45
+ --> $DIR/result_large_err.rs:34:45
|
LL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
| ^^^^^^^ the `Err`-variant is at least 240 bytes
@@ -32,7 +33,7 @@ LL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {
= help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:37:34
+ --> $DIR/result_large_err.rs:43:34
|
LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 256 bytes
@@ -40,7 +41,7 @@ LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeErro
= help: try reducing the size of `(u128, R, FullyDefinedLargeError)`, for example by boxing large elements or replacing it with `Box<(u128, R, FullyDefinedLargeError)>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:48:34
+ --> $DIR/result_large_err.rs:55:34
|
LL | _Omg([u8; 512]),
| --------------- the largest variant contains at least 512 bytes
@@ -51,7 +52,7 @@ LL | pub fn large_enum_error() -> Result<(), Self> {
= help: try reducing the size of `LargeErrorVariants<()>`, for example by boxing large elements or replacing it with `Box<LargeErrorVariants<()>>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:60:30
+ --> $DIR/result_large_err.rs:68:30
|
LL | _Biggest([u8; 1024]),
| -------------------- the largest variant contains at least 1024 bytes
@@ -64,7 +65,7 @@ LL | fn large_enum_error() -> Result<(), Self> {
= help: try reducing the size of `MultipleLargeVariants`, for example by boxing large elements or replacing it with `Box<MultipleLargeVariants>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:66:25
+ --> $DIR/result_large_err.rs:75:25
|
LL | fn large_error() -> Result<(), [u8; 512]> {
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
@@ -72,7 +73,7 @@ LL | fn large_error() -> Result<(), [u8; 512]> {
= help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:85:29
+ --> $DIR/result_large_err.rs:95:29
|
LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
@@ -80,7 +81,7 @@ LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
= help: try reducing the size of `FullyDefinedUnionError`, for example by boxing large elements or replacing it with `Box<FullyDefinedUnionError>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:94:40
+ --> $DIR/result_large_err.rs:105:40
|
LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
@@ -88,7 +89,7 @@ LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
= help: try reducing the size of `UnionError<T>`, for example by boxing large elements or replacing it with `Box<UnionError<T>>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:103:34
+ --> $DIR/result_large_err.rs:115:34
|
LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
@@ -96,7 +97,7 @@ LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
= help: try reducing the size of `ArrayError<i32, U>`, for example by boxing large elements or replacing it with `Box<ArrayError<i32, U>>`
error: the `Err`-variant returned from this function is very large
- --> $DIR/result_large_err.rs:107:31
+ --> $DIR/result_large_err.rs:120:31
|
LL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.fixed b/src/tools/clippy/tests/ui/result_map_or_into_option.fixed
index 6850eeb7a..fb2db6cf5 100644
--- a/src/tools/clippy/tests/ui/result_map_or_into_option.fixed
+++ b/src/tools/clippy/tests/ui/result_map_or_into_option.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::result_map_or_into_option)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.rs b/src/tools/clippy/tests/ui/result_map_or_into_option.rs
index 8e1518144..06779a699 100644
--- a/src/tools/clippy/tests/ui/result_map_or_into_option.rs
+++ b/src/tools/clippy/tests/ui/result_map_or_into_option.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::result_map_or_into_option)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.stderr b/src/tools/clippy/tests/ui/result_map_or_into_option.stderr
index febf32147..9396ea4c0 100644
--- a/src/tools/clippy/tests/ui/result_map_or_into_option.stderr
+++ b/src/tools/clippy/tests/ui/result_map_or_into_option.stderr
@@ -1,10 +1,11 @@
error: called `map_or(None, Some)` on a `Result` value. This can be done more directly by calling `ok()` instead
- --> $DIR/result_map_or_into_option.rs:7:13
+ --> $DIR/result_map_or_into_option.rs:5:13
|
LL | let _ = opt.map_or(None, Some);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()`
|
= note: `-D clippy::result-map-or-into-option` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
index 0583d2927..3890f916b 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::result_map_unit_fn)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
index 7ad3bdd04..c3f5aca7b 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::result_map_unit_fn)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
index ad941fa8b..42ee273c2 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
@@ -1,5 +1,5 @@
error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:35:5
+ --> $DIR/result_map_unit_fn_fixable.rs:34:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
@@ -7,9 +7,10 @@ LL | x.field.map(do_nothing);
| help: try: `if let Ok(x_field) = x.field { do_nothing(x_field) }`
|
= note: `-D clippy::result-map-unit-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_map_unit_fn)]`
error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:37:5
+ --> $DIR/result_map_unit_fn_fixable.rs:36:5
|
LL | x.field.map(do_nothing);
| ^^^^^^^^^^^^^^^^^^^^^^^-
@@ -17,7 +18,7 @@ LL | x.field.map(do_nothing);
| help: try: `if let Ok(x_field) = x.field { do_nothing(x_field) }`
error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:39:5
+ --> $DIR/result_map_unit_fn_fixable.rs:38:5
|
LL | x.field.map(diverge);
| ^^^^^^^^^^^^^^^^^^^^-
@@ -25,7 +26,7 @@ LL | x.field.map(diverge);
| help: try: `if let Ok(x_field) = x.field { diverge(x_field) }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:45:5
+ --> $DIR/result_map_unit_fn_fixable.rs:44:5
|
LL | x.field.map(|value| x.do_result_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -33,7 +34,7 @@ LL | x.field.map(|value| x.do_result_nothing(value + captured));
| help: try: `if let Ok(value) = x.field { x.do_result_nothing(value + captured) }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:47:5
+ --> $DIR/result_map_unit_fn_fixable.rs:46:5
|
LL | x.field.map(|value| { x.do_result_plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -41,7 +42,7 @@ LL | x.field.map(|value| { x.do_result_plus_one(value + captured); });
| help: try: `if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:50:5
+ --> $DIR/result_map_unit_fn_fixable.rs:49:5
|
LL | x.field.map(|value| do_nothing(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -49,7 +50,7 @@ LL | x.field.map(|value| do_nothing(value + captured));
| help: try: `if let Ok(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:52:5
+ --> $DIR/result_map_unit_fn_fixable.rs:51:5
|
LL | x.field.map(|value| { do_nothing(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -57,7 +58,7 @@ LL | x.field.map(|value| { do_nothing(value + captured) });
| help: try: `if let Ok(value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:54:5
+ --> $DIR/result_map_unit_fn_fixable.rs:53:5
|
LL | x.field.map(|value| { do_nothing(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -65,7 +66,7 @@ LL | x.field.map(|value| { do_nothing(value + captured); });
| help: try: `if let Ok(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:56:5
+ --> $DIR/result_map_unit_fn_fixable.rs:55:5
|
LL | x.field.map(|value| { { do_nothing(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -73,7 +74,7 @@ LL | x.field.map(|value| { { do_nothing(value + captured); } });
| help: try: `if let Ok(value) = x.field { do_nothing(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:59:5
+ --> $DIR/result_map_unit_fn_fixable.rs:58:5
|
LL | x.field.map(|value| diverge(value + captured));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -81,7 +82,7 @@ LL | x.field.map(|value| diverge(value + captured));
| help: try: `if let Ok(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:61:5
+ --> $DIR/result_map_unit_fn_fixable.rs:60:5
|
LL | x.field.map(|value| { diverge(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -89,7 +90,7 @@ LL | x.field.map(|value| { diverge(value + captured) });
| help: try: `if let Ok(value) = x.field { diverge(value + captured) }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:63:5
+ --> $DIR/result_map_unit_fn_fixable.rs:62:5
|
LL | x.field.map(|value| { diverge(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -97,7 +98,7 @@ LL | x.field.map(|value| { diverge(value + captured); });
| help: try: `if let Ok(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:65:5
+ --> $DIR/result_map_unit_fn_fixable.rs:64:5
|
LL | x.field.map(|value| { { diverge(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -105,7 +106,7 @@ LL | x.field.map(|value| { { diverge(value + captured); } });
| help: try: `if let Ok(value) = x.field { diverge(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:70:5
+ --> $DIR/result_map_unit_fn_fixable.rs:69:5
|
LL | x.field.map(|value| { let y = plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -113,7 +114,7 @@ LL | x.field.map(|value| { let y = plus_one(value + captured); });
| help: try: `if let Ok(value) = x.field { let y = plus_one(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:72:5
+ --> $DIR/result_map_unit_fn_fixable.rs:71:5
|
LL | x.field.map(|value| { plus_one(value + captured); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -121,7 +122,7 @@ LL | x.field.map(|value| { plus_one(value + captured); });
| help: try: `if let Ok(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:74:5
+ --> $DIR/result_map_unit_fn_fixable.rs:73:5
|
LL | x.field.map(|value| { { plus_one(value + captured); } });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -129,7 +130,7 @@ LL | x.field.map(|value| { { plus_one(value + captured); } });
| help: try: `if let Ok(value) = x.field { plus_one(value + captured); }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:77:5
+ --> $DIR/result_map_unit_fn_fixable.rs:76:5
|
LL | x.field.map(|ref value| { do_nothing(value + captured) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -137,7 +138,7 @@ LL | x.field.map(|ref value| { do_nothing(value + captured) });
| help: try: `if let Ok(ref value) = x.field { do_nothing(value + captured) }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_fixable.rs:79:5
+ --> $DIR/result_map_unit_fn_fixable.rs:78:5
|
LL | x.field.map(|value| println!("{:?}", value));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
index b197c609d..62798b6d3 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
@@ -1,7 +1,7 @@
#![warn(clippy::result_map_unit_fn)]
#![feature(never_type)]
-#![allow(unused)]
-
+#![allow(unused, clippy::unnecessary_map_on_constructor)]
+//@no-rustfix
struct HasResult {
field: Result<usize, usize>,
}
@@ -21,26 +21,33 @@ fn result_map_unit_fn() {
let x = HasResult { field: Ok(10) };
x.field.map(|value| { do_nothing(value); do_nothing(value) });
+ //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t
+ //~| NOTE: `-D clippy::result-map-unit-fn` implied by `-D warnings`
x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
+ //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t
// Suggestion for the let block should be `{ ... }` as it's too difficult to build a
// proper suggestion for these cases
x.field.map(|value| {
+ //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t
do_nothing(value);
do_nothing(value)
});
x.field.map(|value| { do_nothing(value); do_nothing(value); });
+ //~^ ERROR: called `map(f)` on an `Result` value where `f` is a closure that returns t
// The following should suggest `if let Ok(_X) ...` as it's difficult to generate a proper let variable name for them
let res: Result<!, usize> = Ok(42).map(diverge);
"12".parse::<i32>().map(diverge);
+ //~^ ERROR: called `map(f)` on an `Result` value where `f` is a function that returns
let res: Result<(), usize> = Ok(plus_one(1)).map(do_nothing);
// Should suggest `if let Ok(_y) ...` to not override the existing foo variable
let y: Result<usize, usize> = Ok(42);
y.map(do_nothing);
+ //~^ ERROR: called `map(f)` on an `Result` value where `f` is a function that returns
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
index 75ec1ba80..ccf9bfb94 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
@@ -7,9 +7,10 @@ LL | x.field.map(|value| { do_nothing(value); do_nothing(value) });
| help: try: `if let Ok(value) = x.field { ... }`
|
= note: `-D clippy::result-map-unit-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_map_unit_fn)]`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_unfixable.rs:25:5
+ --> $DIR/result_map_unit_fn_unfixable.rs:27:5
|
LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -17,9 +18,10 @@ LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value)
| help: try: `if let Ok(value) = x.field { ... }`
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_unfixable.rs:29:5
+ --> $DIR/result_map_unit_fn_unfixable.rs:32:5
|
LL | // x.field.map(|value| {
+LL | ||
LL | || do_nothing(value);
LL | || do_nothing(value)
LL | || });
@@ -28,7 +30,7 @@ LL | || });
|
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
- --> $DIR/result_map_unit_fn_unfixable.rs:33:5
+ --> $DIR/result_map_unit_fn_unfixable.rs:37:5
|
LL | x.field.map(|value| { do_nothing(value); do_nothing(value); });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -36,7 +38,7 @@ LL | x.field.map(|value| { do_nothing(value); do_nothing(value); });
| help: try: `if let Ok(value) = x.field { ... }`
error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
- --> $DIR/result_map_unit_fn_unfixable.rs:37:5
+ --> $DIR/result_map_unit_fn_unfixable.rs:42:5
|
LL | "12".parse::<i32>().map(diverge);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
@@ -44,7 +46,7 @@ LL | "12".parse::<i32>().map(diverge);
| help: try: `if let Ok(a) = "12".parse::<i32>() { diverge(a) }`
error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
- --> $DIR/result_map_unit_fn_unfixable.rs:43:5
+ --> $DIR/result_map_unit_fn_unfixable.rs:49:5
|
LL | y.map(do_nothing);
| ^^^^^^^^^^^^^^^^^-
diff --git a/src/tools/clippy/tests/ui/result_unit_error.rs b/src/tools/clippy/tests/ui/result_unit_error.rs
index a4ec80302..f3159f2e9 100644
--- a/src/tools/clippy/tests/ui/result_unit_error.rs
+++ b/src/tools/clippy/tests/ui/result_unit_error.rs
@@ -1,6 +1,7 @@
#![warn(clippy::result_unit_err)]
pub fn returns_unit_error() -> Result<u32, ()> {
+ //~^ ERROR: this returns a `Result<_, ()>`
Err(())
}
@@ -10,8 +11,10 @@ fn private_unit_errors() -> Result<String, ()> {
pub trait HasUnitError {
fn get_that_error(&self) -> Result<bool, ()>;
+ //~^ ERROR: this returns a `Result<_, ()>`
fn get_this_one_too(&self) -> Result<bool, ()> {
+ //~^ ERROR: this returns a `Result<_, ()>`
Err(())
}
}
@@ -30,6 +33,7 @@ pub struct UnitErrorHolder;
impl UnitErrorHolder {
pub fn unit_error(&self) -> Result<usize, ()> {
+ //~^ ERROR: this returns a `Result<_, ()>`
Ok(0)
}
}
@@ -39,6 +43,7 @@ pub mod issue_6546 {
type ResInv<A, B> = Result<B, A>;
pub fn should_lint() -> ResInv<(), usize> {
+ //~^ ERROR: this returns a `Result<_, ()>`
Ok(0)
}
diff --git a/src/tools/clippy/tests/ui/result_unit_error.stderr b/src/tools/clippy/tests/ui/result_unit_error.stderr
index 8393a4bf0..72208f539 100644
--- a/src/tools/clippy/tests/ui/result_unit_error.stderr
+++ b/src/tools/clippy/tests/ui/result_unit_error.stderr
@@ -6,9 +6,10 @@ LL | pub fn returns_unit_error() -> Result<u32, ()> {
|
= help: use a custom `Error` type instead
= note: `-D clippy::result-unit-err` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]`
error: this returns a `Result<_, ()>`
- --> $DIR/result_unit_error.rs:12:5
+ --> $DIR/result_unit_error.rs:13:5
|
LL | fn get_that_error(&self) -> Result<bool, ()>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | fn get_that_error(&self) -> Result<bool, ()>;
= help: use a custom `Error` type instead
error: this returns a `Result<_, ()>`
- --> $DIR/result_unit_error.rs:14:5
+ --> $DIR/result_unit_error.rs:16:5
|
LL | fn get_this_one_too(&self) -> Result<bool, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | fn get_this_one_too(&self) -> Result<bool, ()> {
= help: use a custom `Error` type instead
error: this returns a `Result<_, ()>`
- --> $DIR/result_unit_error.rs:32:5
+ --> $DIR/result_unit_error.rs:35:5
|
LL | pub fn unit_error(&self) -> Result<usize, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | pub fn unit_error(&self) -> Result<usize, ()> {
= help: use a custom `Error` type instead
error: this returns a `Result<_, ()>`
- --> $DIR/result_unit_error.rs:41:5
+ --> $DIR/result_unit_error.rs:45:5
|
LL | pub fn should_lint() -> ResInv<(), usize> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/return_self_not_must_use.rs b/src/tools/clippy/tests/ui/return_self_not_must_use.rs
index 9b33ad6d3..ec6f0feb8 100644
--- a/src/tools/clippy/tests/ui/return_self_not_must_use.rs
+++ b/src/tools/clippy/tests/ui/return_self_not_must_use.rs
@@ -6,6 +6,7 @@ pub struct Bar;
pub trait Whatever {
fn what(&self) -> Self;
+ //~^ ERROR: missing `#[must_use]` attribute on a method returning `Self`
// There should be no warning here! (returns a reference)
fn what2(&self) -> &Self;
}
@@ -16,9 +17,11 @@ impl Bar {
Self
}
pub fn foo(&self) -> Self {
+ //~^ ERROR: missing `#[must_use]` attribute on a method returning `Self`
Self
}
pub fn bar(self) -> Self {
+ //~^ ERROR: missing `#[must_use]` attribute on a method returning `Self`
self
}
// There should be no warning here! (private method)
diff --git a/src/tools/clippy/tests/ui/return_self_not_must_use.stderr b/src/tools/clippy/tests/ui/return_self_not_must_use.stderr
index 34932fe1c..b3e41470d 100644
--- a/src/tools/clippy/tests/ui/return_self_not_must_use.stderr
+++ b/src/tools/clippy/tests/ui/return_self_not_must_use.stderr
@@ -6,11 +6,13 @@ LL | fn what(&self) -> Self;
|
= help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type
= note: `-D clippy::return-self-not-must-use` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::return_self_not_must_use)]`
error: missing `#[must_use]` attribute on a method returning `Self`
- --> $DIR/return_self_not_must_use.rs:18:5
+ --> $DIR/return_self_not_must_use.rs:19:5
|
LL | / pub fn foo(&self) -> Self {
+LL | |
LL | | Self
LL | | }
| |_____^
@@ -18,9 +20,10 @@ LL | | }
= help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type
error: missing `#[must_use]` attribute on a method returning `Self`
- --> $DIR/return_self_not_must_use.rs:21:5
+ --> $DIR/return_self_not_must_use.rs:23:5
|
LL | / pub fn bar(self) -> Self {
+LL | |
LL | | self
LL | | }
| |_____^
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed
index 30dfc9776..c8bf1b350 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::reversed_empty_ranges)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs
index 1837249ea..6733c0964 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::reversed_empty_ranges)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr
index c2495ea95..92fbac8e3 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr
@@ -1,17 +1,18 @@
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_fixable.rs:10:5
+ --> $DIR/reversed_empty_ranges_fixable.rs:9:5
|
LL | (42..=21).for_each(|x| println!("{}", x));
| ^^^^^^^^^
|
= note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`
help: consider using the following if you are attempting to iterate over this range in reverse
|
LL | (21..=42).rev().for_each(|x| println!("{}", x));
| ~~~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_fixable.rs:11:13
+ --> $DIR/reversed_empty_ranges_fixable.rs:10:13
|
LL | let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();
| ^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::<Ve
| ~~~~~~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_fixable.rs:13:14
+ --> $DIR/reversed_empty_ranges_fixable.rs:12:14
|
LL | for _ in -21..=-42 {}
| ^^^^^^^^^
@@ -33,7 +34,7 @@ LL | for _ in (-42..=-21).rev() {}
| ~~~~~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_fixable.rs:14:14
+ --> $DIR/reversed_empty_ranges_fixable.rs:13:14
|
LL | for _ in 42u32..21u32 {}
| ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed
index a74569599..df5f2c441 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::reversed_empty_ranges)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs
index 42f9957df..92481be6c 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::reversed_empty_ranges)]
#![allow(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr
index dfc52e64c..843d6a36d 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr
@@ -1,17 +1,18 @@
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_loops_fixable.rs:8:14
+ --> $DIR/reversed_empty_ranges_loops_fixable.rs:7:14
|
LL | for i in 10..0 {
| ^^^^^
|
= note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`
help: consider using the following if you are attempting to iterate over this range in reverse
|
LL | for i in (0..10).rev() {
| ~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_loops_fixable.rs:12:14
+ --> $DIR/reversed_empty_ranges_loops_fixable.rs:11:14
|
LL | for i in 10..=0 {
| ^^^^^^
@@ -22,7 +23,7 @@ LL | for i in (0..=10).rev() {
| ~~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_loops_fixable.rs:16:14
+ --> $DIR/reversed_empty_ranges_loops_fixable.rs:15:14
|
LL | for i in MAX_LEN..0 {
| ^^^^^^^^^^
@@ -33,7 +34,7 @@ LL | for i in (0..MAX_LEN).rev() {
| ~~~~~~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_loops_fixable.rs:35:14
+ --> $DIR/reversed_empty_ranges_loops_fixable.rs:34:14
|
LL | for i in (10..0).map(|x| x * 2) {
| ^^^^^^^
@@ -44,7 +45,7 @@ LL | for i in (0..10).rev().map(|x| x * 2) {
| ~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_loops_fixable.rs:40:14
+ --> $DIR/reversed_empty_ranges_loops_fixable.rs:39:14
|
LL | for i in 10..5 + 4 {
| ^^^^^^^^^
@@ -55,7 +56,7 @@ LL | for i in (5 + 4..10).rev() {
| ~~~~~~~~~~~~~~~~~
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_loops_fixable.rs:44:14
+ --> $DIR/reversed_empty_ranges_loops_fixable.rs:43:14
|
LL | for i in (5 + 2)..(3 - 1) {
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.rs b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.rs
index 50264ef68..cd1701dd4 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.rs
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.rs
@@ -3,10 +3,13 @@
fn main() {
for i in 5..5 {
+ //~^ ERROR: this range is empty so it will yield no values
+ //~| NOTE: `-D clippy::reversed-empty-ranges` implied by `-D warnings`
println!("{}", i);
}
for i in (5 + 2)..(8 - 1) {
+ //~^ ERROR: this range is empty so it will yield no values
println!("{}", i);
}
}
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.stderr
index 4490ff35f..73165e091 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_unfixable.stderr
@@ -5,9 +5,10 @@ LL | for i in 5..5 {
| ^^^^
|
= note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_loops_unfixable.rs:9:14
+ --> $DIR/reversed_empty_ranges_loops_unfixable.rs:11:14
|
LL | for i in (5 + 2)..(8 - 1) {
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.rs b/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.rs
index 264d3d1e9..16c1121ae 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.rs
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.rs
@@ -6,9 +6,13 @@ const SOME_NUM: usize = 3;
fn main() {
let arr = [1, 2, 3, 4, 5];
let _ = &arr[3usize..=1usize];
+ //~^ ERROR: this range is reversed and using it to index a slice will panic at run-tim
+ //~| NOTE: `-D clippy::reversed-empty-ranges` implied by `-D warnings`
let _ = &arr[SOME_NUM..1];
+ //~^ ERROR: this range is reversed and using it to index a slice will panic at run-tim
for _ in ANSWER..ANSWER {}
+ //~^ ERROR: this range is empty so it will yield no values
// Should not be linted, see issue #5689
let _ = (42 + 10..42 + 10).map(|x| x / 2).find(|&x| x == 21);
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.stderr
index f23d4eb0f..e3dc96dfb 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_unfixable.stderr
@@ -5,15 +5,16 @@ LL | let _ = &arr[3usize..=1usize];
| ^^^^^^^^^^^^^^^
|
= note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`
error: this range is reversed and using it to index a slice will panic at run-time
- --> $DIR/reversed_empty_ranges_unfixable.rs:9:18
+ --> $DIR/reversed_empty_ranges_unfixable.rs:11:18
|
LL | let _ = &arr[SOME_NUM..1];
| ^^^^^^^^^^^
error: this range is empty so it will yield no values
- --> $DIR/reversed_empty_ranges_unfixable.rs:11:14
+ --> $DIR/reversed_empty_ranges_unfixable.rs:14:14
|
LL | for _ in ANSWER..ANSWER {}
| ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/same_item_push.rs b/src/tools/clippy/tests/ui/same_item_push.rs
index af01a8df7..df9c2817f 100644
--- a/src/tools/clippy/tests/ui/same_item_push.rs
+++ b/src/tools/clippy/tests/ui/same_item_push.rs
@@ -21,28 +21,33 @@ fn main() {
let item = 2;
for _ in 5..=20 {
vec.push(item);
+ //~^ ERROR: it looks like the same item is being pushed into this Vec
}
let mut vec: Vec<u8> = Vec::new();
for _ in 0..15 {
let item = 2;
vec.push(item);
+ //~^ ERROR: it looks like the same item is being pushed into this Vec
}
let mut vec: Vec<u8> = Vec::new();
for _ in 0..15 {
vec.push(13);
+ //~^ ERROR: it looks like the same item is being pushed into this Vec
}
let mut vec = Vec::new();
for _ in 0..20 {
vec.push(VALUE);
+ //~^ ERROR: it looks like the same item is being pushed into this Vec
}
let mut vec = Vec::new();
let item = VALUE;
for _ in 0..20 {
vec.push(item);
+ //~^ ERROR: it looks like the same item is being pushed into this Vec
}
// ** non-linted cases **
diff --git a/src/tools/clippy/tests/ui/same_item_push.stderr b/src/tools/clippy/tests/ui/same_item_push.stderr
index 1d1254d9f..f519be463 100644
--- a/src/tools/clippy/tests/ui/same_item_push.stderr
+++ b/src/tools/clippy/tests/ui/same_item_push.stderr
@@ -6,9 +6,10 @@ LL | vec.push(item);
|
= help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
= note: `-D clippy::same-item-push` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::same_item_push)]`
error: it looks like the same item is being pushed into this Vec
- --> $DIR/same_item_push.rs:29:9
+ --> $DIR/same_item_push.rs:30:9
|
LL | vec.push(item);
| ^^^
@@ -16,7 +17,7 @@ LL | vec.push(item);
= help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
error: it looks like the same item is being pushed into this Vec
- --> $DIR/same_item_push.rs:34:9
+ --> $DIR/same_item_push.rs:36:9
|
LL | vec.push(13);
| ^^^
@@ -24,7 +25,7 @@ LL | vec.push(13);
= help: try using vec![13;SIZE] or vec.resize(NEW_SIZE, 13)
error: it looks like the same item is being pushed into this Vec
- --> $DIR/same_item_push.rs:39:9
+ --> $DIR/same_item_push.rs:42:9
|
LL | vec.push(VALUE);
| ^^^
@@ -32,7 +33,7 @@ LL | vec.push(VALUE);
= help: try using vec![VALUE;SIZE] or vec.resize(NEW_SIZE, VALUE)
error: it looks like the same item is being pushed into this Vec
- --> $DIR/same_item_push.rs:45:9
+ --> $DIR/same_item_push.rs:49:9
|
LL | vec.push(item);
| ^^^
diff --git a/src/tools/clippy/tests/ui/same_name_method.rs b/src/tools/clippy/tests/ui/same_name_method.rs
index f31a7e33c..1c166a19b 100644
--- a/src/tools/clippy/tests/ui/same_name_method.rs
+++ b/src/tools/clippy/tests/ui/same_name_method.rs
@@ -19,6 +19,7 @@ mod should_lint {
impl S {
fn foo() {}
+ //~^ ERROR: method's name is the same as an existing method in a trait
}
impl T1 for S {
@@ -33,6 +34,7 @@ mod should_lint {
impl S {
fn clone() {}
+ //~^ ERROR: method's name is the same as an existing method in a trait
}
}
@@ -43,6 +45,7 @@ mod should_lint {
impl<U> S<U> {
fn foo() {}
+ //~^ ERROR: method's name is the same as an existing method in a trait
}
impl<U: Copy> T1 for S<U> {
@@ -57,6 +60,7 @@ mod should_lint {
impl S {
fn foo() {}
+ //~^ ERROR: method's name is the same as an existing method in a trait
}
impl T1 for S {}
@@ -69,6 +73,7 @@ mod should_lint {
impl S {
fn foo() {}
+ //~^ ERROR: method's name is the same as an existing method in a trait
}
impl T1 for S {}
diff --git a/src/tools/clippy/tests/ui/same_name_method.stderr b/src/tools/clippy/tests/ui/same_name_method.stderr
index 0c6908c09..3c5c4a53a 100644
--- a/src/tools/clippy/tests/ui/same_name_method.stderr
+++ b/src/tools/clippy/tests/ui/same_name_method.stderr
@@ -5,57 +5,58 @@ LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
- --> $DIR/same_name_method.rs:25:13
+ --> $DIR/same_name_method.rs:26:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
= note: `-D clippy::same-name-method` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::same_name_method)]`
error: method's name is the same as an existing method in a trait
- --> $DIR/same_name_method.rs:35:13
+ --> $DIR/same_name_method.rs:36:13
|
LL | fn clone() {}
| ^^^^^^^^^^^^^
|
note: existing `clone` defined here
- --> $DIR/same_name_method.rs:31:18
+ --> $DIR/same_name_method.rs:32:18
|
LL | #[derive(Clone)]
| ^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: method's name is the same as an existing method in a trait
- --> $DIR/same_name_method.rs:45:13
+ --> $DIR/same_name_method.rs:47:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
- --> $DIR/same_name_method.rs:49:13
+ --> $DIR/same_name_method.rs:52:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
error: method's name is the same as an existing method in a trait
- --> $DIR/same_name_method.rs:59:13
+ --> $DIR/same_name_method.rs:62:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
- --> $DIR/same_name_method.rs:62:9
+ --> $DIR/same_name_method.rs:66:9
|
LL | impl T1 for S {}
| ^^^^^^^^^^^^^^^^
error: method's name is the same as an existing method in a trait
- --> $DIR/same_name_method.rs:71:13
+ --> $DIR/same_name_method.rs:75:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
- --> $DIR/same_name_method.rs:74:9
+ --> $DIR/same_name_method.rs:79:9
|
LL | impl T1 for S {}
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/search_is_some.rs b/src/tools/clippy/tests/ui/search_is_some.rs
index 3cdbfaa16..e8a0920b6 100644
--- a/src/tools/clippy/tests/ui/search_is_some.rs
+++ b/src/tools/clippy/tests/ui/search_is_some.rs
@@ -4,7 +4,7 @@
#![allow(dead_code)]
extern crate option_helpers;
use option_helpers::IteratorFalsePositives;
-
+//@no-rustfix
#[rustfmt::skip]
fn main() {
let v = vec![3, 2, 1, 0, -1, -2, -3];
diff --git a/src/tools/clippy/tests/ui/search_is_some.stderr b/src/tools/clippy/tests/ui/search_is_some.stderr
index 7eff614d1..a7a47447f 100644
--- a/src/tools/clippy/tests/ui/search_is_some.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some.stderr
@@ -10,6 +10,7 @@ LL | | ).is_some();
|
= help: this is more succinctly expressed by calling `any()`
= note: `-D clippy::search-is-some` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
error: called `is_some()` after searching an `Iterator` with `position`
--> $DIR/search_is_some.rs:21:13
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed b/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed
index 08fb87cb3..51636392f 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)]
#![warn(clippy::search_is_some)]
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs b/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs
index ec3386933..c7d773e18 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)]
#![warn(clippy::search_is_some)]
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr b/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr
index 933ce5cf4..f33b04309 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr
@@ -1,55 +1,56 @@
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:10:13
+ --> $DIR/search_is_some_fixable_none.rs:9:13
|
LL | let _ = v.iter().find(|&x| *x < 0).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x < 0)`
|
= note: `-D clippy::search-is-some` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:11:13
+ --> $DIR/search_is_some_fixable_none.rs:10:13
|
LL | let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| **y == x)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:12:13
+ --> $DIR/search_is_some_fixable_none.rs:11:13
|
LL | let _ = (0..1).find(|x| *x == 0).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| x == 0)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:13:13
+ --> $DIR/search_is_some_fixable_none.rs:12:13
|
LL | let _ = v.iter().find(|x| **x == 0).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x == 0)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:14:13
+ --> $DIR/search_is_some_fixable_none.rs:13:13
|
LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:15:13
+ --> $DIR/search_is_some_fixable_none.rs:14:13
|
LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:16:13
+ --> $DIR/search_is_some_fixable_none.rs:15:13
|
LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:17:13
+ --> $DIR/search_is_some_fixable_none.rs:16:13
|
LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:18:13
+ --> $DIR/search_is_some_fixable_none.rs:17:13
|
LL | let _ = (1..3)
| _____________^
@@ -58,91 +59,91 @@ LL | | .is_none();
| |__________________^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
error: called `is_none()` after searching an `Iterator` with `position`
- --> $DIR/search_is_some_fixable_none.rs:23:13
+ --> $DIR/search_is_some_fixable_none.rs:22:13
|
LL | let _ = v.iter().position(|&x| x < 0).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)`
error: called `is_none()` after searching an `Iterator` with `rposition`
- --> $DIR/search_is_some_fixable_none.rs:26:13
+ --> $DIR/search_is_some_fixable_none.rs:25:13
|
LL | let _ = v.iter().rposition(|&x| x < 0).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:32:13
+ --> $DIR/search_is_some_fixable_none.rs:31:13
|
LL | let _ = "hello world".find("world").is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains("world")`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:33:13
+ --> $DIR/search_is_some_fixable_none.rs:32:13
|
LL | let _ = "hello world".find(&s2).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2)`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:34:13
+ --> $DIR/search_is_some_fixable_none.rs:33:13
|
LL | let _ = "hello world".find(&s2[2..]).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2[2..])`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:36:13
+ --> $DIR/search_is_some_fixable_none.rs:35:13
|
LL | let _ = s1.find("world").is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains("world")`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:37:13
+ --> $DIR/search_is_some_fixable_none.rs:36:13
|
LL | let _ = s1.find(&s2).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2)`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:38:13
+ --> $DIR/search_is_some_fixable_none.rs:37:13
|
LL | let _ = s1.find(&s2[2..]).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2[2..])`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:40:13
+ --> $DIR/search_is_some_fixable_none.rs:39:13
|
LL | let _ = s1[2..].find("world").is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains("world")`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:41:13
+ --> $DIR/search_is_some_fixable_none.rs:40:13
|
LL | let _ = s1[2..].find(&s2).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2)`
error: called `is_none()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_none.rs:42:13
+ --> $DIR/search_is_some_fixable_none.rs:41:13
|
LL | let _ = s1[2..].find(&s2[2..]).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2[2..])`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:58:25
+ --> $DIR/search_is_some_fixable_none.rs:57:25
|
LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == &cc)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:74:30
+ --> $DIR/search_is_some_fixable_none.rs:73:30
|
LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == cc)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:85:17
+ --> $DIR/search_is_some_fixable_none.rs:84:17
|
LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:88:17
+ --> $DIR/search_is_some_fixable_none.rs:87:17
|
LL | let _ = vfoo
| _________________^
@@ -158,55 +159,55 @@ LL ~ .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2);
|
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:96:17
+ --> $DIR/search_is_some_fixable_none.rs:95:17
|
LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|a| a[0] == 42)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:102:17
+ --> $DIR/search_is_some_fixable_none.rs:101:17
|
LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:120:17
+ --> $DIR/search_is_some_fixable_none.rs:119:17
|
LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:121:17
+ --> $DIR/search_is_some_fixable_none.rs:120:17
|
LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:124:17
+ --> $DIR/search_is_some_fixable_none.rs:123:17
|
LL | let _ = v.iter().find(|x| deref_enough(**x)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| deref_enough(*x))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:125:17
+ --> $DIR/search_is_some_fixable_none.rs:124:17
|
LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| deref_enough(*x))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:128:17
+ --> $DIR/search_is_some_fixable_none.rs:127:17
|
LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| arg_no_deref(&x))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:130:17
+ --> $DIR/search_is_some_fixable_none.rs:129:17
|
LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| arg_no_deref(&x))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:150:17
+ --> $DIR/search_is_some_fixable_none.rs:149:17
|
LL | let _ = vfoo
| _________________^
@@ -222,61 +223,61 @@ LL ~ .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0]
|
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:166:17
+ --> $DIR/search_is_some_fixable_none.rs:165:17
|
LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.inner[0].bar == 2)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:171:17
+ --> $DIR/search_is_some_fixable_none.rs:170:17
|
LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|x| (**x)[0] == 9)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:184:17
+ --> $DIR/search_is_some_fixable_none.rs:183:17
|
LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.by_ref(&v.bar))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:188:17
+ --> $DIR/search_is_some_fixable_none.rs:187:17
|
LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:189:17
+ --> $DIR/search_is_some_fixable_none.rs:188:17
|
LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:208:17
+ --> $DIR/search_is_some_fixable_none.rs:207:17
|
LL | let _ = v.iter().find(|s| s[0].is_empty()).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| s[0].is_empty())`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:209:17
+ --> $DIR/search_is_some_fixable_none.rs:208:17
|
LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| test_string_1(&s[0]))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:218:17
+ --> $DIR/search_is_some_fixable_none.rs:217:17
|
LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| fp.field.is_power_of_two())`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:219:17
+ --> $DIR/search_is_some_fixable_none.rs:218:17
|
LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_1(fp.field))`
error: called `is_none()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_none.rs:220:17
+ --> $DIR/search_is_some_fixable_none.rs:219:17
|
LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_2(*fp.field))`
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed
index aa16f9da0..ae3cbc3c4 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)]
#![warn(clippy::search_is_some)]
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs
index aeb6f118b..19a44803f 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)]
#![warn(clippy::search_is_some)]
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
index c5c3c92c9..e878e62de 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
@@ -1,55 +1,56 @@
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:10:22
+ --> $DIR/search_is_some_fixable_some.rs:9:22
|
LL | let _ = v.iter().find(|&x| *x < 0).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x < 0)`
|
= note: `-D clippy::search-is-some` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:11:20
+ --> $DIR/search_is_some_fixable_some.rs:10:20
|
LL | let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| **y == x)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:12:20
+ --> $DIR/search_is_some_fixable_some.rs:11:20
|
LL | let _ = (0..1).find(|x| *x == 0).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:13:22
+ --> $DIR/search_is_some_fixable_some.rs:12:22
|
LL | let _ = v.iter().find(|x| **x == 0).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x == 0)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:14:20
+ --> $DIR/search_is_some_fixable_some.rs:13:20
|
LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 1 || x == 3 || x == 5)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:15:20
+ --> $DIR/search_is_some_fixable_some.rs:14:20
|
LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:16:20
+ --> $DIR/search_is_some_fixable_some.rs:15:20
|
LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0 || [1, 2, 3].contains(&x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:17:20
+ --> $DIR/search_is_some_fixable_some.rs:16:20
|
LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:19:10
+ --> $DIR/search_is_some_fixable_some.rs:18:10
|
LL | .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)
| __________^
@@ -57,91 +58,91 @@ LL | | .is_some();
| |__________________^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
error: called `is_some()` after searching an `Iterator` with `position`
- --> $DIR/search_is_some_fixable_some.rs:23:22
+ --> $DIR/search_is_some_fixable_some.rs:22:22
|
LL | let _ = v.iter().position(|&x| x < 0).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)`
error: called `is_some()` after searching an `Iterator` with `rposition`
- --> $DIR/search_is_some_fixable_some.rs:26:22
+ --> $DIR/search_is_some_fixable_some.rs:25:22
|
LL | let _ = v.iter().rposition(|&x| x < 0).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:31:27
+ --> $DIR/search_is_some_fixable_some.rs:30:27
|
LL | let _ = "hello world".find("world").is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:32:27
+ --> $DIR/search_is_some_fixable_some.rs:31:27
|
LL | let _ = "hello world".find(&s2).is_some();
| ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:33:27
+ --> $DIR/search_is_some_fixable_some.rs:32:27
|
LL | let _ = "hello world".find(&s2[2..]).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:35:16
+ --> $DIR/search_is_some_fixable_some.rs:34:16
|
LL | let _ = s1.find("world").is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:36:16
+ --> $DIR/search_is_some_fixable_some.rs:35:16
|
LL | let _ = s1.find(&s2).is_some();
| ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:37:16
+ --> $DIR/search_is_some_fixable_some.rs:36:16
|
LL | let _ = s1.find(&s2[2..]).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:39:21
+ --> $DIR/search_is_some_fixable_some.rs:38:21
|
LL | let _ = s1[2..].find("world").is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:40:21
+ --> $DIR/search_is_some_fixable_some.rs:39:21
|
LL | let _ = s1[2..].find(&s2).is_some();
| ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
error: called `is_some()` after calling `find()` on a string
- --> $DIR/search_is_some_fixable_some.rs:41:21
+ --> $DIR/search_is_some_fixable_some.rs:40:21
|
LL | let _ = s1[2..].find(&s2[2..]).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:57:44
+ --> $DIR/search_is_some_fixable_some.rs:56:44
|
LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == &cc)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:73:49
+ --> $DIR/search_is_some_fixable_some.rs:72:49
|
LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == cc)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:84:29
+ --> $DIR/search_is_some_fixable_some.rs:83:29
|
LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.foo == 1 && v.bar == 2)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:89:14
+ --> $DIR/search_is_some_fixable_some.rs:88:14
|
LL | .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)
| ______________^
@@ -149,55 +150,55 @@ LL | | .is_some();
| |______________________^ help: use `any()` instead: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:95:29
+ --> $DIR/search_is_some_fixable_some.rs:94:29
|
LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|a| a[0] == 42)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:101:29
+ --> $DIR/search_is_some_fixable_some.rs:100:29
|
LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|sub| sub[1..4].len() == 3)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:119:30
+ --> $DIR/search_is_some_fixable_some.rs:118:30
|
LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|ppp_x: &&u32| please(ppp_x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:120:50
+ --> $DIR/search_is_some_fixable_some.rs:119:50
|
LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s.len() == 2)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:123:26
+ --> $DIR/search_is_some_fixable_some.rs:122:26
|
LL | let _ = v.iter().find(|x| deref_enough(**x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| deref_enough(*x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:124:26
+ --> $DIR/search_is_some_fixable_some.rs:123:26
|
LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| deref_enough(*x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:127:26
+ --> $DIR/search_is_some_fixable_some.rs:126:26
|
LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| arg_no_deref(&x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:129:26
+ --> $DIR/search_is_some_fixable_some.rs:128:26
|
LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref(&x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:151:14
+ --> $DIR/search_is_some_fixable_some.rs:150:14
|
LL | .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)
| ______________^
@@ -205,85 +206,85 @@ LL | | .is_some();
| |______________________^ help: use `any()` instead: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:165:29
+ --> $DIR/search_is_some_fixable_some.rs:164:29
|
LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.inner[0].bar == 2)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:170:29
+ --> $DIR/search_is_some_fixable_some.rs:169:29
|
LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| (**x)[0] == 9)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:183:29
+ --> $DIR/search_is_some_fixable_some.rs:182:29
|
LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.by_ref(&v.bar))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:187:55
+ --> $DIR/search_is_some_fixable_some.rs:186:55
|
LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:188:55
+ --> $DIR/search_is_some_fixable_some.rs:187:55
|
LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:207:26
+ --> $DIR/search_is_some_fixable_some.rs:206:26
|
LL | let _ = v.iter().find(|s| s[0].is_empty()).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s[0].is_empty())`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:208:26
+ --> $DIR/search_is_some_fixable_some.rs:207:26
|
LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| test_string_1(&s[0]))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:217:26
+ --> $DIR/search_is_some_fixable_some.rs:216:26
|
LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| fp.field.is_power_of_two())`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:218:26
+ --> $DIR/search_is_some_fixable_some.rs:217:26
|
LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_1(fp.field))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:219:26
+ --> $DIR/search_is_some_fixable_some.rs:218:26
|
LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_2(*fp.field))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:234:18
+ --> $DIR/search_is_some_fixable_some.rs:233:18
|
LL | v.iter().find(|x: &&u32| func(x)).is_some()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| func(&x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:243:26
+ --> $DIR/search_is_some_fixable_some.rs:242:26
|
LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_impl(&x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:246:26
+ --> $DIR/search_is_some_fixable_some.rs:245:26
|
LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_dyn(&x))`
error: called `is_some()` after searching an `Iterator` with `find`
- --> $DIR/search_is_some_fixable_some.rs:249:26
+ --> $DIR/search_is_some_fixable_some.rs:248:26
|
LL | let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| (*arg_no_deref_dyn)(&x))`
diff --git a/src/tools/clippy/tests/ui/seek_from_current.fixed b/src/tools/clippy/tests/ui/seek_from_current.fixed
index 34c33baf6..543f0c681 100644
--- a/src/tools/clippy/tests/ui/seek_from_current.fixed
+++ b/src/tools/clippy/tests/ui/seek_from_current.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::seek_from_current)]
use std::fs::File;
diff --git a/src/tools/clippy/tests/ui/seek_from_current.rs b/src/tools/clippy/tests/ui/seek_from_current.rs
index 22bcff1bc..4ed877f8e 100644
--- a/src/tools/clippy/tests/ui/seek_from_current.rs
+++ b/src/tools/clippy/tests/ui/seek_from_current.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::seek_from_current)]
use std::fs::File;
diff --git a/src/tools/clippy/tests/ui/seek_from_current.stderr b/src/tools/clippy/tests/ui/seek_from_current.stderr
index c079f3611..42eb342c1 100644
--- a/src/tools/clippy/tests/ui/seek_from_current.stderr
+++ b/src/tools/clippy/tests/ui/seek_from_current.stderr
@@ -1,10 +1,11 @@
error: using `SeekFrom::Current` to start from current position
- --> $DIR/seek_from_current.rs:20:5
+ --> $DIR/seek_from_current.rs:19:5
|
LL | f.seek(SeekFrom::Current(0))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `f.stream_position()`
|
= note: `-D clippy::seek-from-current` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::seek_from_current)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed
index d8a6e6985..15cc8d54f 100644
--- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::seek_to_start_instead_of_rewind)]
diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs
index fc6a6433c..197225ffb 100644
--- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::seek_to_start_instead_of_rewind)]
diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr
index 342ec00fe..05c11cf7f 100644
--- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr
@@ -1,19 +1,20 @@
error: used `seek` to go to the start of the stream
- --> $DIR/seek_to_start_instead_of_rewind.rs:53:7
+ --> $DIR/seek_to_start_instead_of_rewind.rs:52:7
|
LL | t.seek(SeekFrom::Start(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
|
= note: `-D clippy::seek-to-start-instead-of-rewind` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::seek_to_start_instead_of_rewind)]`
error: used `seek` to go to the start of the stream
- --> $DIR/seek_to_start_instead_of_rewind.rs:58:7
+ --> $DIR/seek_to_start_instead_of_rewind.rs:57:7
|
LL | t.seek(SeekFrom::Start(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
error: used `seek` to go to the start of the stream
- --> $DIR/seek_to_start_instead_of_rewind.rs:134:7
+ --> $DIR/seek_to_start_instead_of_rewind.rs:133:7
|
LL | f.seek(SeekFrom::Start(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
diff --git a/src/tools/clippy/tests/ui/self_assignment.rs b/src/tools/clippy/tests/ui/self_assignment.rs
index a7f9fbaae..213bca6c4 100644
--- a/src/tools/clippy/tests/ui/self_assignment.rs
+++ b/src/tools/clippy/tests/ui/self_assignment.rs
@@ -11,18 +11,30 @@ pub struct S<'a> {
pub fn positives(mut a: usize, b: &mut u32, mut s: S) {
a = a;
+ //~^ ERROR: self-assignment of `a` to `a`
+ //~| NOTE: `-D clippy::self-assignment` implied by `-D warnings`
*b = *b;
+ //~^ ERROR: self-assignment of `*b` to `*b`
s = s;
+ //~^ ERROR: self-assignment of `s` to `s`
s.a = s.a;
+ //~^ ERROR: self-assignment of `s.a` to `s.a`
s.b[9] = s.b[5 + 4];
+ //~^ ERROR: self-assignment of `s.b[5 + 4]` to `s.b[9]`
s.c[0][1] = s.c[0][1];
+ //~^ ERROR: self-assignment of `s.c[0][1]` to `s.c[0][1]`
s.b[a] = s.b[a];
+ //~^ ERROR: self-assignment of `s.b[a]` to `s.b[a]`
*s.e = *s.e;
+ //~^ ERROR: self-assignment of `*s.e` to `*s.e`
s.b[a + 10] = s.b[10 + a];
+ //~^ ERROR: self-assignment of `s.b[10 + a]` to `s.b[a + 10]`
let mut t = (0, 1);
t.1 = t.1;
+ //~^ ERROR: self-assignment of `t.1` to `t.1`
t.0 = (t.0);
+ //~^ ERROR: self-assignment of `(t.0)` to `t.0`
}
pub fn negatives_not_equal(mut a: usize, b: &mut usize, mut s: S) {
diff --git a/src/tools/clippy/tests/ui/self_assignment.stderr b/src/tools/clippy/tests/ui/self_assignment.stderr
index 25b8569fa..4612f8f82 100644
--- a/src/tools/clippy/tests/ui/self_assignment.stderr
+++ b/src/tools/clippy/tests/ui/self_assignment.stderr
@@ -5,63 +5,64 @@ LL | a = a;
| ^^^^^
|
= note: `-D clippy::self-assignment` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::self_assignment)]`
error: self-assignment of `*b` to `*b`
- --> $DIR/self_assignment.rs:14:5
+ --> $DIR/self_assignment.rs:16:5
|
LL | *b = *b;
| ^^^^^^^
error: self-assignment of `s` to `s`
- --> $DIR/self_assignment.rs:15:5
+ --> $DIR/self_assignment.rs:18:5
|
LL | s = s;
| ^^^^^
error: self-assignment of `s.a` to `s.a`
- --> $DIR/self_assignment.rs:16:5
+ --> $DIR/self_assignment.rs:20:5
|
LL | s.a = s.a;
| ^^^^^^^^^
error: self-assignment of `s.b[5 + 4]` to `s.b[9]`
- --> $DIR/self_assignment.rs:17:5
+ --> $DIR/self_assignment.rs:22:5
|
LL | s.b[9] = s.b[5 + 4];
| ^^^^^^^^^^^^^^^^^^^
error: self-assignment of `s.c[0][1]` to `s.c[0][1]`
- --> $DIR/self_assignment.rs:18:5
+ --> $DIR/self_assignment.rs:24:5
|
LL | s.c[0][1] = s.c[0][1];
| ^^^^^^^^^^^^^^^^^^^^^
error: self-assignment of `s.b[a]` to `s.b[a]`
- --> $DIR/self_assignment.rs:19:5
+ --> $DIR/self_assignment.rs:26:5
|
LL | s.b[a] = s.b[a];
| ^^^^^^^^^^^^^^^
error: self-assignment of `*s.e` to `*s.e`
- --> $DIR/self_assignment.rs:20:5
+ --> $DIR/self_assignment.rs:28:5
|
LL | *s.e = *s.e;
| ^^^^^^^^^^^
error: self-assignment of `s.b[10 + a]` to `s.b[a + 10]`
- --> $DIR/self_assignment.rs:21:5
+ --> $DIR/self_assignment.rs:30:5
|
LL | s.b[a + 10] = s.b[10 + a];
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: self-assignment of `t.1` to `t.1`
- --> $DIR/self_assignment.rs:24:5
+ --> $DIR/self_assignment.rs:34:5
|
LL | t.1 = t.1;
| ^^^^^^^^^
error: self-assignment of `(t.0)` to `t.0`
- --> $DIR/self_assignment.rs:25:5
+ --> $DIR/self_assignment.rs:36:5
|
LL | t.0 = (t.0);
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/self_named_constructors.rs b/src/tools/clippy/tests/ui/self_named_constructors.rs
index 356f701c9..dc326b399 100644
--- a/src/tools/clippy/tests/ui/self_named_constructors.rs
+++ b/src/tools/clippy/tests/ui/self_named_constructors.rs
@@ -5,6 +5,8 @@ struct ShouldNotSpawn;
impl ShouldSpawn {
pub fn should_spawn() -> ShouldSpawn {
+ //~^ ERROR: constructor `should_spawn` has the same name as the type
+ //~| NOTE: `-D clippy::self-named-constructors` implied by `-D warnings`
ShouldSpawn
}
diff --git a/src/tools/clippy/tests/ui/self_named_constructors.stderr b/src/tools/clippy/tests/ui/self_named_constructors.stderr
index ba989f06d..f299b860d 100644
--- a/src/tools/clippy/tests/ui/self_named_constructors.stderr
+++ b/src/tools/clippy/tests/ui/self_named_constructors.stderr
@@ -2,11 +2,14 @@ error: constructor `should_spawn` has the same name as the type
--> $DIR/self_named_constructors.rs:7:5
|
LL | / pub fn should_spawn() -> ShouldSpawn {
+LL | |
+LL | |
LL | | ShouldSpawn
LL | | }
| |_____^
|
= note: `-D clippy::self-named-constructors` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::self_named_constructors)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed
index 653f4533b..bbcc0de27 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::semicolon_if_nothing_returned)]
#![allow(clippy::redundant_closure, clippy::uninlined_format_args, clippy::needless_late_init)]
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
index 9db038219..fdc9c0c33 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::semicolon_if_nothing_returned)]
#![allow(clippy::redundant_closure, clippy::uninlined_format_args, clippy::needless_late_init)]
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
index 78813e7cc..66373a13c 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
@@ -1,31 +1,32 @@
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:9:5
+ --> $DIR/semicolon_if_nothing_returned.rs:8:5
|
LL | println!("Hello")
| ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!("Hello");`
|
= note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::semicolon_if_nothing_returned)]`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:13:5
+ --> $DIR/semicolon_if_nothing_returned.rs:12:5
|
LL | get_unit()
| ^^^^^^^^^^ help: add a `;` here: `get_unit();`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:18:5
+ --> $DIR/semicolon_if_nothing_returned.rs:17:5
|
LL | y = x + 1
| ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:24:9
+ --> $DIR/semicolon_if_nothing_returned.rs:23:9
|
LL | hello()
| ^^^^^^^ help: add a `;` here: `hello();`
error: consider adding a `;` to the last statement for consistent formatting
- --> $DIR/semicolon_if_nothing_returned.rs:35:9
+ --> $DIR/semicolon_if_nothing_returned.rs:34:9
|
LL | ptr::drop_in_place(s.as_mut_ptr())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block.fixed b/src/tools/clippy/tests/ui/semicolon_inside_block.fixed
index ee359f60c..21681e715 100644
--- a/src/tools/clippy/tests/ui/semicolon_inside_block.fixed
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block.rs b/src/tools/clippy/tests/ui/semicolon_inside_block.rs
index e8516f79b..3a81661cd 100644
--- a/src/tools/clippy/tests/ui/semicolon_inside_block.rs
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block.stderr b/src/tools/clippy/tests/ui/semicolon_inside_block.stderr
index 48d3690e2..1bfc1f24c 100644
--- a/src/tools/clippy/tests/ui/semicolon_inside_block.stderr
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block.stderr
@@ -1,10 +1,11 @@
error: consider moving the `;` inside the block for consistent formatting
- --> $DIR/semicolon_inside_block.rs:39:5
+ --> $DIR/semicolon_inside_block.rs:38:5
|
LL | { unit_fn_block() };
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::semicolon-inside-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`
help: put the `;` here
|
LL - { unit_fn_block() };
@@ -12,7 +13,7 @@ LL + { unit_fn_block(); }
|
error: consider moving the `;` inside the block for consistent formatting
- --> $DIR/semicolon_inside_block.rs:40:5
+ --> $DIR/semicolon_inside_block.rs:39:5
|
LL | unsafe { unit_fn_block() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + unsafe { unit_fn_block(); }
|
error: consider moving the `;` inside the block for consistent formatting
- --> $DIR/semicolon_inside_block.rs:48:5
+ --> $DIR/semicolon_inside_block.rs:47:5
|
LL | / {
LL | | unit_fn_block();
@@ -39,7 +40,7 @@ LL ~ }
|
error: consider moving the `;` inside the block for consistent formatting
- --> $DIR/semicolon_inside_block.rs:61:5
+ --> $DIR/semicolon_inside_block.rs:60:5
|
LL | { m!(()) };
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.fixed b/src/tools/clippy/tests/ui/semicolon_outside_block.fixed
index 034c7f8c7..148e112e0 100644
--- a/src/tools/clippy/tests/ui/semicolon_outside_block.fixed
+++ b/src/tools/clippy/tests/ui/semicolon_outside_block.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.rs b/src/tools/clippy/tests/ui/semicolon_outside_block.rs
index 4dc956d8a..c76720146 100644
--- a/src/tools/clippy/tests/ui/semicolon_outside_block.rs
+++ b/src/tools/clippy/tests/ui/semicolon_outside_block.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(
unused,
clippy::unused_unit,
diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.stderr b/src/tools/clippy/tests/ui/semicolon_outside_block.stderr
index dcc102e60..427271fca 100644
--- a/src/tools/clippy/tests/ui/semicolon_outside_block.stderr
+++ b/src/tools/clippy/tests/ui/semicolon_outside_block.stderr
@@ -1,10 +1,11 @@
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/semicolon_outside_block.rs:42:5
+ --> $DIR/semicolon_outside_block.rs:41:5
|
LL | { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::semicolon-outside-block` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::semicolon_outside_block)]`
help: put the `;` here
|
LL - { unit_fn_block(); }
@@ -12,7 +13,7 @@ LL + { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/semicolon_outside_block.rs:43:5
+ --> $DIR/semicolon_outside_block.rs:42:5
|
LL | unsafe { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + unsafe { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/semicolon_outside_block.rs:52:5
+ --> $DIR/semicolon_outside_block.rs:51:5
|
LL | / {
LL | | unit_fn_block();
@@ -39,7 +40,7 @@ LL ~ };
|
error: consider moving the `;` outside the block for consistent formatting
- --> $DIR/semicolon_outside_block.rs:62:5
+ --> $DIR/semicolon_outside_block.rs:61:5
|
LL | { m!(()); }
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/serde.rs b/src/tools/clippy/tests/ui/serde.rs
index 5843344eb..610a50020 100644
--- a/src/tools/clippy/tests/ui/serde.rs
+++ b/src/tools/clippy/tests/ui/serde.rs
@@ -37,6 +37,8 @@ impl<'de> serde::de::Visitor<'de> for B {
}
fn visit_string<E>(self, _v: String) -> Result<Self::Value, E>
+ //~^ ERROR: you should not implement `visit_string` without also implementing `visit_s
+ //~| NOTE: `-D clippy::serde-api-misuse` implied by `-D warnings`
where
E: serde::de::Error,
{
diff --git a/src/tools/clippy/tests/ui/serde.stderr b/src/tools/clippy/tests/ui/serde.stderr
index 760c9c990..e5d64e271 100644
--- a/src/tools/clippy/tests/ui/serde.stderr
+++ b/src/tools/clippy/tests/ui/serde.stderr
@@ -2,14 +2,16 @@ error: you should not implement `visit_string` without also implementing `visit_
--> $DIR/serde.rs:39:5
|
LL | / fn visit_string<E>(self, _v: String) -> Result<Self::Value, E>
+LL | |
+LL | |
LL | | where
-LL | | E: serde::de::Error,
-LL | | {
+... |
LL | | unimplemented!()
LL | | }
| |_____^
|
= note: `-D clippy::serde-api-misuse` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::serde_api_misuse)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/shadow.rs b/src/tools/clippy/tests/ui/shadow.rs
index 1b40a43d0..258dba9dd 100644
--- a/src/tools/clippy/tests/ui/shadow.rs
+++ b/src/tools/clippy/tests/ui/shadow.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/shadow.stderr b/src/tools/clippy/tests/ui/shadow.stderr
index 88b02f53b..26ace287b 100644
--- a/src/tools/clippy/tests/ui/shadow.stderr
+++ b/src/tools/clippy/tests/ui/shadow.stderr
@@ -10,6 +10,7 @@ note: previous binding is here
LL | let x = 1;
| ^
= note: `-D clippy::shadow-same` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::shadow_same)]`
error: `mut x` is shadowed by itself in `&x`
--> $DIR/shadow.rs:25:13
@@ -59,6 +60,7 @@ note: previous binding is here
LL | let x = ([[0]], ());
| ^
= note: `-D clippy::shadow-reuse` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::shadow_reuse)]`
error: `x` is shadowed
--> $DIR/shadow.rs:33:9
@@ -156,6 +158,7 @@ note: previous binding is here
LL | let x = 1;
| ^
= note: `-D clippy::shadow-unrelated` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::shadow_unrelated)]`
error: `x` shadows a previous, unrelated binding
--> $DIR/shadow.rs:60:13
diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.fixed b/src/tools/clippy/tests/ui/short_circuit_statement.fixed
index 1737d5014..a9930ef4d 100644
--- a/src/tools/clippy/tests/ui/short_circuit_statement.fixed
+++ b/src/tools/clippy/tests/ui/short_circuit_statement.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::short_circuit_statement)]
#![allow(clippy::nonminimal_bool)]
diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.rs b/src/tools/clippy/tests/ui/short_circuit_statement.rs
index ab93aa1ca..71f7c7f2a 100644
--- a/src/tools/clippy/tests/ui/short_circuit_statement.rs
+++ b/src/tools/clippy/tests/ui/short_circuit_statement.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::short_circuit_statement)]
#![allow(clippy::nonminimal_bool)]
diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.stderr b/src/tools/clippy/tests/ui/short_circuit_statement.stderr
index aa84ac3a7..dbdf44dfc 100644
--- a/src/tools/clippy/tests/ui/short_circuit_statement.stderr
+++ b/src/tools/clippy/tests/ui/short_circuit_statement.stderr
@@ -1,19 +1,20 @@
error: boolean short circuit operator in statement may be clearer using an explicit test
- --> $DIR/short_circuit_statement.rs:7:5
+ --> $DIR/short_circuit_statement.rs:5:5
|
LL | f() && g();
| ^^^^^^^^^^^ help: replace it with: `if f() { g(); }`
|
= note: `-D clippy::short-circuit-statement` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::short_circuit_statement)]`
error: boolean short circuit operator in statement may be clearer using an explicit test
- --> $DIR/short_circuit_statement.rs:8:5
+ --> $DIR/short_circuit_statement.rs:6:5
|
LL | f() || g();
| ^^^^^^^^^^^ help: replace it with: `if !f() { g(); }`
error: boolean short circuit operator in statement may be clearer using an explicit test
- --> $DIR/short_circuit_statement.rs:9:5
+ --> $DIR/short_circuit_statement.rs:7:5
|
LL | 1 == 2 || g();
| ^^^^^^^^^^^^^^ help: replace it with: `if 1 != 2 { g(); }`
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.rs b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.rs
index 20d49f5a9..85eed3f06 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.rs
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.rs
@@ -23,62 +23,77 @@ impl T {
// trait method list part 1, should lint all
// *****************************************
pub fn add(self, other: T) -> T {
+ //~^ ERROR: method `add` can be confused for the standard trait method `std::ops::Add:
unimplemented!()
}
pub fn as_mut(&mut self) -> &mut T {
+ //~^ ERROR: method `as_mut` can be confused for the standard trait method `std::conver
unimplemented!()
}
pub fn as_ref(&self) -> &T {
+ //~^ ERROR: method `as_ref` can be confused for the standard trait method `std::conver
unimplemented!()
}
pub fn bitand(self, rhs: T) -> T {
+ //~^ ERROR: method `bitand` can be confused for the standard trait method `std::ops::B
unimplemented!()
}
pub fn bitor(self, rhs: Self) -> Self {
+ //~^ ERROR: method `bitor` can be confused for the standard trait method `std::ops::Bi
unimplemented!()
}
pub fn bitxor(self, rhs: Self) -> Self {
+ //~^ ERROR: method `bitxor` can be confused for the standard trait method `std::ops::B
unimplemented!()
}
pub fn borrow(&self) -> &str {
+ //~^ ERROR: method `borrow` can be confused for the standard trait method `std::borrow
unimplemented!()
}
pub fn borrow_mut(&mut self) -> &mut str {
+ //~^ ERROR: method `borrow_mut` can be confused for the standard trait method `std::bo
unimplemented!()
}
pub fn clone(&self) -> Self {
+ //~^ ERROR: method `clone` can be confused for the standard trait method `std::clone::
unimplemented!()
}
pub fn cmp(&self, other: &Self) -> Self {
+ //~^ ERROR: method `cmp` can be confused for the standard trait method `std::cmp::Ord:
unimplemented!()
}
pub fn default() -> Self {
+ //~^ ERROR: method `default` can be confused for the standard trait method `std::defau
unimplemented!()
}
pub fn deref(&self) -> &Self {
+ //~^ ERROR: method `deref` can be confused for the standard trait method `std::ops::De
unimplemented!()
}
pub fn deref_mut(&mut self) -> &mut Self {
+ //~^ ERROR: method `deref_mut` can be confused for the standard trait method `std::ops
unimplemented!()
}
pub fn div(self, rhs: Self) -> Self {
+ //~^ ERROR: method `div` can be confused for the standard trait method `std::ops::Div:
unimplemented!()
}
pub fn drop(&mut self) {
+ //~^ ERROR: method `drop` can be confused for the standard trait method `std::ops::Dro
unimplemented!()
}
// **********
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr
index 161dd66b0..c9894eec5 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr
@@ -2,17 +2,20 @@ error: method `add` can be confused for the standard trait method `std::ops::Add
--> $DIR/method_list_1.rs:25:5
|
LL | / pub fn add(self, other: T) -> T {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
|
= help: consider implementing the trait `std::ops::Add` or choosing a less ambiguous method name
= note: `-D clippy::should-implement-trait` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]`
error: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut`
- --> $DIR/method_list_1.rs:29:5
+ --> $DIR/method_list_1.rs:30:5
|
LL | / pub fn as_mut(&mut self) -> &mut T {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -20,9 +23,10 @@ LL | | }
= help: consider implementing the trait `std::convert::AsMut` or choosing a less ambiguous method name
error: method `as_ref` can be confused for the standard trait method `std::convert::AsRef::as_ref`
- --> $DIR/method_list_1.rs:33:5
+ --> $DIR/method_list_1.rs:35:5
|
LL | / pub fn as_ref(&self) -> &T {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -30,9 +34,10 @@ LL | | }
= help: consider implementing the trait `std::convert::AsRef` or choosing a less ambiguous method name
error: method `bitand` can be confused for the standard trait method `std::ops::BitAnd::bitand`
- --> $DIR/method_list_1.rs:37:5
+ --> $DIR/method_list_1.rs:40:5
|
LL | / pub fn bitand(self, rhs: T) -> T {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -40,9 +45,10 @@ LL | | }
= help: consider implementing the trait `std::ops::BitAnd` or choosing a less ambiguous method name
error: method `bitor` can be confused for the standard trait method `std::ops::BitOr::bitor`
- --> $DIR/method_list_1.rs:41:5
+ --> $DIR/method_list_1.rs:45:5
|
LL | / pub fn bitor(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -50,9 +56,10 @@ LL | | }
= help: consider implementing the trait `std::ops::BitOr` or choosing a less ambiguous method name
error: method `bitxor` can be confused for the standard trait method `std::ops::BitXor::bitxor`
- --> $DIR/method_list_1.rs:45:5
+ --> $DIR/method_list_1.rs:50:5
|
LL | / pub fn bitxor(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -60,9 +67,10 @@ LL | | }
= help: consider implementing the trait `std::ops::BitXor` or choosing a less ambiguous method name
error: method `borrow` can be confused for the standard trait method `std::borrow::Borrow::borrow`
- --> $DIR/method_list_1.rs:49:5
+ --> $DIR/method_list_1.rs:55:5
|
LL | / pub fn borrow(&self) -> &str {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -70,9 +78,10 @@ LL | | }
= help: consider implementing the trait `std::borrow::Borrow` or choosing a less ambiguous method name
error: method `borrow_mut` can be confused for the standard trait method `std::borrow::BorrowMut::borrow_mut`
- --> $DIR/method_list_1.rs:53:5
+ --> $DIR/method_list_1.rs:60:5
|
LL | / pub fn borrow_mut(&mut self) -> &mut str {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -80,9 +89,10 @@ LL | | }
= help: consider implementing the trait `std::borrow::BorrowMut` or choosing a less ambiguous method name
error: method `clone` can be confused for the standard trait method `std::clone::Clone::clone`
- --> $DIR/method_list_1.rs:57:5
+ --> $DIR/method_list_1.rs:65:5
|
LL | / pub fn clone(&self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -90,9 +100,10 @@ LL | | }
= help: consider implementing the trait `std::clone::Clone` or choosing a less ambiguous method name
error: method `cmp` can be confused for the standard trait method `std::cmp::Ord::cmp`
- --> $DIR/method_list_1.rs:61:5
+ --> $DIR/method_list_1.rs:70:5
|
LL | / pub fn cmp(&self, other: &Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -100,9 +111,10 @@ LL | | }
= help: consider implementing the trait `std::cmp::Ord` or choosing a less ambiguous method name
error: method `default` can be confused for the standard trait method `std::default::Default::default`
- --> $DIR/method_list_1.rs:65:5
+ --> $DIR/method_list_1.rs:75:5
|
LL | / pub fn default() -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -110,9 +122,10 @@ LL | | }
= help: consider implementing the trait `std::default::Default` or choosing a less ambiguous method name
error: method `deref` can be confused for the standard trait method `std::ops::Deref::deref`
- --> $DIR/method_list_1.rs:69:5
+ --> $DIR/method_list_1.rs:80:5
|
LL | / pub fn deref(&self) -> &Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -120,9 +133,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Deref` or choosing a less ambiguous method name
error: method `deref_mut` can be confused for the standard trait method `std::ops::DerefMut::deref_mut`
- --> $DIR/method_list_1.rs:73:5
+ --> $DIR/method_list_1.rs:85:5
|
LL | / pub fn deref_mut(&mut self) -> &mut Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -130,9 +144,10 @@ LL | | }
= help: consider implementing the trait `std::ops::DerefMut` or choosing a less ambiguous method name
error: method `div` can be confused for the standard trait method `std::ops::Div::div`
- --> $DIR/method_list_1.rs:77:5
+ --> $DIR/method_list_1.rs:90:5
|
LL | / pub fn div(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -140,9 +155,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Div` or choosing a less ambiguous method name
error: method `drop` can be confused for the standard trait method `std::ops::Drop::drop`
- --> $DIR/method_list_1.rs:81:5
+ --> $DIR/method_list_1.rs:95:5
|
LL | / pub fn drop(&mut self) {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs
index 3efec1c52..33211b32d 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs
@@ -10,7 +10,7 @@
clippy::missing_panics_doc,
clippy::return_self_not_must_use
)]
-
+//@no-rustfix
use std::ops::Mul;
use std::rc::{self, Rc};
use std::sync::{self, Arc};
@@ -24,62 +24,77 @@ impl T {
// *****************************************
pub fn eq(&self, other: &Self) -> bool {
+ //~^ ERROR: method `eq` can be confused for the standard trait method `std::cmp::Parti
unimplemented!()
}
pub fn from_iter<T>(iter: T) -> Self {
+ //~^ ERROR: method `from_iter` can be confused for the standard trait method `std::ite
unimplemented!()
}
pub fn from_str(s: &str) -> Result<Self, Self> {
+ //~^ ERROR: method `from_str` can be confused for the standard trait method `std::str:
unimplemented!()
}
pub fn hash(&self, state: &mut T) {
+ //~^ ERROR: method `hash` can be confused for the standard trait method `std::hash::Ha
unimplemented!()
}
pub fn index(&self, index: usize) -> &Self {
+ //~^ ERROR: method `index` can be confused for the standard trait method `std::ops::In
unimplemented!()
}
pub fn index_mut(&mut self, index: usize) -> &mut Self {
+ //~^ ERROR: method `index_mut` can be confused for the standard trait method `std::ops
unimplemented!()
}
pub fn into_iter(self) -> Self {
+ //~^ ERROR: method `into_iter` can be confused for the standard trait method `std::ite
unimplemented!()
}
pub fn mul(self, rhs: Self) -> Self {
+ //~^ ERROR: method `mul` can be confused for the standard trait method `std::ops::Mul:
unimplemented!()
}
pub fn neg(self) -> Self {
+ //~^ ERROR: method `neg` can be confused for the standard trait method `std::ops::Neg:
unimplemented!()
}
pub fn next(&mut self) -> Option<Self> {
+ //~^ ERROR: method `next` can be confused for the standard trait method `std::iter::It
unimplemented!()
}
pub fn not(self) -> Self {
+ //~^ ERROR: method `not` can be confused for the standard trait method `std::ops::Not:
unimplemented!()
}
pub fn rem(self, rhs: Self) -> Self {
+ //~^ ERROR: method `rem` can be confused for the standard trait method `std::ops::Rem:
unimplemented!()
}
pub fn shl(self, rhs: Self) -> Self {
+ //~^ ERROR: method `shl` can be confused for the standard trait method `std::ops::Shl:
unimplemented!()
}
pub fn shr(self, rhs: Self) -> Self {
+ //~^ ERROR: method `shr` can be confused for the standard trait method `std::ops::Shr:
unimplemented!()
}
pub fn sub(self, rhs: Self) -> Self {
+ //~^ ERROR: method `sub` can be confused for the standard trait method `std::ops::Sub:
unimplemented!()
}
// **********
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
index 10bfea68f..c257f4113 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
@@ -2,17 +2,20 @@ error: method `eq` can be confused for the standard trait method `std::cmp::Part
--> $DIR/method_list_2.rs:26:5
|
LL | / pub fn eq(&self, other: &Self) -> bool {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
|
= help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name
= note: `-D clippy::should-implement-trait` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]`
error: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter`
- --> $DIR/method_list_2.rs:30:5
+ --> $DIR/method_list_2.rs:31:5
|
LL | / pub fn from_iter<T>(iter: T) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -20,9 +23,10 @@ LL | | }
= help: consider implementing the trait `std::iter::FromIterator` or choosing a less ambiguous method name
error: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
- --> $DIR/method_list_2.rs:34:5
+ --> $DIR/method_list_2.rs:36:5
|
LL | / pub fn from_str(s: &str) -> Result<Self, Self> {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -30,9 +34,10 @@ LL | | }
= help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
error: method `hash` can be confused for the standard trait method `std::hash::Hash::hash`
- --> $DIR/method_list_2.rs:38:5
+ --> $DIR/method_list_2.rs:41:5
|
LL | / pub fn hash(&self, state: &mut T) {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -40,9 +45,10 @@ LL | | }
= help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name
error: method `index` can be confused for the standard trait method `std::ops::Index::index`
- --> $DIR/method_list_2.rs:42:5
+ --> $DIR/method_list_2.rs:46:5
|
LL | / pub fn index(&self, index: usize) -> &Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -50,9 +56,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name
error: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut`
- --> $DIR/method_list_2.rs:46:5
+ --> $DIR/method_list_2.rs:51:5
|
LL | / pub fn index_mut(&mut self, index: usize) -> &mut Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -60,9 +67,10 @@ LL | | }
= help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name
error: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`
- --> $DIR/method_list_2.rs:50:5
+ --> $DIR/method_list_2.rs:56:5
|
LL | / pub fn into_iter(self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -70,9 +78,10 @@ LL | | }
= help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name
error: method `mul` can be confused for the standard trait method `std::ops::Mul::mul`
- --> $DIR/method_list_2.rs:54:5
+ --> $DIR/method_list_2.rs:61:5
|
LL | / pub fn mul(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -80,9 +89,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name
error: method `neg` can be confused for the standard trait method `std::ops::Neg::neg`
- --> $DIR/method_list_2.rs:58:5
+ --> $DIR/method_list_2.rs:66:5
|
LL | / pub fn neg(self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -90,9 +100,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name
error: method `next` can be confused for the standard trait method `std::iter::Iterator::next`
- --> $DIR/method_list_2.rs:62:5
+ --> $DIR/method_list_2.rs:71:5
|
LL | / pub fn next(&mut self) -> Option<Self> {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -100,9 +111,10 @@ LL | | }
= help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name
error: method `not` can be confused for the standard trait method `std::ops::Not::not`
- --> $DIR/method_list_2.rs:66:5
+ --> $DIR/method_list_2.rs:76:5
|
LL | / pub fn not(self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -110,9 +122,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name
error: method `rem` can be confused for the standard trait method `std::ops::Rem::rem`
- --> $DIR/method_list_2.rs:70:5
+ --> $DIR/method_list_2.rs:81:5
|
LL | / pub fn rem(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -120,9 +133,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name
error: method `shl` can be confused for the standard trait method `std::ops::Shl::shl`
- --> $DIR/method_list_2.rs:74:5
+ --> $DIR/method_list_2.rs:86:5
|
LL | / pub fn shl(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -130,9 +144,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name
error: method `shr` can be confused for the standard trait method `std::ops::Shr::shr`
- --> $DIR/method_list_2.rs:78:5
+ --> $DIR/method_list_2.rs:91:5
|
LL | / pub fn shr(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
@@ -140,9 +155,10 @@ LL | | }
= help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name
error: method `sub` can be confused for the standard trait method `std::ops::Sub::sub`
- --> $DIR/method_list_2.rs:82:5
+ --> $DIR/method_list_2.rs:96:5
|
LL | / pub fn sub(self, rhs: Self) -> Self {
+LL | |
LL | | unimplemented!()
LL | | }
| |_____^
diff --git a/src/tools/clippy/tests/ui/should_panic_without_expect.rs b/src/tools/clippy/tests/ui/should_panic_without_expect.rs
new file mode 100644
index 000000000..b554fdaf2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/should_panic_without_expect.rs
@@ -0,0 +1,21 @@
+//@no-rustfix
+#![deny(clippy::should_panic_without_expect)]
+
+#[test]
+#[should_panic]
+fn no_message() {}
+
+#[test]
+#[should_panic]
+#[cfg(not(test))]
+fn no_message_cfg_false() {}
+
+#[test]
+#[should_panic = "message"]
+fn metastr() {}
+
+#[test]
+#[should_panic(expected = "message")]
+fn metalist() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/should_panic_without_expect.stderr b/src/tools/clippy/tests/ui/should_panic_without_expect.stderr
new file mode 100644
index 000000000..dfcef52a9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/should_panic_without_expect.stderr
@@ -0,0 +1,14 @@
+error: #[should_panic] attribute without a reason
+ --> $DIR/should_panic_without_expect.rs:5:1
+ |
+LL | #[should_panic]
+ | ^^^^^^^^^^^^^^^ help: consider specifying the expected panic: `#[should_panic(expected = /* panic message */)]`
+ |
+note: the lint level is defined here
+ --> $DIR/should_panic_without_expect.rs:2:9
+ |
+LL | #![deny(clippy::should_panic_without_expect)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.fixed b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.fixed
deleted file mode 100644
index acc78d6bb..000000000
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.fixed
+++ /dev/null
@@ -1,627 +0,0 @@
-// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934
-// //@run-rustfix
-#![warn(clippy::significant_drop_in_scrutinee)]
-#![allow(dead_code, unused_assignments)]
-#![allow(clippy::match_single_binding, clippy::single_match, clippy::uninlined_format_args)]
-
-use std::num::ParseIntError;
-use std::ops::Deref;
-use std::sync::atomic::{AtomicU64, Ordering};
-use std::sync::RwLock;
-use std::sync::{Mutex, MutexGuard};
-
-struct State {}
-
-impl State {
- fn foo(&self) -> bool {
- true
- }
-
- fn bar(&self) {}
-}
-
-fn should_not_trigger_lint_with_mutex_guard_outside_match() {
- let mutex = Mutex::new(State {});
-
- // Should not trigger lint because the temporary should drop at the `;` on line before the match
- let is_foo = mutex.lock().unwrap().foo();
- match is_foo {
- true => {
- mutex.lock().unwrap().bar();
- },
- false => {},
- };
-}
-
-fn should_not_trigger_lint_with_mutex_guard_when_taking_ownership_in_match() {
- let mutex = Mutex::new(State {});
-
- // Should not trigger lint because the scrutinee is explicitly returning the MutexGuard,
- // so its lifetime should not be surprising.
- match mutex.lock() {
- Ok(guard) => {
- guard.foo();
- mutex.lock().unwrap().bar();
- },
- _ => {},
- };
-}
-
-fn should_trigger_lint_with_mutex_guard_in_match_scrutinee() {
- let mutex = Mutex::new(State {});
-
- // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it
- // is preserved until the end of the match, but there is no clear indication that this is the
- // case.
- match mutex.lock().unwrap().foo() {
- true => {
- mutex.lock().unwrap().bar();
- },
- false => {},
- };
-}
-
-fn should_not_trigger_lint_with_mutex_guard_in_match_scrutinee_when_lint_allowed() {
- let mutex = Mutex::new(State {});
-
- // Lint should not be triggered because it is "allowed" below.
- #[allow(clippy::significant_drop_in_scrutinee)]
- match mutex.lock().unwrap().foo() {
- true => {
- mutex.lock().unwrap().bar();
- },
- false => {},
- };
-}
-
-fn should_not_trigger_lint_for_insignificant_drop() {
- // Should not trigger lint because there are no temporaries whose drops have a significant
- // side effect.
- match 1u64.to_string().is_empty() {
- true => {
- println!("It was empty")
- },
- false => {
- println!("It was not empty")
- },
- }
-}
-
-struct StateWithMutex {
- m: Mutex<u64>,
-}
-
-struct MutexGuardWrapper<'a> {
- mg: MutexGuard<'a, u64>,
-}
-
-impl<'a> MutexGuardWrapper<'a> {
- fn get_the_value(&self) -> u64 {
- *self.mg.deref()
- }
-}
-
-struct MutexGuardWrapperWrapper<'a> {
- mg: MutexGuardWrapper<'a>,
-}
-
-impl<'a> MutexGuardWrapperWrapper<'a> {
- fn get_the_value(&self) -> u64 {
- *self.mg.mg.deref()
- }
-}
-
-impl StateWithMutex {
- fn lock_m(&self) -> MutexGuardWrapper<'_> {
- MutexGuardWrapper {
- mg: self.m.lock().unwrap(),
- }
- }
-
- fn lock_m_m(&self) -> MutexGuardWrapperWrapper<'_> {
- MutexGuardWrapperWrapper {
- mg: MutexGuardWrapper {
- mg: self.m.lock().unwrap(),
- },
- }
- }
-
- fn foo(&self) -> bool {
- true
- }
-
- fn bar(&self) {}
-}
-
-fn should_trigger_lint_with_wrapped_mutex() {
- let s = StateWithMutex { m: Mutex::new(1) };
-
- // Should trigger lint because a temporary contains a type with a significant drop and its
- // lifetime is not obvious. Additionally, it is not obvious from looking at the scrutinee that
- // the temporary contains such a type, making it potentially even more surprising.
- match s.lock_m().get_the_value() {
- 1 => {
- println!("Got 1. Is it still 1?");
- println!("{}", s.lock_m().get_the_value());
- },
- 2 => {
- println!("Got 2. Is it still 2?");
- println!("{}", s.lock_m().get_the_value());
- },
- _ => {},
- }
- println!("All done!");
-}
-
-fn should_trigger_lint_with_double_wrapped_mutex() {
- let s = StateWithMutex { m: Mutex::new(1) };
-
- // Should trigger lint because a temporary contains a type which further contains a type with a
- // significant drop and its lifetime is not obvious. Additionally, it is not obvious from
- // looking at the scrutinee that the temporary contains such a type, making it potentially even
- // more surprising.
- match s.lock_m_m().get_the_value() {
- 1 => {
- println!("Got 1. Is it still 1?");
- println!("{}", s.lock_m().get_the_value());
- },
- 2 => {
- println!("Got 2. Is it still 2?");
- println!("{}", s.lock_m().get_the_value());
- },
- _ => {},
- }
- println!("All done!");
-}
-
-struct Counter {
- i: AtomicU64,
-}
-
-#[clippy::has_significant_drop]
-struct CounterWrapper<'a> {
- counter: &'a Counter,
-}
-
-impl<'a> CounterWrapper<'a> {
- fn new(counter: &Counter) -> CounterWrapper {
- counter.i.fetch_add(1, Ordering::Relaxed);
- CounterWrapper { counter }
- }
-}
-
-impl<'a> Drop for CounterWrapper<'a> {
- fn drop(&mut self) {
- self.counter.i.fetch_sub(1, Ordering::Relaxed);
- }
-}
-
-impl Counter {
- fn temp_increment(&self) -> Vec<CounterWrapper> {
- vec![CounterWrapper::new(self), CounterWrapper::new(self)]
- }
-}
-
-fn should_trigger_lint_for_vec() {
- let counter = Counter { i: AtomicU64::new(0) };
-
- // Should trigger lint because the temporary in the scrutinee returns a collection of types
- // which have significant drops. The types with significant drops are also non-obvious when
- // reading the expression in the scrutinee.
- match counter.temp_increment().len() {
- 2 => {
- let current_count = counter.i.load(Ordering::Relaxed);
- println!("Current count {}", current_count);
- assert_eq!(current_count, 0);
- },
- 1 => {},
- 3 => {},
- _ => {},
- };
-}
-
-struct StateWithField {
- s: String,
-}
-
-// Should trigger lint only on the type in the tuple which is created using a temporary
-// with a significant drop. Additionally, this test ensures that the format of the tuple
-// is preserved correctly in the suggestion.
-fn should_trigger_lint_for_tuple_in_scrutinee() {
- let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() });
-
- {
- match (mutex1.lock().unwrap().s.len(), true) {
- (3, _) => {
- println!("started");
- mutex1.lock().unwrap().s.len();
- println!("done");
- },
- (_, _) => {},
- };
-
- match (true, mutex1.lock().unwrap().s.len(), true) {
- (_, 3, _) => {
- println!("started");
- mutex1.lock().unwrap().s.len();
- println!("done");
- },
- (_, _, _) => {},
- };
-
- let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() });
- match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
- (3, _, 3) => {
- println!("started");
- mutex1.lock().unwrap().s.len();
- mutex2.lock().unwrap().s.len();
- println!("done");
- },
- (_, _, _) => {},
- };
-
- let mutex3 = Mutex::new(StateWithField { s: "three".to_owned() });
- match mutex3.lock().unwrap().s.as_str() {
- "three" => {
- println!("started");
- mutex1.lock().unwrap().s.len();
- mutex2.lock().unwrap().s.len();
- println!("done");
- },
- _ => {},
- };
-
- match (true, mutex3.lock().unwrap().s.as_str()) {
- (_, "three") => {
- println!("started");
- mutex1.lock().unwrap().s.len();
- mutex2.lock().unwrap().s.len();
- println!("done");
- },
- (_, _) => {},
- };
- }
-}
-
-// Should trigger lint when either side of a binary operation creates a temporary with a
-// significant drop.
-// To avoid potential unnecessary copies or creating references that would trigger the significant
-// drop problem, the lint recommends moving the entire binary operation.
-fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() {
- let mutex = Mutex::new(StateWithField { s: "state".to_owned() });
-
- match mutex.lock().unwrap().s.len() > 1 {
- true => {
- mutex.lock().unwrap().s.len();
- },
- false => {},
- };
-
- match 1 < mutex.lock().unwrap().s.len() {
- true => {
- mutex.lock().unwrap().s.len();
- },
- false => {},
- };
-}
-
-// Should trigger lint when both sides of a binary operation creates a temporary with a
-// significant drop.
-// To avoid potential unnecessary copies or creating references that would trigger the significant
-// drop problem, the lint recommends moving the entire binary operation.
-fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op() {
- let mutex1 = Mutex::new(StateWithField { s: "state".to_owned() });
- let mutex2 = Mutex::new(StateWithField {
- s: "statewithfield".to_owned(),
- });
-
- match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
- true => {
- println!(
- "{} < {}",
- mutex1.lock().unwrap().s.len(),
- mutex2.lock().unwrap().s.len()
- );
- },
- false => {},
- };
-
- match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
- true => {
- println!(
- "{} >= {}",
- mutex1.lock().unwrap().s.len(),
- mutex2.lock().unwrap().s.len()
- );
- },
- false => {},
- };
-}
-
-fn should_not_trigger_lint_for_closure_in_scrutinee() {
- let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() });
-
- let get_mutex_guard = || mutex1.lock().unwrap().s.len();
-
- // Should not trigger lint because the temporary with a significant drop will be dropped
- // at the end of the closure, so the MutexGuard will be unlocked and not have a potentially
- // surprising lifetime.
- match get_mutex_guard() > 1 {
- true => {
- mutex1.lock().unwrap().s.len();
- },
- false => {},
- };
-}
-
-fn should_trigger_lint_for_return_from_closure_in_scrutinee() {
- let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() });
-
- let get_mutex_guard = || mutex1.lock().unwrap();
-
- // Should trigger lint because the temporary with a significant drop is returned from the
- // closure but not used directly in any match arms, so it has a potentially surprising lifetime.
- match get_mutex_guard().s.len() > 1 {
- true => {
- mutex1.lock().unwrap().s.len();
- },
- false => {},
- };
-}
-
-fn should_trigger_lint_for_return_from_match_in_scrutinee() {
- let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() });
- let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() });
-
- let i = 100;
-
- // Should trigger lint because the nested match within the scrutinee returns a temporary with a
- // significant drop is but not used directly in any match arms, so it has a potentially
- // surprising lifetime.
- match match i {
- 100 => mutex1.lock().unwrap(),
- _ => mutex2.lock().unwrap(),
- }
- .s
- .len()
- > 1
- {
- true => {
- mutex1.lock().unwrap().s.len();
- },
- false => {
- println!("nothing to do here");
- },
- };
-}
-
-fn should_trigger_lint_for_return_from_if_in_scrutinee() {
- let mutex1 = Mutex::new(StateWithField { s: "one".to_owned() });
- let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() });
-
- let i = 100;
-
- // Should trigger lint because the nested if-expression within the scrutinee returns a temporary
- // with a significant drop is but not used directly in any match arms, so it has a potentially
- // surprising lifetime.
- match if i > 1 {
- mutex1.lock().unwrap()
- } else {
- mutex2.lock().unwrap()
- }
- .s
- .len()
- > 1
- {
- true => {
- mutex1.lock().unwrap().s.len();
- },
- false => {},
- };
-}
-
-fn should_not_trigger_lint_for_if_in_scrutinee() {
- let mutex = Mutex::new(StateWithField { s: "state".to_owned() });
-
- let i = 100;
-
- // Should not trigger the lint because the temporary with a significant drop *is* dropped within
- // the body of the if-expression nested within the match scrutinee, and therefore does not have
- // a potentially surprising lifetime.
- match if i > 1 {
- mutex.lock().unwrap().s.len() > 1
- } else {
- false
- } {
- true => {
- mutex.lock().unwrap().s.len();
- },
- false => {},
- };
-}
-
-struct StateWithBoxedMutexGuard {
- u: Mutex<u64>,
-}
-
-impl StateWithBoxedMutexGuard {
- fn new() -> StateWithBoxedMutexGuard {
- StateWithBoxedMutexGuard { u: Mutex::new(42) }
- }
- fn lock(&self) -> Box<MutexGuard<u64>> {
- Box::new(self.u.lock().unwrap())
- }
-}
-
-fn should_trigger_lint_for_boxed_mutex_guard() {
- let s = StateWithBoxedMutexGuard::new();
-
- // Should trigger lint because a temporary Box holding a type with a significant drop in a match
- // scrutinee may have a potentially surprising lifetime.
- match s.lock().deref().deref() {
- 0 | 1 => println!("Value was less than 2"),
- _ => println!("Value is {}", s.lock().deref()),
- };
-}
-
-struct StateStringWithBoxedMutexGuard {
- s: Mutex<String>,
-}
-
-impl StateStringWithBoxedMutexGuard {
- fn new() -> StateStringWithBoxedMutexGuard {
- StateStringWithBoxedMutexGuard {
- s: Mutex::new("A String".to_owned()),
- }
- }
- fn lock(&self) -> Box<MutexGuard<String>> {
- Box::new(self.s.lock().unwrap())
- }
-}
-
-fn should_trigger_lint_for_boxed_mutex_guard_holding_string() {
- let s = StateStringWithBoxedMutexGuard::new();
-
- let matcher = String::from("A String");
-
- // Should trigger lint because a temporary Box holding a type with a significant drop in a match
- // scrutinee may have a potentially surprising lifetime.
- match s.lock().deref().deref() {
- matcher => println!("Value is {}", s.lock().deref()),
- _ => println!("Value was not a match"),
- };
-}
-
-struct StateWithIntField {
- i: u64,
-}
-
-// Should trigger lint when either side of an assign expression contains a temporary with a
-// significant drop, because the temporary's lifetime will be extended to the end of the match.
-// To avoid potential unnecessary copies or creating references that would trigger the significant
-// drop problem, the lint recommends moving the entire binary operation.
-fn should_trigger_lint_in_assign_expr() {
- let mutex = Mutex::new(StateWithIntField { i: 10 });
-
- let mut i = 100;
-
- match mutex.lock().unwrap().i = i {
- _ => {
- println!("{}", mutex.lock().unwrap().i);
- },
- };
-
- match i = mutex.lock().unwrap().i {
- _ => {
- println!("{}", mutex.lock().unwrap().i);
- },
- };
-
- match mutex.lock().unwrap().i += 1 {
- _ => {
- println!("{}", mutex.lock().unwrap().i);
- },
- };
-
- match i += mutex.lock().unwrap().i {
- _ => {
- println!("{}", mutex.lock().unwrap().i);
- },
- };
-}
-
-#[derive(Debug)]
-enum RecursiveEnum {
- Foo(Option<Box<RecursiveEnum>>),
-}
-
-#[derive(Debug)]
-enum GenericRecursiveEnum<T> {
- Foo(T, Option<Box<GenericRecursiveEnum<T>>>),
-}
-
-fn should_not_cause_stack_overflow() {
- // Test that when a type recursively contains itself, a stack overflow does not occur when
- // checking sub-types for significant drops.
- let f = RecursiveEnum::Foo(Some(Box::new(RecursiveEnum::Foo(None))));
- match f {
- RecursiveEnum::Foo(Some(f)) => {
- println!("{:?}", f)
- },
- RecursiveEnum::Foo(f) => {
- println!("{:?}", f)
- },
- }
-
- let f = GenericRecursiveEnum::Foo(1u64, Some(Box::new(GenericRecursiveEnum::Foo(2u64, None))));
- match f {
- GenericRecursiveEnum::Foo(i, Some(f)) => {
- println!("{} {:?}", i, f)
- },
- GenericRecursiveEnum::Foo(i, f) => {
- println!("{} {:?}", i, f)
- },
- }
-}
-
-fn should_not_produce_lint_for_try_desugar() -> Result<u64, ParseIntError> {
- // TryDesugar (i.e. using `?` for a Result type) will turn into a match but is out of scope
- // for this lint
- let rwlock = RwLock::new("1".to_string());
- let result = rwlock.read().unwrap().parse::<u64>()?;
- println!("{}", result);
- rwlock.write().unwrap().push('2');
- Ok(result)
-}
-
-struct ResultReturner {
- s: String,
-}
-
-impl ResultReturner {
- fn to_number(&self) -> Result<i64, ParseIntError> {
- self.s.parse::<i64>()
- }
-}
-
-fn should_trigger_lint_for_non_ref_move_and_clone_suggestion() {
- let rwlock = RwLock::<ResultReturner>::new(ResultReturner { s: "1".to_string() });
- match rwlock.read().unwrap().to_number() {
- Ok(n) => println!("Converted to number: {}", n),
- Err(e) => println!("Could not convert {} to number", e),
- };
-}
-
-fn should_trigger_lint_for_read_write_lock_for_loop() {
- // For-in loops desugar to match expressions and are prone to the type of deadlock this lint is
- // designed to look for.
- let rwlock = RwLock::<Vec<String>>::new(vec!["1".to_string()]);
- for s in rwlock.read().unwrap().iter() {
- println!("{}", s);
- }
-}
-
-fn do_bar(mutex: &Mutex<State>) {
- mutex.lock().unwrap().bar();
-}
-
-fn should_trigger_lint_without_significant_drop_in_arm() {
- let mutex = Mutex::new(State {});
-
- // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it
- // is preserved until the end of the match, but there is no clear indication that this is the
- // case.
- match mutex.lock().unwrap().foo() {
- true => do_bar(&mutex),
- false => {},
- };
-}
-
-fn should_not_trigger_on_significant_iterator_drop() {
- let lines = std::io::stdin().lines();
- for line in lines {
- println!("foo: {}", line.unwrap());
- }
-}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
index 17df9f88f..0305d895f 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
@@ -1,5 +1,5 @@
// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934
-//
+//@no-rustfix
#![warn(clippy::significant_drop_in_scrutinee)]
#![allow(dead_code, unused_assignments)]
#![allow(clippy::match_single_binding, clippy::single_match, clippy::uninlined_format_args)]
@@ -53,6 +53,8 @@ fn should_trigger_lint_with_mutex_guard_in_match_scrutinee() {
// is preserved until the end of the match, but there is no clear indication that this is the
// case.
match mutex.lock().unwrap().foo() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
true => {
mutex.lock().unwrap().bar();
},
@@ -139,6 +141,8 @@ fn should_trigger_lint_with_wrapped_mutex() {
// lifetime is not obvious. Additionally, it is not obvious from looking at the scrutinee that
// the temporary contains such a type, making it potentially even more surprising.
match s.lock_m().get_the_value() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
1 => {
println!("Got 1. Is it still 1?");
println!("{}", s.lock_m().get_the_value());
@@ -160,6 +164,8 @@ fn should_trigger_lint_with_double_wrapped_mutex() {
// looking at the scrutinee that the temporary contains such a type, making it potentially even
// more surprising.
match s.lock_m_m().get_the_value() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
1 => {
println!("Got 1. Is it still 1?");
println!("{}", s.lock_m().get_the_value());
@@ -208,6 +214,8 @@ fn should_trigger_lint_for_vec() {
// which have significant drops. The types with significant drops are also non-obvious when
// reading the expression in the scrutinee.
match counter.temp_increment().len() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
2 => {
let current_count = counter.i.load(Ordering::Relaxed);
println!("Current count {}", current_count);
@@ -231,6 +239,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() {
{
match (mutex1.lock().unwrap().s.len(), true) {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
(3, _) => {
println!("started");
mutex1.lock().unwrap().s.len();
@@ -240,6 +250,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() {
};
match (true, mutex1.lock().unwrap().s.len(), true) {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
(_, 3, _) => {
println!("started");
mutex1.lock().unwrap().s.len();
@@ -250,6 +262,10 @@ fn should_trigger_lint_for_tuple_in_scrutinee() {
let mutex2 = Mutex::new(StateWithField { s: "two".to_owned() });
match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
+ //~| ERROR: temporary with significant `Drop` in `match` scrutinee will live until
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
(3, _, 3) => {
println!("started");
mutex1.lock().unwrap().s.len();
@@ -261,6 +277,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() {
let mutex3 = Mutex::new(StateWithField { s: "three".to_owned() });
match mutex3.lock().unwrap().s.as_str() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
"three" => {
println!("started");
mutex1.lock().unwrap().s.len();
@@ -271,6 +289,8 @@ fn should_trigger_lint_for_tuple_in_scrutinee() {
};
match (true, mutex3.lock().unwrap().s.as_str()) {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
(_, "three") => {
println!("started");
mutex1.lock().unwrap().s.len();
@@ -290,6 +310,8 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() {
let mutex = Mutex::new(StateWithField { s: "state".to_owned() });
match mutex.lock().unwrap().s.len() > 1 {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
true => {
mutex.lock().unwrap().s.len();
},
@@ -297,6 +319,8 @@ fn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() {
};
match 1 < mutex.lock().unwrap().s.len() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
true => {
mutex.lock().unwrap().s.len();
},
@@ -315,6 +339,8 @@ fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op(
});
match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
true => {
println!(
"{} < {}",
@@ -326,6 +352,8 @@ fn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op(
};
match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
true => {
println!(
"{} >= {}",
@@ -361,6 +389,8 @@ fn should_trigger_lint_for_return_from_closure_in_scrutinee() {
// Should trigger lint because the temporary with a significant drop is returned from the
// closure but not used directly in any match arms, so it has a potentially surprising lifetime.
match get_mutex_guard().s.len() > 1 {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
true => {
mutex1.lock().unwrap().s.len();
},
@@ -378,6 +408,8 @@ fn should_trigger_lint_for_return_from_match_in_scrutinee() {
// significant drop is but not used directly in any match arms, so it has a potentially
// surprising lifetime.
match match i {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
100 => mutex1.lock().unwrap(),
_ => mutex2.lock().unwrap(),
}
@@ -404,6 +436,8 @@ fn should_trigger_lint_for_return_from_if_in_scrutinee() {
// with a significant drop is but not used directly in any match arms, so it has a potentially
// surprising lifetime.
match if i > 1 {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
mutex1.lock().unwrap()
} else {
mutex2.lock().unwrap()
@@ -458,6 +492,8 @@ fn should_trigger_lint_for_boxed_mutex_guard() {
// Should trigger lint because a temporary Box holding a type with a significant drop in a match
// scrutinee may have a potentially surprising lifetime.
match s.lock().deref().deref() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
0 | 1 => println!("Value was less than 2"),
_ => println!("Value is {}", s.lock().deref()),
};
@@ -486,6 +522,8 @@ fn should_trigger_lint_for_boxed_mutex_guard_holding_string() {
// Should trigger lint because a temporary Box holding a type with a significant drop in a match
// scrutinee may have a potentially surprising lifetime.
match s.lock().deref().deref() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
matcher => println!("Value is {}", s.lock().deref()),
_ => println!("Value was not a match"),
};
@@ -505,24 +543,32 @@ fn should_trigger_lint_in_assign_expr() {
let mut i = 100;
match mutex.lock().unwrap().i = i {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
_ => {
println!("{}", mutex.lock().unwrap().i);
},
};
match i = mutex.lock().unwrap().i {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
_ => {
println!("{}", mutex.lock().unwrap().i);
},
};
match mutex.lock().unwrap().i += 1 {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
_ => {
println!("{}", mutex.lock().unwrap().i);
},
};
match i += mutex.lock().unwrap().i {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
_ => {
println!("{}", mutex.lock().unwrap().i);
},
@@ -586,6 +632,8 @@ impl ResultReturner {
fn should_trigger_lint_for_non_ref_move_and_clone_suggestion() {
let rwlock = RwLock::<ResultReturner>::new(ResultReturner { s: "1".to_string() });
match rwlock.read().unwrap().to_number() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
Ok(n) => println!("Converted to number: {}", n),
Err(e) => println!("Could not convert {} to number", e),
};
@@ -596,6 +644,8 @@ fn should_trigger_lint_for_read_write_lock_for_loop() {
// designed to look for.
let rwlock = RwLock::<Vec<String>>::new(vec!["1".to_string()]);
for s in rwlock.read().unwrap().iter() {
+ //~^ ERROR: temporary with significant `Drop` in `for` loop condition will live until
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
println!("{}", s);
}
}
@@ -611,6 +661,8 @@ fn should_trigger_lint_without_significant_drop_in_arm() {
// is preserved until the end of the match, but there is no clear indication that this is the
// case.
match mutex.lock().unwrap().foo() {
+ //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+ //~| NOTE: this might lead to deadlocks or other unexpected behavior
true => do_bar(&mutex),
false => {},
};
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
index b56ace200..05bfda547 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
@@ -3,7 +3,7 @@ error: temporary with significant `Drop` in `match` scrutinee will live until th
|
LL | match mutex.lock().unwrap().foo() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | true => {
+...
LL | mutex.lock().unwrap().bar();
| --------------------- another value with significant `Drop` created here
...
@@ -12,6 +12,7 @@ LL | };
|
= note: this might lead to deadlocks or other unexpected behavior
= note: `-D clippy::significant-drop-in-scrutinee` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::significant_drop_in_scrutinee)]`
help: try moving the temporary above the match
|
LL ~ let value = mutex.lock().unwrap().foo();
@@ -19,7 +20,7 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:141:11
+ --> $DIR/significant_drop_in_scrutinee.rs:143:11
|
LL | match s.lock_m().get_the_value() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -38,7 +39,7 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:162:11
+ --> $DIR/significant_drop_in_scrutinee.rs:166:11
|
LL | match s.lock_m_m().get_the_value() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -57,7 +58,7 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:210:11
+ --> $DIR/significant_drop_in_scrutinee.rs:216:11
|
LL | match counter.temp_increment().len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +74,7 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:233:16
+ --> $DIR/significant_drop_in_scrutinee.rs:241:16
|
LL | match (mutex1.lock().unwrap().s.len(), true) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -92,7 +93,7 @@ LL ~ match (value, true) {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:242:22
+ --> $DIR/significant_drop_in_scrutinee.rs:252:22
|
LL | match (true, mutex1.lock().unwrap().s.len(), true) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -111,7 +112,7 @@ LL ~ match (true, value, true) {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:252:16
+ --> $DIR/significant_drop_in_scrutinee.rs:264:16
|
LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,7 +133,7 @@ LL ~ match (value, true, mutex2.lock().unwrap().s.len()) {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:252:54
+ --> $DIR/significant_drop_in_scrutinee.rs:264:54
|
LL | match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -153,7 +154,7 @@ LL ~ match (mutex1.lock().unwrap().s.len(), true, value) {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:263:15
+ --> $DIR/significant_drop_in_scrutinee.rs:279:15
|
LL | match mutex3.lock().unwrap().s.as_str() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -169,7 +170,7 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:273:22
+ --> $DIR/significant_drop_in_scrutinee.rs:291:22
|
LL | match (true, mutex3.lock().unwrap().s.as_str()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -185,11 +186,11 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:292:11
+ --> $DIR/significant_drop_in_scrutinee.rs:312:11
|
LL | match mutex.lock().unwrap().s.len() > 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | true => {
+...
LL | mutex.lock().unwrap().s.len();
| --------------------- another value with significant `Drop` created here
...
@@ -204,11 +205,11 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:299:11
+ --> $DIR/significant_drop_in_scrutinee.rs:321:11
|
LL | match 1 < mutex.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | true => {
+...
LL | mutex.lock().unwrap().s.len();
| --------------------- another value with significant `Drop` created here
...
@@ -223,7 +224,7 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:317:11
+ --> $DIR/significant_drop_in_scrutinee.rs:341:11
|
LL | match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -244,7 +245,7 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:328:11
+ --> $DIR/significant_drop_in_scrutinee.rs:354:11
|
LL | match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -265,11 +266,11 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:363:11
+ --> $DIR/significant_drop_in_scrutinee.rs:391:11
|
LL | match get_mutex_guard().s.len() > 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | true => {
+...
LL | mutex1.lock().unwrap().s.len();
| ---------------------- another value with significant `Drop` created here
...
@@ -284,14 +285,14 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:380:11
+ --> $DIR/significant_drop_in_scrutinee.rs:410:11
|
LL | match match i {
| ___________^
+LL | |
+LL | |
LL | | 100 => mutex1.lock().unwrap(),
-LL | | _ => mutex2.lock().unwrap(),
-LL | | }
-LL | | .s
+... |
LL | | .len()
LL | | > 1
| |___________^
@@ -306,6 +307,8 @@ LL | };
help: try moving the temporary above the match
|
LL ~ let value = match i {
+LL +
+LL +
LL + 100 => mutex1.lock().unwrap(),
LL + _ => mutex2.lock().unwrap(),
LL + }
@@ -316,13 +319,13 @@ LL ~ match value
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:406:11
+ --> $DIR/significant_drop_in_scrutinee.rs:438:11
|
LL | match if i > 1 {
| ___________^
+LL | |
+LL | |
LL | | mutex1.lock().unwrap()
-LL | | } else {
-LL | | mutex2.lock().unwrap()
... |
LL | | .len()
LL | | > 1
@@ -338,6 +341,8 @@ LL | };
help: try moving the temporary above the match
|
LL ~ let value = if i > 1 {
+LL +
+LL +
LL + mutex1.lock().unwrap()
LL + } else {
LL + mutex2.lock().unwrap()
@@ -349,11 +354,11 @@ LL ~ match value
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:460:11
+ --> $DIR/significant_drop_in_scrutinee.rs:494:11
|
LL | match s.lock().deref().deref() {
| ^^^^^^^^^^^^^^^^^^^^^^^^
-LL | 0 | 1 => println!("Value was less than 2"),
+...
LL | _ => println!("Value is {}", s.lock().deref()),
| ---------------- another value with significant `Drop` created here
LL | };
@@ -367,10 +372,11 @@ LL ~ match value {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:488:11
+ --> $DIR/significant_drop_in_scrutinee.rs:524:11
|
LL | match s.lock().deref().deref() {
| ^^^^^^^^^^^^^^^^^^^^^^^^
+...
LL | matcher => println!("Value is {}", s.lock().deref()),
| ---------------- another value with significant `Drop` created here
LL | _ => println!("Value was not a match"),
@@ -380,11 +386,11 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:507:11
+ --> $DIR/significant_drop_in_scrutinee.rs:545:11
|
LL | match mutex.lock().unwrap().i = i {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | _ => {
+...
LL | println!("{}", mutex.lock().unwrap().i);
| --------------------- another value with significant `Drop` created here
LL | },
@@ -399,11 +405,11 @@ LL ~ match () {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:513:11
+ --> $DIR/significant_drop_in_scrutinee.rs:553:11
|
LL | match i = mutex.lock().unwrap().i {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | _ => {
+...
LL | println!("{}", mutex.lock().unwrap().i);
| --------------------- another value with significant `Drop` created here
LL | },
@@ -418,11 +424,11 @@ LL ~ match () {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:519:11
+ --> $DIR/significant_drop_in_scrutinee.rs:561:11
|
LL | match mutex.lock().unwrap().i += 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | _ => {
+...
LL | println!("{}", mutex.lock().unwrap().i);
| --------------------- another value with significant `Drop` created here
LL | },
@@ -437,11 +443,11 @@ LL ~ match () {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:525:11
+ --> $DIR/significant_drop_in_scrutinee.rs:569:11
|
LL | match i += mutex.lock().unwrap().i {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | _ => {
+...
LL | println!("{}", mutex.lock().unwrap().i);
| --------------------- another value with significant `Drop` created here
LL | },
@@ -456,7 +462,7 @@ LL ~ match () {
|
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:588:11
+ --> $DIR/significant_drop_in_scrutinee.rs:634:11
|
LL | match rwlock.read().unwrap().to_number() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -467,18 +473,18 @@ LL | };
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
- --> $DIR/significant_drop_in_scrutinee.rs:598:14
+ --> $DIR/significant_drop_in_scrutinee.rs:646:14
|
LL | for s in rwlock.read().unwrap().iter() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | println!("{}", s);
+...
LL | }
| - temporary lives until here
|
= note: this might lead to deadlocks or other unexpected behavior
error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
- --> $DIR/significant_drop_in_scrutinee.rs:613:11
+ --> $DIR/significant_drop_in_scrutinee.rs:663:11
|
LL | match mutex.lock().unwrap().foo() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.fixed b/src/tools/clippy/tests/ui/significant_drop_tightening.fixed
index 8065e9e5f..ed05f6e0c 100644
--- a/src/tools/clippy/tests/ui/significant_drop_tightening.fixed
+++ b/src/tools/clippy/tests/ui/significant_drop_tightening.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::significant_drop_tightening)]
use std::sync::Mutex;
diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.rs b/src/tools/clippy/tests/ui/significant_drop_tightening.rs
index 1620b7684..e5f17278f 100644
--- a/src/tools/clippy/tests/ui/significant_drop_tightening.rs
+++ b/src/tools/clippy/tests/ui/significant_drop_tightening.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::significant_drop_tightening)]
use std::sync::Mutex;
diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
index b5cad88ad..6572d9969 100644
--- a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr
@@ -1,5 +1,5 @@
error: temporary with significant `Drop` can be early dropped
- --> $DIR/significant_drop_tightening.rs:12:9
+ --> $DIR/significant_drop_tightening.rs:10:9
|
LL | pub fn complex_return_triggers_the_lint() -> i32 {
| __________________________________________________-
@@ -16,6 +16,7 @@ LL | | }
|
= note: this might lead to unnecessary resource contention
= note: `-D clippy::significant-drop-tightening` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::significant_drop_tightening)]`
help: drop the temporary after the end of its last usage
|
LL ~ let _ = *lock;
@@ -23,7 +24,7 @@ LL + drop(lock);
|
error: temporary with significant `Drop` can be early dropped
- --> $DIR/significant_drop_tightening.rs:106:13
+ --> $DIR/significant_drop_tightening.rs:104:13
|
LL | / {
LL | | let mutex = Mutex::new(1i32);
@@ -43,7 +44,7 @@ LL + drop(lock);
|
error: temporary with significant `Drop` can be early dropped
- --> $DIR/significant_drop_tightening.rs:127:13
+ --> $DIR/significant_drop_tightening.rs:125:13
|
LL | / {
LL | | let mutex = Mutex::new(1i32);
@@ -67,7 +68,7 @@ LL +
|
error: temporary with significant `Drop` can be early dropped
- --> $DIR/significant_drop_tightening.rs:133:17
+ --> $DIR/significant_drop_tightening.rs:131:17
|
LL | / {
LL | | let mutex = Mutex::new(vec![1i32]);
diff --git a/src/tools/clippy/tests/ui/similar_names.rs b/src/tools/clippy/tests/ui/similar_names.rs
index c21225d15..f46af56c6 100644
--- a/src/tools/clippy/tests/ui/similar_names.rs
+++ b/src/tools/clippy/tests/ui/similar_names.rs
@@ -3,6 +3,7 @@
unused,
clippy::println_empty_string,
clippy::empty_loop,
+ clippy::never_loop,
clippy::diverging_sub_expression,
clippy::let_unit_value
)]
@@ -19,8 +20,10 @@ fn main() {
let apple: i32;
let bpple: i32;
+ //~^ ERROR: binding's name is too similar to existing binding
let cpple: i32;
+ //~^ ERROR: binding's name is too similar to existing binding
let a_bar: i32;
let b_bar: i32;
@@ -45,10 +48,12 @@ fn main() {
let blubx: i32;
let bluby: i32;
+ //~^ ERROR: binding's name is too similar to existing binding
let cake: i32;
let cakes: i32;
let coke: i32;
+ //~^ ERROR: binding's name is too similar to existing binding
match 5 {
cheese @ 1 => {},
@@ -67,10 +72,12 @@ fn main() {
let xyz1abc: i32;
let xyz2abc: i32;
let xyzeabc: i32;
+ //~^ ERROR: binding's name is too similar to existing binding
let parser: i32;
let parsed: i32;
let parsee: i32;
+ //~^ ERROR: binding's name is too similar to existing binding
let setter: i32;
let getter: i32;
@@ -92,6 +99,7 @@ fn foo() {
let Foo {
apple: spring,
bpple: sprang,
+ //~^ ERROR: binding's name is too similar to existing binding
} = unimplemented!();
}
diff --git a/src/tools/clippy/tests/ui/similar_names.stderr b/src/tools/clippy/tests/ui/similar_names.stderr
index 43c5cee4b..44ae3532a 100644
--- a/src/tools/clippy/tests/ui/similar_names.stderr
+++ b/src/tools/clippy/tests/ui/similar_names.stderr
@@ -1,84 +1,85 @@
error: binding's name is too similar to existing binding
- --> $DIR/similar_names.rs:21:9
+ --> $DIR/similar_names.rs:22:9
|
LL | let bpple: i32;
| ^^^^^
|
note: existing binding defined here
- --> $DIR/similar_names.rs:19:9
+ --> $DIR/similar_names.rs:20:9
|
LL | let apple: i32;
| ^^^^^
= note: `-D clippy::similar-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::similar_names)]`
error: binding's name is too similar to existing binding
- --> $DIR/similar_names.rs:23:9
+ --> $DIR/similar_names.rs:25:9
|
LL | let cpple: i32;
| ^^^^^
|
note: existing binding defined here
- --> $DIR/similar_names.rs:19:9
+ --> $DIR/similar_names.rs:20:9
|
LL | let apple: i32;
| ^^^^^
error: binding's name is too similar to existing binding
- --> $DIR/similar_names.rs:47:9
+ --> $DIR/similar_names.rs:50:9
|
LL | let bluby: i32;
| ^^^^^
|
note: existing binding defined here
- --> $DIR/similar_names.rs:46:9
+ --> $DIR/similar_names.rs:49:9
|
LL | let blubx: i32;
| ^^^^^
error: binding's name is too similar to existing binding
- --> $DIR/similar_names.rs:51:9
+ --> $DIR/similar_names.rs:55:9
|
LL | let coke: i32;
| ^^^^
|
note: existing binding defined here
- --> $DIR/similar_names.rs:49:9
+ --> $DIR/similar_names.rs:53:9
|
LL | let cake: i32;
| ^^^^
error: binding's name is too similar to existing binding
- --> $DIR/similar_names.rs:69:9
+ --> $DIR/similar_names.rs:74:9
|
LL | let xyzeabc: i32;
| ^^^^^^^
|
note: existing binding defined here
- --> $DIR/similar_names.rs:67:9
+ --> $DIR/similar_names.rs:72:9
|
LL | let xyz1abc: i32;
| ^^^^^^^
error: binding's name is too similar to existing binding
- --> $DIR/similar_names.rs:73:9
+ --> $DIR/similar_names.rs:79:9
|
LL | let parsee: i32;
| ^^^^^^
|
note: existing binding defined here
- --> $DIR/similar_names.rs:71:9
+ --> $DIR/similar_names.rs:77:9
|
LL | let parser: i32;
| ^^^^^^
error: binding's name is too similar to existing binding
- --> $DIR/similar_names.rs:94:16
+ --> $DIR/similar_names.rs:101:16
|
LL | bpple: sprang,
| ^^^^^^
|
note: existing binding defined here
- --> $DIR/similar_names.rs:93:16
+ --> $DIR/similar_names.rs:100:16
|
LL | apple: spring,
| ^^^^^^
diff --git a/src/tools/clippy/tests/ui/single_call_fn.rs b/src/tools/clippy/tests/ui/single_call_fn.rs
index 76e175014..3cc806164 100644
--- a/src/tools/clippy/tests/ui/single_call_fn.rs
+++ b/src/tools/clippy/tests/ui/single_call_fn.rs
@@ -1,4 +1,5 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@ignore-32bit
+//@aux-build:proc_macros.rs
#![allow(clippy::redundant_closure_call, unused)]
#![warn(clippy::single_call_fn)]
#![no_main]
diff --git a/src/tools/clippy/tests/ui/single_call_fn.stderr b/src/tools/clippy/tests/ui/single_call_fn.stderr
index 9ef8c4878..d5cd70775 100644
--- a/src/tools/clippy/tests/ui/single_call_fn.stderr
+++ b/src/tools/clippy/tests/ui/single_call_fn.stderr
@@ -1,5 +1,5 @@
error: this function is only used once
- --> $DIR/single_call_fn.rs:33:1
+ --> $DIR/single_call_fn.rs:34:1
|
LL | / fn c() {
LL | | println!("really");
@@ -9,44 +9,45 @@ LL | | }
| |_^
|
help: used here
- --> $DIR/single_call_fn.rs:40:5
+ --> $DIR/single_call_fn.rs:41:5
|
LL | c();
| ^
= note: `-D clippy::single-call-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_call_fn)]`
error: this function is only used once
- --> $DIR/single_call_fn.rs:12:1
+ --> $DIR/single_call_fn.rs:13:1
|
LL | fn i() {}
| ^^^^^^^^^
|
help: used here
- --> $DIR/single_call_fn.rs:17:13
+ --> $DIR/single_call_fn.rs:18:13
|
LL | let a = i;
| ^
error: this function is only used once
- --> $DIR/single_call_fn.rs:43:1
+ --> $DIR/single_call_fn.rs:44:1
|
LL | fn a() {}
| ^^^^^^^^^
|
help: used here
- --> $DIR/single_call_fn.rs:46:5
+ --> $DIR/single_call_fn.rs:47:5
|
LL | a();
| ^
error: this function is only used once
- --> $DIR/single_call_fn.rs:13:1
+ --> $DIR/single_call_fn.rs:14:1
|
LL | fn j() {}
| ^^^^^^^^^
|
help: used here
- --> $DIR/single_call_fn.rs:24:9
+ --> $DIR/single_call_fn.rs:25:9
|
LL | j();
| ^
diff --git a/src/tools/clippy/tests/ui/single_char_add_str.fixed b/src/tools/clippy/tests/ui/single_char_add_str.fixed
index cb301c8bc..eafd17f53 100644
--- a/src/tools/clippy/tests/ui/single_char_add_str.fixed
+++ b/src/tools/clippy/tests/ui/single_char_add_str.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::single_char_add_str)]
#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)]
diff --git a/src/tools/clippy/tests/ui/single_char_add_str.rs b/src/tools/clippy/tests/ui/single_char_add_str.rs
index 99baf35ac..5326c7cf2 100644
--- a/src/tools/clippy/tests/ui/single_char_add_str.rs
+++ b/src/tools/clippy/tests/ui/single_char_add_str.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::single_char_add_str)]
#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)]
diff --git a/src/tools/clippy/tests/ui/single_char_add_str.stderr b/src/tools/clippy/tests/ui/single_char_add_str.stderr
index 3f93c1847..a6f2b3e03 100644
--- a/src/tools/clippy/tests/ui/single_char_add_str.stderr
+++ b/src/tools/clippy/tests/ui/single_char_add_str.stderr
@@ -1,91 +1,92 @@
error: calling `push_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:15:5
+ --> $DIR/single_char_add_str.rs:14:5
|
LL | string.push_str("R");
| ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('R')`
|
= note: `-D clippy::single-char-add-str` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_char_add_str)]`
error: calling `push_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:16:5
+ --> $DIR/single_char_add_str.rs:15:5
|
LL | string.push_str("'");
- | ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('/'')`
+ | ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\'')`
error: calling `push_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:21:5
+ --> $DIR/single_char_add_str.rs:20:5
|
-LL | string.push_str("/x52");
- | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('/x52')`
+LL | string.push_str("\x52");
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\x52')`
error: calling `push_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:22:5
+ --> $DIR/single_char_add_str.rs:21:5
|
-LL | string.push_str("/u{0052}");
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('/u{0052}')`
+LL | string.push_str("\u{0052}");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\u{0052}')`
error: calling `push_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:23:5
+ --> $DIR/single_char_add_str.rs:22:5
|
LL | string.push_str(r##"a"##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('a')`
error: calling `push_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:25:5
+ --> $DIR/single_char_add_str.rs:24:5
|
LL | get_string!().push_str("ö");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `get_string!().push('ö')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:30:5
+ --> $DIR/single_char_add_str.rs:29:5
|
LL | string.insert_str(0, "R");
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, 'R')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:31:5
+ --> $DIR/single_char_add_str.rs:30:5
|
LL | string.insert_str(1, "'");
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(1, '/'')`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(1, '\'')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:36:5
+ --> $DIR/single_char_add_str.rs:35:5
|
-LL | string.insert_str(0, "/x52");
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '/x52')`
+LL | string.insert_str(0, "\x52");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\x52')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:37:5
+ --> $DIR/single_char_add_str.rs:36:5
|
-LL | string.insert_str(0, "/u{0052}");
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '/u{0052}')`
+LL | string.insert_str(0, "\u{0052}");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\u{0052}')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:39:5
+ --> $DIR/single_char_add_str.rs:38:5
|
LL | string.insert_str(x, r##"a"##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(x, 'a')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:41:5
+ --> $DIR/single_char_add_str.rs:40:5
|
LL | string.insert_str(Y, r##"a"##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, 'a')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:42:5
+ --> $DIR/single_char_add_str.rs:41:5
|
LL | string.insert_str(Y, r##"""##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '"')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:43:5
+ --> $DIR/single_char_add_str.rs:42:5
|
LL | string.insert_str(Y, r##"'"##);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '/'')`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '\'')`
error: calling `insert_str()` using a single-character string literal
- --> $DIR/single_char_add_str.rs:45:5
+ --> $DIR/single_char_add_str.rs:44:5
|
LL | get_string!().insert_str(1, "?");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `get_string!().insert(1, '?')`
diff --git a/src/tools/clippy/tests/ui/single_char_lifetime_names.rs b/src/tools/clippy/tests/ui/single_char_lifetime_names.rs
index 69c5b236f..6731b5b13 100644
--- a/src/tools/clippy/tests/ui/single_char_lifetime_names.rs
+++ b/src/tools/clippy/tests/ui/single_char_lifetime_names.rs
@@ -3,6 +3,8 @@
// Lifetimes should only be linted when they're introduced
struct DiagnosticCtx<'a, 'b>
+//~^ ERROR: single-character lifetime names are likely uninformative
+//~| ERROR: single-character lifetime names are likely uninformative
where
'a: 'b,
{
@@ -12,6 +14,8 @@ where
// Only the lifetimes on the `impl`'s generics should be linted
impl<'a, 'b> DiagnosticCtx<'a, 'b> {
+ //~^ ERROR: single-character lifetime names are likely uninformative
+ //~| ERROR: single-character lifetime names are likely uninformative
fn new(source: &'a str, unit: &'b ()) -> DiagnosticCtx<'a, 'b> {
Self {
_source: source,
@@ -32,6 +36,7 @@ impl<'src, 'unit> DiagnosticCtx<'src, 'unit> {
// Only 'a should be linted here
fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) {
+ //~^ ERROR: single-character lifetime names are likely uninformative
base.split_once(other)
.map(|(left, right)| (left, Some(right)))
.unwrap_or((base, None))
diff --git a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
index bfe6d44b5..2cdfd6135 100644
--- a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
+++ b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
@@ -6,6 +6,7 @@ LL | struct DiagnosticCtx<'a, 'b>
|
= help: use a more informative name
= note: `-D clippy::single-char-lifetime-names` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_char_lifetime_names)]`
error: single-character lifetime names are likely uninformative
--> $DIR/single_char_lifetime_names.rs:5:26
@@ -16,7 +17,7 @@ LL | struct DiagnosticCtx<'a, 'b>
= help: use a more informative name
error: single-character lifetime names are likely uninformative
- --> $DIR/single_char_lifetime_names.rs:14:6
+ --> $DIR/single_char_lifetime_names.rs:16:6
|
LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
| ^^
@@ -24,7 +25,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
= help: use a more informative name
error: single-character lifetime names are likely uninformative
- --> $DIR/single_char_lifetime_names.rs:14:10
+ --> $DIR/single_char_lifetime_names.rs:16:10
|
LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
| ^^
@@ -32,7 +33,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
= help: use a more informative name
error: single-character lifetime names are likely uninformative
- --> $DIR/single_char_lifetime_names.rs:34:15
+ --> $DIR/single_char_lifetime_names.rs:38:15
|
LL | fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) {
| ^^
diff --git a/src/tools/clippy/tests/ui/single_char_pattern.fixed b/src/tools/clippy/tests/ui/single_char_pattern.fixed
index 7ae62231a..79e7eda40 100644
--- a/src/tools/clippy/tests/ui/single_char_pattern.fixed
+++ b/src/tools/clippy/tests/ui/single_char_pattern.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)]
use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/single_char_pattern.rs b/src/tools/clippy/tests/ui/single_char_pattern.rs
index 0604624e7..81962c0a6 100644
--- a/src/tools/clippy/tests/ui/single_char_pattern.rs
+++ b/src/tools/clippy/tests/ui/single_char_pattern.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)]
use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/single_char_pattern.stderr b/src/tools/clippy/tests/ui/single_char_pattern.stderr
index 5ae2450c2..6e57ab348 100644
--- a/src/tools/clippy/tests/ui/single_char_pattern.stderr
+++ b/src/tools/clippy/tests/ui/single_char_pattern.stderr
@@ -1,238 +1,239 @@
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:9:13
+ --> $DIR/single_char_pattern.rs:7:13
|
LL | x.split("x");
| ^^^ help: try using a `char` instead: `'x'`
|
= note: `-D clippy::single-char-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_char_pattern)]`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:15:13
+ --> $DIR/single_char_pattern.rs:13:13
|
LL | x.split("ß");
| ^^^ help: try using a `char` instead: `'ß'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:16:13
+ --> $DIR/single_char_pattern.rs:14:13
|
LL | x.split("ℝ");
| ^^^ help: try using a `char` instead: `'ℝ'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:17:13
+ --> $DIR/single_char_pattern.rs:15:13
|
LL | x.split("💣");
| ^^^^ help: try using a `char` instead: `'💣'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:20:23
+ --> $DIR/single_char_pattern.rs:18:23
|
LL | x.split_inclusive("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:21:16
+ --> $DIR/single_char_pattern.rs:19:16
|
LL | x.contains("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:22:19
+ --> $DIR/single_char_pattern.rs:20:19
|
LL | x.starts_with("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:23:17
+ --> $DIR/single_char_pattern.rs:21:17
|
LL | x.ends_with("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:24:12
+ --> $DIR/single_char_pattern.rs:22:12
|
LL | x.find("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:25:13
+ --> $DIR/single_char_pattern.rs:23:13
|
LL | x.rfind("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:26:14
+ --> $DIR/single_char_pattern.rs:24:14
|
LL | x.rsplit("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:27:24
+ --> $DIR/single_char_pattern.rs:25:24
|
LL | x.split_terminator("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:28:25
+ --> $DIR/single_char_pattern.rs:26:25
|
LL | x.rsplit_terminator("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:29:17
+ --> $DIR/single_char_pattern.rs:27:17
|
LL | x.splitn(2, "x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:30:18
+ --> $DIR/single_char_pattern.rs:28:18
|
LL | x.rsplitn(2, "x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:31:18
+ --> $DIR/single_char_pattern.rs:29:18
|
LL | x.split_once("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:32:19
+ --> $DIR/single_char_pattern.rs:30:19
|
LL | x.rsplit_once("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:33:15
+ --> $DIR/single_char_pattern.rs:31:15
|
LL | x.matches("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:34:16
+ --> $DIR/single_char_pattern.rs:32:16
|
LL | x.rmatches("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:35:21
+ --> $DIR/single_char_pattern.rs:33:21
|
LL | x.match_indices("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:36:22
+ --> $DIR/single_char_pattern.rs:34:22
|
LL | x.rmatch_indices("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:37:26
+ --> $DIR/single_char_pattern.rs:35:26
|
LL | x.trim_start_matches("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:38:24
+ --> $DIR/single_char_pattern.rs:36:24
|
LL | x.trim_end_matches("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:39:20
+ --> $DIR/single_char_pattern.rs:37:20
|
LL | x.strip_prefix("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:40:20
+ --> $DIR/single_char_pattern.rs:38:20
|
LL | x.strip_suffix("x");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:41:15
+ --> $DIR/single_char_pattern.rs:39:15
|
LL | x.replace("x", "y");
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:42:16
+ --> $DIR/single_char_pattern.rs:40:16
|
LL | x.replacen("x", "y", 3);
| ^^^ help: try using a `char` instead: `'x'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:44:13
+ --> $DIR/single_char_pattern.rs:42:13
|
-LL | x.split("/n");
- | ^^^^ help: try using a `char` instead: `'/n'`
+LL | x.split("\n");
+ | ^^^^ help: try using a `char` instead: `'\n'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:45:13
+ --> $DIR/single_char_pattern.rs:43:13
|
LL | x.split("'");
- | ^^^ help: try using a `char` instead: `'/''`
+ | ^^^ help: try using a `char` instead: `'\''`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:46:13
+ --> $DIR/single_char_pattern.rs:44:13
|
-LL | x.split("/'");
- | ^^^^ help: try using a `char` instead: `'/''`
+LL | x.split("\'");
+ | ^^^^ help: try using a `char` instead: `'\''`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:51:31
+ --> $DIR/single_char_pattern.rs:49:31
|
LL | x.replace(';', ",").split(","); // issue #2978
| ^^^ help: try using a `char` instead: `','`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:52:19
+ --> $DIR/single_char_pattern.rs:50:19
|
-LL | x.starts_with("/x03"); // issue #2996
- | ^^^^^^ help: try using a `char` instead: `'/x03'`
+LL | x.starts_with("\x03"); // issue #2996
+ | ^^^^^^ help: try using a `char` instead: `'\x03'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:59:13
+ --> $DIR/single_char_pattern.rs:57:13
|
LL | x.split(r"a");
| ^^^^ help: try using a `char` instead: `'a'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:60:13
+ --> $DIR/single_char_pattern.rs:58:13
|
LL | x.split(r#"a"#);
| ^^^^^^ help: try using a `char` instead: `'a'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:61:13
+ --> $DIR/single_char_pattern.rs:59:13
|
LL | x.split(r###"a"###);
| ^^^^^^^^^^ help: try using a `char` instead: `'a'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:62:13
+ --> $DIR/single_char_pattern.rs:60:13
|
LL | x.split(r###"'"###);
- | ^^^^^^^^^^ help: try using a `char` instead: `'/''`
+ | ^^^^^^^^^^ help: try using a `char` instead: `'\''`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:63:13
+ --> $DIR/single_char_pattern.rs:61:13
|
LL | x.split(r###"#"###);
| ^^^^^^^^^^ help: try using a `char` instead: `'#'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:65:13
+ --> $DIR/single_char_pattern.rs:63:13
|
-LL | x.split(r#"/"#);
- | ^^^^^^ help: try using a `char` instead: `'//'`
+LL | x.split(r#"\"#);
+ | ^^^^^^ help: try using a `char` instead: `'\\'`
error: single-character string constant used as pattern
- --> $DIR/single_char_pattern.rs:66:13
+ --> $DIR/single_char_pattern.rs:64:13
|
-LL | x.split(r"/");
- | ^^^^ help: try using a `char` instead: `'//'`
+LL | x.split(r"\");
+ | ^^^^ help: try using a `char` instead: `'\\'`
error: aborting due to 39 previous errors
diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.fixed b/src/tools/clippy/tests/ui/single_component_path_imports.fixed
index b6b6b0288..fdff336c2 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports.fixed
+++ b/src/tools/clippy/tests/ui/single_component_path_imports.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::single_component_path_imports)]
#![allow(unused_imports)]
diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.rs b/src/tools/clippy/tests/ui/single_component_path_imports.rs
index a8c4d8990..2d72f122a 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports.rs
+++ b/src/tools/clippy/tests/ui/single_component_path_imports.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::single_component_path_imports)]
#![allow(unused_imports)]
diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.stderr b/src/tools/clippy/tests/ui/single_component_path_imports.stderr
index 853a2fe0e..440d34002 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports.stderr
+++ b/src/tools/clippy/tests/ui/single_component_path_imports.stderr
@@ -1,13 +1,14 @@
error: this import is redundant
- --> $DIR/single_component_path_imports.rs:7:1
+ --> $DIR/single_component_path_imports.rs:6:1
|
LL | use regex;
| ^^^^^^^^^^ help: remove it entirely
|
= note: `-D clippy::single-component-path-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_component_path_imports)]`
error: this import is redundant
- --> $DIR/single_component_path_imports.rs:33:5
+ --> $DIR/single_component_path_imports.rs:32:5
|
LL | use regex;
| ^^^^^^^^^^ help: remove it entirely
diff --git a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.rs b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.rs
index d6243c19f..b4a1ce1d6 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.rs
+++ b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.rs
@@ -1,7 +1,9 @@
#![warn(clippy::single_component_path_imports)]
#![allow(unused_imports)]
-
+//@no-rustfix
use regex;
+//~^ ERROR: this import is redundant
+//~| NOTE: `-D clippy::single-component-path-imports` implied by `-D warnings`
use serde as edres;
@@ -13,6 +15,8 @@ fn main() {
mod root_nested_use_mod {
use {regex, serde};
+ //~^ ERROR: this import is redundant
+ //~| ERROR: this import is redundant
#[allow(dead_code)]
fn root_nested_use_mod() {}
}
diff --git a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr
index ff148355e..d65ab5620 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr
+++ b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr
@@ -5,9 +5,10 @@ LL | use regex;
| ^^^^^^^^^^ help: remove it entirely
|
= note: `-D clippy::single-component-path-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_component_path_imports)]`
error: this import is redundant
- --> $DIR/single_component_path_imports_nested_first.rs:15:10
+ --> $DIR/single_component_path_imports_nested_first.rs:17:10
|
LL | use {regex, serde};
| ^^^^^
@@ -15,7 +16,7 @@ LL | use {regex, serde};
= help: remove this import
error: this import is redundant
- --> $DIR/single_component_path_imports_nested_first.rs:15:17
+ --> $DIR/single_component_path_imports_nested_first.rs:17:17
|
LL | use {regex, serde};
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/single_element_loop.fixed b/src/tools/clippy/tests/ui/single_element_loop.fixed
index 598f25941..a82eb6afc 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.fixed
+++ b/src/tools/clippy/tests/ui/single_element_loop.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
// Tests from for_loop.rs that don't have suggestions
#![allow(clippy::single_range_in_vec_init)]
diff --git a/src/tools/clippy/tests/ui/single_element_loop.rs b/src/tools/clippy/tests/ui/single_element_loop.rs
index 3fc461735..a55ece6b0 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.rs
+++ b/src/tools/clippy/tests/ui/single_element_loop.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
// Tests from for_loop.rs that don't have suggestions
#![allow(clippy::single_range_in_vec_init)]
diff --git a/src/tools/clippy/tests/ui/single_element_loop.stderr b/src/tools/clippy/tests/ui/single_element_loop.stderr
index c40c61989..603dd7406 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.stderr
+++ b/src/tools/clippy/tests/ui/single_element_loop.stderr
@@ -1,5 +1,5 @@
error: for loop over a single element
- --> $DIR/single_element_loop.rs:9:5
+ --> $DIR/single_element_loop.rs:8:5
|
LL | / for item in &[item1] {
LL | | dbg!(item);
@@ -7,6 +7,7 @@ LL | | }
| |_____^
|
= note: `-D clippy::single-element-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_element_loop)]`
help: try
|
LL ~ {
@@ -16,7 +17,7 @@ LL + }
|
error: for loop over a single element
- --> $DIR/single_element_loop.rs:13:5
+ --> $DIR/single_element_loop.rs:12:5
|
LL | / for item in [item1].iter() {
LL | | dbg!(item);
@@ -32,7 +33,7 @@ LL + }
|
error: for loop over a single element
- --> $DIR/single_element_loop.rs:17:5
+ --> $DIR/single_element_loop.rs:16:5
|
LL | / for item in &[0..5] {
LL | | dbg!(item);
@@ -48,7 +49,7 @@ LL + }
|
error: for loop over a single element
- --> $DIR/single_element_loop.rs:21:5
+ --> $DIR/single_element_loop.rs:20:5
|
LL | / for item in [0..5].iter_mut() {
LL | | dbg!(item);
@@ -64,7 +65,7 @@ LL + }
|
error: for loop over a single element
- --> $DIR/single_element_loop.rs:25:5
+ --> $DIR/single_element_loop.rs:24:5
|
LL | / for item in [0..5] {
LL | | dbg!(item);
@@ -80,7 +81,7 @@ LL + }
|
error: for loop over a single element
- --> $DIR/single_element_loop.rs:29:5
+ --> $DIR/single_element_loop.rs:28:5
|
LL | / for item in [0..5].into_iter() {
LL | | dbg!(item);
@@ -96,7 +97,7 @@ LL + }
|
error: for loop over a single element
- --> $DIR/single_element_loop.rs:48:5
+ --> $DIR/single_element_loop.rs:47:5
|
LL | / for _ in [42] {
LL | | let _f = |n: u32| {
diff --git a/src/tools/clippy/tests/ui/single_match.fixed b/src/tools/clippy/tests/ui/single_match.fixed
index 163ba94af..0a49be2dc 100644
--- a/src/tools/clippy/tests/ui/single_match.fixed
+++ b/src/tools/clippy/tests/ui/single_match.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::single_match)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/single_match.rs b/src/tools/clippy/tests/ui/single_match.rs
index 0dcdb125f..4e35d265a 100644
--- a/src/tools/clippy/tests/ui/single_match.rs
+++ b/src/tools/clippy/tests/ui/single_match.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::single_match)]
#![allow(
unused,
diff --git a/src/tools/clippy/tests/ui/single_match.stderr b/src/tools/clippy/tests/ui/single_match.stderr
index d35361599..d4b865995 100644
--- a/src/tools/clippy/tests/ui/single_match.stderr
+++ b/src/tools/clippy/tests/ui/single_match.stderr
@@ -1,5 +1,5 @@
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:15:5
+ --> $DIR/single_match.rs:14:5
|
LL | / match x {
LL | | Some(y) => {
@@ -10,6 +10,7 @@ LL | | };
| |_____^
|
= note: `-D clippy::single-match` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_match)]`
help: try
|
LL ~ if let Some(y) = x {
@@ -18,7 +19,7 @@ LL ~ };
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:23:5
+ --> $DIR/single_match.rs:22:5
|
LL | / match x {
LL | | // Note the missing block braces.
@@ -30,7 +31,7 @@ LL | | }
| |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:32:5
+ --> $DIR/single_match.rs:31:5
|
LL | / match z {
LL | | (2..=3, 7..=9) => dummy(),
@@ -39,7 +40,7 @@ LL | | };
| |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:61:5
+ --> $DIR/single_match.rs:60:5
|
LL | / match x {
LL | | Some(y) => dummy(),
@@ -48,7 +49,7 @@ LL | | };
| |_____^ help: try: `if let Some(y) = x { dummy() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:66:5
+ --> $DIR/single_match.rs:65:5
|
LL | / match y {
LL | | Ok(y) => dummy(),
@@ -57,7 +58,7 @@ LL | | };
| |_____^ help: try: `if let Ok(y) = y { dummy() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:73:5
+ --> $DIR/single_match.rs:72:5
|
LL | / match c {
LL | | Cow::Borrowed(..) => dummy(),
@@ -66,7 +67,7 @@ LL | | };
| |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
- --> $DIR/single_match.rs:94:5
+ --> $DIR/single_match.rs:93:5
|
LL | / match x {
LL | | "test" => println!(),
@@ -75,7 +76,7 @@ LL | | }
| |_____^ help: try: `if x == "test" { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
- --> $DIR/single_match.rs:107:5
+ --> $DIR/single_match.rs:106:5
|
LL | / match x {
LL | | Foo::A => println!(),
@@ -84,7 +85,7 @@ LL | | }
| |_____^ help: try: `if x == Foo::A { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
- --> $DIR/single_match.rs:113:5
+ --> $DIR/single_match.rs:112:5
|
LL | / match x {
LL | | FOO_C => println!(),
@@ -93,7 +94,7 @@ LL | | }
| |_____^ help: try: `if x == FOO_C { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
- --> $DIR/single_match.rs:118:5
+ --> $DIR/single_match.rs:117:5
|
LL | / match &&x {
LL | | Foo::A => println!(),
@@ -102,7 +103,7 @@ LL | | }
| |_____^ help: try: `if x == Foo::A { println!() }`
error: you seem to be trying to use `match` for an equality check. Consider using `if`
- --> $DIR/single_match.rs:124:5
+ --> $DIR/single_match.rs:123:5
|
LL | / match &x {
LL | | Foo::A => println!(),
@@ -111,7 +112,7 @@ LL | | }
| |_____^ help: try: `if x == &Foo::A { println!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:141:5
+ --> $DIR/single_match.rs:140:5
|
LL | / match x {
LL | | Bar::A => println!(),
@@ -120,7 +121,7 @@ LL | | }
| |_____^ help: try: `if let Bar::A = x { println!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:149:5
+ --> $DIR/single_match.rs:148:5
|
LL | / match x {
LL | | None => println!(),
@@ -129,7 +130,7 @@ LL | | };
| |_____^ help: try: `if let None = x { println!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:171:5
+ --> $DIR/single_match.rs:170:5
|
LL | / match x {
LL | | (Some(_), _) => {},
@@ -138,7 +139,7 @@ LL | | }
| |_____^ help: try: `if let (Some(_), _) = x {}`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:177:5
+ --> $DIR/single_match.rs:176:5
|
LL | / match x {
LL | | (Some(E::V), _) => todo!(),
@@ -147,7 +148,7 @@ LL | | }
| |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:183:5
+ --> $DIR/single_match.rs:182:5
|
LL | / match (Some(42), Some(E::V), Some(42)) {
LL | | (.., Some(E::V), _) => {},
@@ -156,7 +157,7 @@ LL | | }
| |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:255:5
+ --> $DIR/single_match.rs:254:5
|
LL | / match bar {
LL | | Some(v) => unsafe {
@@ -176,7 +177,7 @@ LL + } }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match.rs:263:5
+ --> $DIR/single_match.rs:262:5
|
LL | / match bar {
LL | | #[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed
index fcc8f1480..f3b1de3b4 100644
--- a/src/tools/clippy/tests/ui/single_match_else.fixed
+++ b/src/tools/clippy/tests/ui/single_match_else.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![warn(clippy::single_match_else)]
#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs
index 77afd58a0..ddee2e42e 100644
--- a/src/tools/clippy/tests/ui/single_match_else.rs
+++ b/src/tools/clippy/tests/ui/single_match_else.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![warn(clippy::single_match_else)]
#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index 5e7d4062e..3b4b1332c 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -1,5 +1,5 @@
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:17:13
+ --> $DIR/single_match_else.rs:16:13
|
LL | let _ = match ExprNode::Butterflies {
| _____________^
@@ -12,6 +12,7 @@ LL | | };
| |_____^
|
= note: `-D clippy::single-match-else` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_match_else)]`
help: try
|
LL ~ let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else {
@@ -21,7 +22,7 @@ LL ~ };
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:82:5
+ --> $DIR/single_match_else.rs:81:5
|
LL | / match Some(1) {
LL | | Some(a) => println!("${:?}", a),
@@ -41,7 +42,7 @@ LL + }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:91:5
+ --> $DIR/single_match_else.rs:90:5
|
LL | / match Some(1) {
LL | | Some(a) => println!("${:?}", a),
@@ -61,7 +62,7 @@ LL + }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:101:5
+ --> $DIR/single_match_else.rs:100:5
|
LL | / match Result::<i32, Infallible>::Ok(1) {
LL | | Ok(a) => println!("${:?}", a),
@@ -81,7 +82,7 @@ LL + }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:110:5
+ --> $DIR/single_match_else.rs:109:5
|
LL | / match Cow::from("moo") {
LL | | Cow::Owned(a) => println!("${:?}", a),
@@ -101,7 +102,7 @@ LL + }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:120:5
+ --> $DIR/single_match_else.rs:119:5
|
LL | / match bar {
LL | | Some(v) => unsafe {
@@ -124,7 +125,7 @@ LL + }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:131:5
+ --> $DIR/single_match_else.rs:130:5
|
LL | / match bar {
LL | | Some(v) => {
@@ -148,7 +149,7 @@ LL + } }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:143:5
+ --> $DIR/single_match_else.rs:142:5
|
LL | / match bar {
LL | | Some(v) => unsafe {
@@ -172,7 +173,7 @@ LL + } }
|
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
- --> $DIR/single_match_else.rs:155:5
+ --> $DIR/single_match_else.rs:154:5
|
LL | / match bar {
LL | | #[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/single_range_in_vec_init.rs b/src/tools/clippy/tests/ui/single_range_in_vec_init.rs
index 833e1c43b..7887cfc61 100644
--- a/src/tools/clippy/tests/ui/single_range_in_vec_init.rs
+++ b/src/tools/clippy/tests/ui/single_range_in_vec_init.rs
@@ -1,4 +1,5 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
+//@no-rustfix: overlapping suggestions
#![allow(clippy::no_effect, clippy::useless_vec, unused)]
#![warn(clippy::single_range_in_vec_init)]
#![feature(generic_arg_infer)]
diff --git a/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr b/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr
index 3e3d521f4..e83e49af6 100644
--- a/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr
+++ b/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr
@@ -1,10 +1,11 @@
error: an array of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:25:5
+ --> $DIR/single_range_in_vec_init.rs:26:5
|
LL | [0..200];
| ^^^^^^^^
|
= note: `-D clippy::single-range-in-vec-init` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]`
help: if you wanted a `Vec` that contains the entire range, try
|
LL | (0..200).collect::<std::vec::Vec<i32>>();
@@ -15,7 +16,7 @@ LL | [0; 200];
| ~~~~~~
error: a `Vec` of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:26:5
+ --> $DIR/single_range_in_vec_init.rs:27:5
|
LL | vec![0..200];
| ^^^^^^^^^^^^
@@ -30,7 +31,7 @@ LL | vec![0; 200];
| ~~~~~~
error: an array of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:27:5
+ --> $DIR/single_range_in_vec_init.rs:28:5
|
LL | [0u8..200];
| ^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | [0u8; 200];
| ~~~~~~~~
error: an array of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:28:5
+ --> $DIR/single_range_in_vec_init.rs:29:5
|
LL | [0usize..200];
| ^^^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL | [0usize; 200];
| ~~~~~~~~~~~
error: an array of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:29:5
+ --> $DIR/single_range_in_vec_init.rs:30:5
|
LL | [0..200usize];
| ^^^^^^^^^^^^^
@@ -75,7 +76,7 @@ LL | [0; 200usize];
| ~~~~~~~~~~~
error: a `Vec` of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:30:5
+ --> $DIR/single_range_in_vec_init.rs:31:5
|
LL | vec![0u8..200];
| ^^^^^^^^^^^^^^
@@ -90,7 +91,7 @@ LL | vec![0u8; 200];
| ~~~~~~~~
error: a `Vec` of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:31:5
+ --> $DIR/single_range_in_vec_init.rs:32:5
|
LL | vec![0usize..200];
| ^^^^^^^^^^^^^^^^^
@@ -105,7 +106,7 @@ LL | vec![0usize; 200];
| ~~~~~~~~~~~
error: a `Vec` of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:32:5
+ --> $DIR/single_range_in_vec_init.rs:33:5
|
LL | vec![0..200usize];
| ^^^^^^^^^^^^^^^^^
@@ -120,7 +121,7 @@ LL | vec![0; 200usize];
| ~~~~~~~~~~~
error: an array of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:34:5
+ --> $DIR/single_range_in_vec_init.rs:35:5
|
LL | [0..200isize];
| ^^^^^^^^^^^^^
@@ -131,7 +132,7 @@ LL | (0..200isize).collect::<std::vec::Vec<isize>>();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: a `Vec` of `Range` that is only one element
- --> $DIR/single_range_in_vec_init.rs:35:5
+ --> $DIR/single_range_in_vec_init.rs:36:5
|
LL | vec![0..200isize];
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs
index 2594e8fa6..91b7ea392 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs
@@ -13,12 +13,15 @@ fn main() {
// Count expression involving multiplication of size_of (Should trigger the lint)
unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
// Count expression involving nested multiplications of size_of (Should trigger the lint)
unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
// Count expression involving divisions of size_of (Should trigger the lint)
unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u8>() / 2) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
// Count expression involving divisions by size_of (Should not trigger the lint)
unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::<u8>()) };
@@ -28,6 +31,7 @@ fn main() {
// Count expression involving recursive divisions by size_of (Should trigger the lint)
unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u8>())) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
// No size_of calls (Should not trigger the lint)
unsafe { copy(x.as_ptr(), y.as_mut_ptr(), SIZE) };
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
index 037f695f3..47f9632b8 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
@@ -6,9 +6,10 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>(
|
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
= note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::size_of_in_element_count)]`
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/expressions.rs:18:62
+ --> $DIR/expressions.rs:19:62
|
LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * si
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/expressions.rs:21:47
+ --> $DIR/expressions.rs:23:47
|
LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u8>() / 2) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u8>()
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/expressions.rs:30:47
+ --> $DIR/expressions.rs:33:47
|
LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u8>())) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs
index 09d08ac37..3501cbdf8 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs
@@ -16,31 +16,52 @@ fn main() {
// Count is size_of (Should trigger the lint)
unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::<u8>() * SIZE) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::<u8>() * SIZE) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u8>() * SIZE) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE);
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
slice_from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE);
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { y.as_mut_ptr().sub(size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
y.as_ptr().wrapping_sub(size_of::<u8>());
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { y.as_ptr().add(size_of::<u8>()) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
y.as_mut_ptr().wrapping_add(size_of::<u8>());
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
unsafe { y.as_ptr().offset(size_of::<u8>() as isize) };
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
y.as_mut_ptr().wrapping_offset(size_of::<u8>() as isize);
+ //~^ ERROR: found a count of bytes instead of a count of elements of `T`
}
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
index 4351e6a14..aba4c800e 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
@@ -6,9 +6,10 @@ LL | unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of:
|
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
= note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::size_of_in_element_count)]`
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:19:62
+ --> $DIR/functions.rs:20:62
|
LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
| ^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:21:49
+ --> $DIR/functions.rs:23:49
|
LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u8>()) };
| ^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u8>()) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:22:64
+ --> $DIR/functions.rs:25:64
|
LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u8>()) };
| ^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u8
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:23:51
+ --> $DIR/functions.rs:27:51
|
LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u8>()) };
| ^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u8>()) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:24:66
+ --> $DIR/functions.rs:29:66
|
LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u8>()) };
| ^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:26:47
+ --> $DIR/functions.rs:32:47
|
LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
| ^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:27:47
+ --> $DIR/functions.rs:34:47
|
LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
| ^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:29:46
+ --> $DIR/functions.rs:37:46
|
LL | unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::<u8>() * SIZE) };
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::<u8>() * SIZE) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:30:47
+ --> $DIR/functions.rs:39:47
|
LL | unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::<u8>() * SIZE) };
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +81,7 @@ LL | unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::<u8>() * SIZE) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:32:66
+ --> $DIR/functions.rs:42:66
|
LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u8>() * SIZE) };
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +89,7 @@ LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:34:46
+ --> $DIR/functions.rs:45:46
|
LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE);
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE);
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:35:38
+ --> $DIR/functions.rs:47:38
|
LL | slice_from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE);
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +105,7 @@ LL | slice_from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE);
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:37:49
+ --> $DIR/functions.rs:50:49
|
LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE) };
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +113,7 @@ LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:38:41
+ --> $DIR/functions.rs:52:41
|
LL | unsafe { from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE) };
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -120,7 +121,7 @@ LL | unsafe { from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:40:33
+ --> $DIR/functions.rs:55:33
|
LL | unsafe { y.as_mut_ptr().sub(size_of::<u8>()) };
| ^^^^^^^^^^^^^^^
@@ -128,7 +129,7 @@ LL | unsafe { y.as_mut_ptr().sub(size_of::<u8>()) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:41:29
+ --> $DIR/functions.rs:57:29
|
LL | y.as_ptr().wrapping_sub(size_of::<u8>());
| ^^^^^^^^^^^^^^^
@@ -136,7 +137,7 @@ LL | y.as_ptr().wrapping_sub(size_of::<u8>());
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:42:29
+ --> $DIR/functions.rs:59:29
|
LL | unsafe { y.as_ptr().add(size_of::<u8>()) };
| ^^^^^^^^^^^^^^^
@@ -144,7 +145,7 @@ LL | unsafe { y.as_ptr().add(size_of::<u8>()) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:43:33
+ --> $DIR/functions.rs:61:33
|
LL | y.as_mut_ptr().wrapping_add(size_of::<u8>());
| ^^^^^^^^^^^^^^^
@@ -152,7 +153,7 @@ LL | y.as_mut_ptr().wrapping_add(size_of::<u8>());
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:44:32
+ --> $DIR/functions.rs:63:32
|
LL | unsafe { y.as_ptr().offset(size_of::<u8>() as isize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -160,7 +161,7 @@ LL | unsafe { y.as_ptr().offset(size_of::<u8>() as isize) };
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
error: found a count of bytes instead of a count of elements of `T`
- --> $DIR/functions.rs:45:36
+ --> $DIR/functions.rs:65:36
|
LL | y.as_mut_ptr().wrapping_offset(size_of::<u8>() as isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/size_of_ref.rs b/src/tools/clippy/tests/ui/size_of_ref.rs
index 1e83ab829..670c6c080 100644
--- a/src/tools/clippy/tests/ui/size_of_ref.rs
+++ b/src/tools/clippy/tests/ui/size_of_ref.rs
@@ -11,7 +11,9 @@ fn main() {
size_of_val(y); // no lint
size_of_val(&&x);
+ //~^ ERROR: argument to `std::mem::size_of_val()` is a reference to a reference
size_of_val(&y);
+ //~^ ERROR: argument to `std::mem::size_of_val()` is a reference to a reference
}
struct S {
@@ -23,5 +25,6 @@ impl S {
/// Get size of object including `self`, in bytes.
pub fn size(&self) -> usize {
std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity())
+ //~^ ERROR: argument to `std::mem::size_of_val()` is a reference to a reference
}
}
diff --git a/src/tools/clippy/tests/ui/size_of_ref.stderr b/src/tools/clippy/tests/ui/size_of_ref.stderr
index d4c13ac32..e239c5810 100644
--- a/src/tools/clippy/tests/ui/size_of_ref.stderr
+++ b/src/tools/clippy/tests/ui/size_of_ref.stderr
@@ -6,9 +6,10 @@ LL | size_of_val(&&x);
|
= help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
= note: `-D clippy::size-of-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::size_of_ref)]`
error: argument to `std::mem::size_of_val()` is a reference to a reference
- --> $DIR/size_of_ref.rs:14:5
+ --> $DIR/size_of_ref.rs:15:5
|
LL | size_of_val(&y);
| ^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | size_of_val(&y);
= help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
error: argument to `std::mem::size_of_val()` is a reference to a reference
- --> $DIR/size_of_ref.rs:25:9
+ --> $DIR/size_of_ref.rs:27:9
|
LL | std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/skip_while_next.stderr b/src/tools/clippy/tests/ui/skip_while_next.stderr
index 7308ab4e5..3c33af3a1 100644
--- a/src/tools/clippy/tests/ui/skip_while_next.stderr
+++ b/src/tools/clippy/tests/ui/skip_while_next.stderr
@@ -6,6 +6,7 @@ LL | let _ = v.iter().skip_while(|&x| *x < 0).next();
|
= help: this is more succinctly expressed by calling `.find(!<p>)` instead
= note: `-D clippy::skip-while-next` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::skip_while_next)]`
error: called `skip_while(<p>).next()` on an `Iterator`
--> $DIR/skip_while_next.rs:17:13
diff --git a/src/tools/clippy/tests/ui/slow_vector_initialization.rs b/src/tools/clippy/tests/ui/slow_vector_initialization.rs
index cfb856861..16f810195 100644
--- a/src/tools/clippy/tests/ui/slow_vector_initialization.rs
+++ b/src/tools/clippy/tests/ui/slow_vector_initialization.rs
@@ -1,5 +1,5 @@
+//@no-rustfix
use std::iter::repeat;
-
fn main() {
resize_vector();
extend_vector();
@@ -12,10 +12,13 @@ fn extend_vector() {
let len = 300;
let mut vec1 = Vec::with_capacity(len);
vec1.extend(repeat(0).take(len));
+ //~^ ERROR: slow zero-filling initialization
+ //~| NOTE: `-D clippy::slow-vector-initialization` implied by `-D warnings`
// Extend with len expression
let mut vec2 = Vec::with_capacity(len - 10);
vec2.extend(repeat(0).take(len - 10));
+ //~^ ERROR: slow zero-filling initialization
// Extend with mismatching expression should not be warned
let mut vec3 = Vec::with_capacity(24322);
@@ -23,6 +26,7 @@ fn extend_vector() {
let mut vec4 = Vec::with_capacity(len);
vec4.extend(repeat(0).take(vec4.capacity()));
+ //~^ ERROR: slow zero-filling initialization
}
fn mixed_extend_resize_vector() {
@@ -33,9 +37,11 @@ fn mixed_extend_resize_vector() {
// Slow initialization
let mut resized_vec = Vec::with_capacity(30);
resized_vec.resize(30, 0);
+ //~^ ERROR: slow zero-filling initialization
let mut extend_vec = Vec::with_capacity(30);
extend_vec.extend(repeat(0).take(30));
+ //~^ ERROR: slow zero-filling initialization
}
fn resize_vector() {
@@ -43,6 +49,7 @@ fn resize_vector() {
let len = 300;
let mut vec1 = Vec::with_capacity(len);
vec1.resize(len, 0);
+ //~^ ERROR: slow zero-filling initialization
// Resize mismatch len
let mut vec2 = Vec::with_capacity(200);
@@ -51,13 +58,16 @@ fn resize_vector() {
// Resize with len expression
let mut vec3 = Vec::with_capacity(len - 10);
vec3.resize(len - 10, 0);
+ //~^ ERROR: slow zero-filling initialization
let mut vec4 = Vec::with_capacity(len);
vec4.resize(vec4.capacity(), 0);
+ //~^ ERROR: slow zero-filling initialization
// Reinitialization should be warned
vec1 = Vec::with_capacity(10);
vec1.resize(10, 0);
+ //~^ ERROR: slow zero-filling initialization
}
fn from_empty_vec() {
@@ -65,14 +75,31 @@ fn from_empty_vec() {
let len = 300;
let mut vec1 = Vec::new();
vec1.resize(len, 0);
+ //~^ ERROR: slow zero-filling initialization
// Resize with len expression
let mut vec3 = Vec::new();
vec3.resize(len - 10, 0);
+ //~^ ERROR: slow zero-filling initialization
// Reinitialization should be warned
vec1 = Vec::new();
vec1.resize(10, 0);
+ //~^ ERROR: slow zero-filling initialization
+
+ vec1 = vec![];
+ vec1.resize(10, 0);
+ //~^ ERROR: slow zero-filling initialization
+
+ macro_rules! x {
+ () => {
+ vec![]
+ };
+ }
+
+ // `vec![]` comes from another macro, don't warn
+ vec1 = x!();
+ vec1.resize(10, 0);
}
fn do_stuff(vec: &mut [u8]) {}
diff --git a/src/tools/clippy/tests/ui/slow_vector_initialization.stderr b/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
index c88c97a55..16a705765 100644
--- a/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
+++ b/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
@@ -7,9 +7,10 @@ LL | vec1.extend(repeat(0).take(len));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::slow-vector-initialization` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::slow_vector_initialization)]`
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:18:5
+ --> $DIR/slow_vector_initialization.rs:20:5
|
LL | let mut vec2 = Vec::with_capacity(len - 10);
| ---------------------------- help: consider replacing this with: `vec![0; len - 10]`
@@ -17,7 +18,7 @@ LL | vec2.extend(repeat(0).take(len - 10));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:25:5
+ --> $DIR/slow_vector_initialization.rs:28:5
|
LL | let mut vec4 = Vec::with_capacity(len);
| ----------------------- help: consider replacing this with: `vec![0; len]`
@@ -25,7 +26,7 @@ LL | vec4.extend(repeat(0).take(vec4.capacity()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:35:5
+ --> $DIR/slow_vector_initialization.rs:39:5
|
LL | let mut resized_vec = Vec::with_capacity(30);
| ---------------------- help: consider replacing this with: `vec![0; 30]`
@@ -33,7 +34,7 @@ LL | resized_vec.resize(30, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:38:5
+ --> $DIR/slow_vector_initialization.rs:43:5
|
LL | let mut extend_vec = Vec::with_capacity(30);
| ---------------------- help: consider replacing this with: `vec![0; 30]`
@@ -41,7 +42,7 @@ LL | extend_vec.extend(repeat(0).take(30));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:45:5
+ --> $DIR/slow_vector_initialization.rs:51:5
|
LL | let mut vec1 = Vec::with_capacity(len);
| ----------------------- help: consider replacing this with: `vec![0; len]`
@@ -49,7 +50,7 @@ LL | vec1.resize(len, 0);
| ^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:53:5
+ --> $DIR/slow_vector_initialization.rs:60:5
|
LL | let mut vec3 = Vec::with_capacity(len - 10);
| ---------------------------- help: consider replacing this with: `vec![0; len - 10]`
@@ -57,7 +58,7 @@ LL | vec3.resize(len - 10, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:56:5
+ --> $DIR/slow_vector_initialization.rs:64:5
|
LL | let mut vec4 = Vec::with_capacity(len);
| ----------------------- help: consider replacing this with: `vec![0; len]`
@@ -65,7 +66,7 @@ LL | vec4.resize(vec4.capacity(), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:60:5
+ --> $DIR/slow_vector_initialization.rs:69:5
|
LL | vec1 = Vec::with_capacity(10);
| ---------------------- help: consider replacing this with: `vec![0; 10]`
@@ -73,7 +74,7 @@ LL | vec1.resize(10, 0);
| ^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:67:5
+ --> $DIR/slow_vector_initialization.rs:77:5
|
LL | let mut vec1 = Vec::new();
| ---------- help: consider replacing this with: `vec![0; len]`
@@ -81,7 +82,7 @@ LL | vec1.resize(len, 0);
| ^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:71:5
+ --> $DIR/slow_vector_initialization.rs:82:5
|
LL | let mut vec3 = Vec::new();
| ---------- help: consider replacing this with: `vec![0; len - 10]`
@@ -89,12 +90,20 @@ LL | vec3.resize(len - 10, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: slow zero-filling initialization
- --> $DIR/slow_vector_initialization.rs:75:5
+ --> $DIR/slow_vector_initialization.rs:87:5
|
LL | vec1 = Vec::new();
| ---------- help: consider replacing this with: `vec![0; 10]`
LL | vec1.resize(10, 0);
| ^^^^^^^^^^^^^^^^^^
-error: aborting due to 12 previous errors
+error: slow zero-filling initialization
+ --> $DIR/slow_vector_initialization.rs:91:5
+ |
+LL | vec1 = vec![];
+ | ------ help: consider replacing this with: `vec![0; 10]`
+LL | vec1.resize(10, 0);
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 13 previous errors
diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.fixed b/src/tools/clippy/tests/ui/stable_sort_primitive.fixed
index 50c1fc71a..97f3a9223 100644
--- a/src/tools/clippy/tests/ui/stable_sort_primitive.fixed
+++ b/src/tools/clippy/tests/ui/stable_sort_primitive.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::stable_sort_primitive)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.rs b/src/tools/clippy/tests/ui/stable_sort_primitive.rs
index bd1bb428f..26e3d8e74 100644
--- a/src/tools/clippy/tests/ui/stable_sort_primitive.rs
+++ b/src/tools/clippy/tests/ui/stable_sort_primitive.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::stable_sort_primitive)]
#![allow(clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
index aa5d7b7e4..b66503328 100644
--- a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
+++ b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
@@ -1,14 +1,15 @@
error: used `sort` on primitive type `i32`
- --> $DIR/stable_sort_primitive.rs:8:5
+ --> $DIR/stable_sort_primitive.rs:7:5
|
LL | vec.sort();
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
|
= note: an unstable sort typically performs faster without any observable difference for this data type
= note: `-D clippy::stable-sort-primitive` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::stable_sort_primitive)]`
error: used `sort` on primitive type `bool`
- --> $DIR/stable_sort_primitive.rs:10:5
+ --> $DIR/stable_sort_primitive.rs:9:5
|
LL | vec.sort();
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
@@ -16,7 +17,7 @@ LL | vec.sort();
= note: an unstable sort typically performs faster without any observable difference for this data type
error: used `sort` on primitive type `char`
- --> $DIR/stable_sort_primitive.rs:12:5
+ --> $DIR/stable_sort_primitive.rs:11:5
|
LL | vec.sort();
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
@@ -24,7 +25,7 @@ LL | vec.sort();
= note: an unstable sort typically performs faster without any observable difference for this data type
error: used `sort` on primitive type `str`
- --> $DIR/stable_sort_primitive.rs:14:5
+ --> $DIR/stable_sort_primitive.rs:13:5
|
LL | vec.sort();
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
@@ -32,7 +33,7 @@ LL | vec.sort();
= note: an unstable sort typically performs faster without any observable difference for this data type
error: used `sort` on primitive type `tuple`
- --> $DIR/stable_sort_primitive.rs:16:5
+ --> $DIR/stable_sort_primitive.rs:15:5
|
LL | vec.sort();
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
@@ -40,7 +41,7 @@ LL | vec.sort();
= note: an unstable sort typically performs faster without any observable difference for this data type
error: used `sort` on primitive type `array`
- --> $DIR/stable_sort_primitive.rs:18:5
+ --> $DIR/stable_sort_primitive.rs:17:5
|
LL | vec.sort();
| ^^^^^^^^^^ help: try: `vec.sort_unstable()`
@@ -48,7 +49,7 @@ LL | vec.sort();
= note: an unstable sort typically performs faster without any observable difference for this data type
error: used `sort` on primitive type `i32`
- --> $DIR/stable_sort_primitive.rs:20:5
+ --> $DIR/stable_sort_primitive.rs:19:5
|
LL | arr.sort();
| ^^^^^^^^^^ help: try: `arr.sort_unstable()`
diff --git a/src/tools/clippy/tests/ui/starts_ends_with.fixed b/src/tools/clippy/tests/ui/starts_ends_with.fixed
index b7237069d..4a66ca7ec 100644
--- a/src/tools/clippy/tests/ui/starts_ends_with.fixed
+++ b/src/tools/clippy/tests/ui/starts_ends_with.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::needless_if, dead_code, unused_must_use)]
fn main() {}
diff --git a/src/tools/clippy/tests/ui/starts_ends_with.rs b/src/tools/clippy/tests/ui/starts_ends_with.rs
index 658312e87..16a68e02d 100644
--- a/src/tools/clippy/tests/ui/starts_ends_with.rs
+++ b/src/tools/clippy/tests/ui/starts_ends_with.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(clippy::needless_if, dead_code, unused_must_use)]
fn main() {}
diff --git a/src/tools/clippy/tests/ui/starts_ends_with.stderr b/src/tools/clippy/tests/ui/starts_ends_with.stderr
index 2dd9f53b8..c4c547949 100644
--- a/src/tools/clippy/tests/ui/starts_ends_with.stderr
+++ b/src/tools/clippy/tests/ui/starts_ends_with.stderr
@@ -1,102 +1,104 @@
error: you should use the `starts_with` method
- --> $DIR/starts_ends_with.rs:8:5
+ --> $DIR/starts_ends_with.rs:7:5
|
LL | "".chars().next() == Some(' ');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".starts_with(' ')`
|
= note: `-D clippy::chars-next-cmp` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::chars_next_cmp)]`
error: you should use the `starts_with` method
- --> $DIR/starts_ends_with.rs:9:5
+ --> $DIR/starts_ends_with.rs:8:5
|
LL | Some(' ') != "".chars().next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".starts_with(' ')`
error: you should use the `starts_with` method
- --> $DIR/starts_ends_with.rs:12:5
+ --> $DIR/starts_ends_with.rs:11:5
|
-LL | "".chars().next() == Some('/n');
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".starts_with('/n')`
+LL | "".chars().next() == Some('\n');
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".starts_with('\n')`
error: you should use the `starts_with` method
- --> $DIR/starts_ends_with.rs:13:5
+ --> $DIR/starts_ends_with.rs:12:5
|
-LL | Some('/n') != "".chars().next();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".starts_with('/n')`
+LL | Some('\n') != "".chars().next();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".starts_with('\n')`
error: you should use the `starts_with` method
- --> $DIR/starts_ends_with.rs:18:8
+ --> $DIR/starts_ends_with.rs:17:8
|
LL | if s.chars().next().unwrap() == 'f' {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.starts_with('f')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:22:8
+ --> $DIR/starts_ends_with.rs:21:8
|
LL | if s.chars().next_back().unwrap() == 'o' {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.ends_with('o')`
|
= note: `-D clippy::chars-last-cmp` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::chars_last_cmp)]`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:26:8
+ --> $DIR/starts_ends_with.rs:25:8
|
LL | if s.chars().last().unwrap() == 'o' {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.ends_with('o')`
error: you should use the `starts_with` method
- --> $DIR/starts_ends_with.rs:30:8
+ --> $DIR/starts_ends_with.rs:29:8
|
LL | if s.chars().next().unwrap() != 'f' {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.starts_with('f')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:34:8
+ --> $DIR/starts_ends_with.rs:33:8
|
LL | if s.chars().next_back().unwrap() != 'o' {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.ends_with('o')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:38:8
+ --> $DIR/starts_ends_with.rs:37:8
|
-LL | if s.chars().last().unwrap() != '/n' {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.ends_with('/n')`
+LL | if s.chars().last().unwrap() != '\n' {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.ends_with('\n')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:46:5
+ --> $DIR/starts_ends_with.rs:45:5
|
LL | "".chars().last() == Some(' ');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".ends_with(' ')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:47:5
+ --> $DIR/starts_ends_with.rs:46:5
|
LL | Some(' ') != "".chars().last();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".ends_with(' ')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:48:5
+ --> $DIR/starts_ends_with.rs:47:5
|
LL | "".chars().next_back() == Some(' ');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".ends_with(' ')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:49:5
+ --> $DIR/starts_ends_with.rs:48:5
|
LL | Some(' ') != "".chars().next_back();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".ends_with(' ')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:52:5
+ --> $DIR/starts_ends_with.rs:51:5
|
-LL | "".chars().last() == Some('/n');
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".ends_with('/n')`
+LL | "".chars().last() == Some('\n');
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `"".ends_with('\n')`
error: you should use the `ends_with` method
- --> $DIR/starts_ends_with.rs:53:5
+ --> $DIR/starts_ends_with.rs:52:5
|
-LL | Some('/n') != "".chars().last();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".ends_with('/n')`
+LL | Some('\n') != "".chars().last();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!"".ends_with('\n')`
error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.fixed b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
new file mode 100644
index 000000000..8027c053f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
@@ -0,0 +1,62 @@
+#![warn(clippy::std_instead_of_core)]
+#![allow(unused_imports)]
+
+extern crate alloc;
+
+#[warn(clippy::std_instead_of_core)]
+fn std_instead_of_core() {
+ // Regular import
+ use core::hash::Hasher;
+ //~^ ERROR: used import from `std` instead of `core`
+ // Absolute path
+ use ::core::hash::Hash;
+ //~^ ERROR: used import from `std` instead of `core`
+ // Don't lint on `env` macro
+ use std::env;
+
+ // Multiple imports
+ use core::fmt::{Debug, Result};
+ //~^ ERROR: used import from `std` instead of `core`
+
+ // Function calls
+ let ptr = core::ptr::null::<u32>();
+ //~^ ERROR: used import from `std` instead of `core`
+ let ptr_mut = ::core::ptr::null_mut::<usize>();
+ //~^ ERROR: used import from `std` instead of `core`
+
+ // Types
+ let cell = core::cell::Cell::new(8u32);
+ //~^ ERROR: used import from `std` instead of `core`
+ let cell_absolute = ::core::cell::Cell::new(8u32);
+ //~^ ERROR: used import from `std` instead of `core`
+
+ let _ = std::env!("PATH");
+
+ // do not lint until `error_in_core` is stable
+ use std::error::Error;
+
+ // lint items re-exported from private modules, `core::iter::traits::iterator::Iterator`
+ use core::iter::Iterator;
+ //~^ ERROR: used import from `std` instead of `core`
+}
+
+#[warn(clippy::std_instead_of_alloc)]
+fn std_instead_of_alloc() {
+ // Only lint once.
+ use alloc::vec;
+ //~^ ERROR: used import from `std` instead of `alloc`
+ use alloc::vec::Vec;
+ //~^ ERROR: used import from `std` instead of `alloc`
+}
+
+#[warn(clippy::alloc_instead_of_core)]
+fn alloc_instead_of_core() {
+ use core::slice::from_ref;
+ //~^ ERROR: used import from `alloc` instead of `core`
+}
+
+fn main() {
+ std_instead_of_core();
+ std_instead_of_alloc();
+ alloc_instead_of_core();
+}
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.rs b/src/tools/clippy/tests/ui/std_instead_of_core.rs
index 75b114ba0..63a096384 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.rs
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs
@@ -7,21 +7,28 @@ extern crate alloc;
fn std_instead_of_core() {
// Regular import
use std::hash::Hasher;
+ //~^ ERROR: used import from `std` instead of `core`
// Absolute path
use ::std::hash::Hash;
+ //~^ ERROR: used import from `std` instead of `core`
// Don't lint on `env` macro
use std::env;
// Multiple imports
use std::fmt::{Debug, Result};
+ //~^ ERROR: used import from `std` instead of `core`
// Function calls
let ptr = std::ptr::null::<u32>();
+ //~^ ERROR: used import from `std` instead of `core`
let ptr_mut = ::std::ptr::null_mut::<usize>();
+ //~^ ERROR: used import from `std` instead of `core`
// Types
let cell = std::cell::Cell::new(8u32);
+ //~^ ERROR: used import from `std` instead of `core`
let cell_absolute = ::std::cell::Cell::new(8u32);
+ //~^ ERROR: used import from `std` instead of `core`
let _ = std::env!("PATH");
@@ -30,18 +37,22 @@ fn std_instead_of_core() {
// lint items re-exported from private modules, `core::iter::traits::iterator::Iterator`
use std::iter::Iterator;
+ //~^ ERROR: used import from `std` instead of `core`
}
#[warn(clippy::std_instead_of_alloc)]
fn std_instead_of_alloc() {
// Only lint once.
use std::vec;
+ //~^ ERROR: used import from `std` instead of `alloc`
use std::vec::Vec;
+ //~^ ERROR: used import from `std` instead of `alloc`
}
#[warn(clippy::alloc_instead_of_core)]
fn alloc_instead_of_core() {
use alloc::slice::from_ref;
+ //~^ ERROR: used import from `alloc` instead of `core`
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
index d21024973..ca26f77bd 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
@@ -2,100 +2,76 @@ error: used import from `std` instead of `core`
--> $DIR/std_instead_of_core.rs:9:9
|
LL | use std::hash::Hasher;
- | ^^^^^^^^^^^^^^^^^
+ | ^^^ help: consider importing the item from `core`: `core`
|
- = help: consider importing the item from `core`
= note: `-D clippy::std-instead-of-core` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`
error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:11:9
+ --> $DIR/std_instead_of_core.rs:12:11
|
LL | use ::std::hash::Hash;
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider importing the item from `core`
-
-error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:16:20
- |
-LL | use std::fmt::{Debug, Result};
- | ^^^^^
- |
- = help: consider importing the item from `core`
+ | ^^^ help: consider importing the item from `core`: `core`
error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:16:27
+ --> $DIR/std_instead_of_core.rs:18:9
|
LL | use std::fmt::{Debug, Result};
- | ^^^^^^
- |
- = help: consider importing the item from `core`
+ | ^^^ help: consider importing the item from `core`: `core`
error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:19:15
+ --> $DIR/std_instead_of_core.rs:22:15
|
LL | let ptr = std::ptr::null::<u32>();
- | ^^^^^^^^^^^^^^^^^^^^^
- |
- = help: consider importing the item from `core`
+ | ^^^ help: consider importing the item from `core`: `core`
error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:20:19
+ --> $DIR/std_instead_of_core.rs:24:21
|
LL | let ptr_mut = ::std::ptr::null_mut::<usize>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: consider importing the item from `core`
+ | ^^^ help: consider importing the item from `core`: `core`
error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:23:16
+ --> $DIR/std_instead_of_core.rs:28:16
|
LL | let cell = std::cell::Cell::new(8u32);
- | ^^^^^^^^^^^^^^^
- |
- = help: consider importing the item from `core`
+ | ^^^ help: consider importing the item from `core`: `core`
error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:24:25
+ --> $DIR/std_instead_of_core.rs:30:27
|
LL | let cell_absolute = ::std::cell::Cell::new(8u32);
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider importing the item from `core`
+ | ^^^ help: consider importing the item from `core`: `core`
error: used import from `std` instead of `core`
- --> $DIR/std_instead_of_core.rs:32:9
+ --> $DIR/std_instead_of_core.rs:39:9
|
LL | use std::iter::Iterator;
- | ^^^^^^^^^^^^^^^^^^^
- |
- = help: consider importing the item from `core`
+ | ^^^ help: consider importing the item from `core`: `core`
error: used import from `std` instead of `alloc`
- --> $DIR/std_instead_of_core.rs:38:9
+ --> $DIR/std_instead_of_core.rs:46:9
|
LL | use std::vec;
- | ^^^^^^^^
+ | ^^^ help: consider importing the item from `alloc`: `alloc`
|
- = help: consider importing the item from `alloc`
= note: `-D clippy::std-instead-of-alloc` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`
error: used import from `std` instead of `alloc`
- --> $DIR/std_instead_of_core.rs:39:9
+ --> $DIR/std_instead_of_core.rs:48:9
|
LL | use std::vec::Vec;
- | ^^^^^^^^^^^^^
- |
- = help: consider importing the item from `alloc`
+ | ^^^ help: consider importing the item from `alloc`: `alloc`
error: used import from `alloc` instead of `core`
- --> $DIR/std_instead_of_core.rs:44:9
+ --> $DIR/std_instead_of_core.rs:54:9
|
LL | use alloc::slice::from_ref;
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^ help: consider importing the item from `core`: `core`
|
- = help: consider importing the item from `core`
= note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`
-error: aborting due to 12 previous errors
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/str_to_string.rs b/src/tools/clippy/tests/ui/str_to_string.rs
index 08f734025..f93b289c2 100644
--- a/src/tools/clippy/tests/ui/str_to_string.rs
+++ b/src/tools/clippy/tests/ui/str_to_string.rs
@@ -2,6 +2,8 @@
fn main() {
let hello = "hello world".to_string();
+ //~^ ERROR: `to_string()` called on a `&str`
let msg = &hello[..];
msg.to_string();
+ //~^ ERROR: `to_string()` called on a `&str`
}
diff --git a/src/tools/clippy/tests/ui/str_to_string.stderr b/src/tools/clippy/tests/ui/str_to_string.stderr
index 1d47da571..203805eca 100644
--- a/src/tools/clippy/tests/ui/str_to_string.stderr
+++ b/src/tools/clippy/tests/ui/str_to_string.stderr
@@ -6,9 +6,10 @@ LL | let hello = "hello world".to_string();
|
= help: consider using `.to_owned()`
= note: `-D clippy::str-to-string` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::str_to_string)]`
error: `to_string()` called on a `&str`
- --> $DIR/str_to_string.rs:6:5
+ --> $DIR/str_to_string.rs:7:5
|
LL | msg.to_string();
| ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/string_add.rs b/src/tools/clippy/tests/ui/string_add.rs
index 6980242ae..c535f2ebb 100644
--- a/src/tools/clippy/tests/ui/string_add.rs
+++ b/src/tools/clippy/tests/ui/string_add.rs
@@ -1,5 +1,5 @@
-//@aux-build:proc_macros.rs:proc-macro
-
+//@aux-build:proc_macros.rs
+//@no-rustfix
extern crate proc_macros;
use proc_macros::external;
diff --git a/src/tools/clippy/tests/ui/string_add.stderr b/src/tools/clippy/tests/ui/string_add.stderr
index 3987641c7..892753b90 100644
--- a/src/tools/clippy/tests/ui/string_add.stderr
+++ b/src/tools/clippy/tests/ui/string_add.stderr
@@ -5,6 +5,7 @@ LL | x = x + ".";
| ^^^^^^^^^^^ help: replace it with: `x += "."`
|
= note: `-D clippy::assign-op-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]`
error: you added something to a string. Consider using `String::push_str()` instead
--> $DIR/string_add.rs:13:13
@@ -13,6 +14,7 @@ LL | x = x + ".";
| ^^^^^^^
|
= note: `-D clippy::string-add` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_add)]`
error: you added something to a string. Consider using `String::push_str()` instead
--> $DIR/string_add.rs:17:13
diff --git a/src/tools/clippy/tests/ui/string_add_assign.fixed b/src/tools/clippy/tests/ui/string_add_assign.fixed
index 616c6daaf..31d84831d 100644
--- a/src/tools/clippy/tests/ui/string_add_assign.fixed
+++ b/src/tools/clippy/tests/ui/string_add_assign.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[allow(clippy::string_add, unused)]
#[warn(clippy::string_add_assign)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/string_add_assign.rs b/src/tools/clippy/tests/ui/string_add_assign.rs
index e1f885975..cdea91573 100644
--- a/src/tools/clippy/tests/ui/string_add_assign.rs
+++ b/src/tools/clippy/tests/ui/string_add_assign.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[allow(clippy::string_add, unused)]
#[warn(clippy::string_add_assign)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/string_add_assign.stderr b/src/tools/clippy/tests/ui/string_add_assign.stderr
index 7676175c1..7d37c98a8 100644
--- a/src/tools/clippy/tests/ui/string_add_assign.stderr
+++ b/src/tools/clippy/tests/ui/string_add_assign.stderr
@@ -1,21 +1,23 @@
error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead
- --> $DIR/string_add_assign.rs:10:9
+ --> $DIR/string_add_assign.rs:8:9
|
LL | x = x + ".";
| ^^^^^^^^^^^
|
= note: `-D clippy::string-add-assign` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_add_assign)]`
error: manual implementation of an assign operation
- --> $DIR/string_add_assign.rs:10:9
+ --> $DIR/string_add_assign.rs:8:9
|
LL | x = x + ".";
| ^^^^^^^^^^^ help: replace it with: `x += "."`
|
= note: `-D clippy::assign-op-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]`
error: manual implementation of an assign operation
- --> $DIR/string_add_assign.rs:19:5
+ --> $DIR/string_add_assign.rs:17:5
|
LL | x = x + 1;
| ^^^^^^^^^ help: replace it with: `x += 1`
diff --git a/src/tools/clippy/tests/ui/string_extend.fixed b/src/tools/clippy/tests/ui/string_extend.fixed
index 65c9abff3..142cb6a34 100644
--- a/src/tools/clippy/tests/ui/string_extend.fixed
+++ b/src/tools/clippy/tests/ui/string_extend.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[derive(Copy, Clone)]
struct HasChars;
diff --git a/src/tools/clippy/tests/ui/string_extend.rs b/src/tools/clippy/tests/ui/string_extend.rs
index 5f72ffe2f..41c0d29fa 100644
--- a/src/tools/clippy/tests/ui/string_extend.rs
+++ b/src/tools/clippy/tests/ui/string_extend.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#[derive(Copy, Clone)]
struct HasChars;
diff --git a/src/tools/clippy/tests/ui/string_extend.stderr b/src/tools/clippy/tests/ui/string_extend.stderr
index 34b432901..e063d87e3 100644
--- a/src/tools/clippy/tests/ui/string_extend.stderr
+++ b/src/tools/clippy/tests/ui/string_extend.stderr
@@ -1,25 +1,26 @@
error: calling `.extend(_.chars())`
- --> $DIR/string_extend.rs:18:5
+ --> $DIR/string_extend.rs:16:5
|
LL | s.extend(abc.chars());
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(abc)`
|
= note: `-D clippy::string-extend-chars` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_extend_chars)]`
error: calling `.extend(_.chars())`
- --> $DIR/string_extend.rs:21:5
+ --> $DIR/string_extend.rs:19:5
|
LL | s.extend("abc".chars());
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str("abc")`
error: calling `.extend(_.chars())`
- --> $DIR/string_extend.rs:24:5
+ --> $DIR/string_extend.rs:22:5
|
LL | s.extend(def.chars());
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&def)`
error: calling `.extend(_.chars())`
- --> $DIR/string_extend.rs:34:5
+ --> $DIR/string_extend.rs:32:5
|
LL | s.extend(abc[0..2].chars());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&abc[0..2])`
diff --git a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed
index 9b315ae2b..6aa5a95c6 100644
--- a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed
+++ b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::string_from_utf8_as_bytes)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs
index 043dd2350..c8717f795 100644
--- a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs
+++ b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::string_from_utf8_as_bytes)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr
index bf5e5d33e..cf5688a97 100644
--- a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr
+++ b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.stderr
@@ -1,10 +1,11 @@
error: calling a slice of `as_bytes()` with `from_utf8` should be not necessary
- --> $DIR/string_from_utf8_as_bytes.rs:5:13
+ --> $DIR/string_from_utf8_as_bytes.rs:4:13
|
LL | let _ = std::str::from_utf8(&"Hello World!".as_bytes()[6..11]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&"Hello World!"[6..11])`
|
= note: `-D clippy::string-from-utf8-as-bytes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_from_utf8_as_bytes)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed b/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed
index 0edd81acc..225d4e90c 100644
--- a/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed
+++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:macro_rules.rs
#![allow(clippy::needless_raw_string_hashes, dead_code, unused_variables)]
diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.rs b/src/tools/clippy/tests/ui/string_lit_as_bytes.rs
index 2647f02f0..3d116214c 100644
--- a/src/tools/clippy/tests/ui/string_lit_as_bytes.rs
+++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:macro_rules.rs
#![allow(clippy::needless_raw_string_hashes, dead_code, unused_variables)]
diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr b/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr
index 61b4e210e..1c12cb8e5 100644
--- a/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr
+++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.stderr
@@ -1,31 +1,32 @@
error: calling `as_bytes()` on a string literal
- --> $DIR/string_lit_as_bytes.rs:17:14
+ --> $DIR/string_lit_as_bytes.rs:16:14
|
LL | let bs = "hello there".as_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"hello there"`
|
= note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_lit_as_bytes)]`
error: calling `as_bytes()` on a string literal
- --> $DIR/string_lit_as_bytes.rs:19:14
+ --> $DIR/string_lit_as_bytes.rs:18:14
|
LL | let bs = r###"raw string with 3# plus " ""###.as_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with 3# plus " ""###`
error: calling `into_bytes()` on a string literal
- --> $DIR/string_lit_as_bytes.rs:21:14
+ --> $DIR/string_lit_as_bytes.rs:20:14
|
LL | let bs = "lit to string".to_string().into_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to string".to_vec()`
error: calling `into_bytes()` on a string literal
- --> $DIR/string_lit_as_bytes.rs:22:14
+ --> $DIR/string_lit_as_bytes.rs:21:14
|
LL | let bs = "lit to owned".to_owned().into_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to owned".to_vec()`
error: calling `as_bytes()` on a string literal
- --> $DIR/string_lit_as_bytes.rs:12:26
+ --> $DIR/string_lit_as_bytes.rs:11:26
|
LL | const B: &[u8] = $b.as_bytes();
| ^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"warning"`
@@ -36,16 +37,16 @@ LL | b!("warning");
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
error: calling `as_bytes()` on `include_str!(..)`
- --> $DIR/string_lit_as_bytes.rs:39:22
+ --> $DIR/string_lit_as_bytes.rs:38:22
|
LL | let includestr = include_str!("string_lit_as_bytes.rs").as_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("string_lit_as_bytes.rs")`
error: calling `as_bytes()` on a string literal
- --> $DIR/string_lit_as_bytes.rs:41:13
+ --> $DIR/string_lit_as_bytes.rs:40:13
|
-LL | let _ = "string with newline/t/n".as_bytes();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline/t/n"`
+LL | let _ = "string with newline\t\n".as_bytes();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline\t\n"`
error: aborting due to 7 previous errors
diff --git a/src/tools/clippy/tests/ui/string_lit_chars_any.fixed b/src/tools/clippy/tests/ui/string_lit_chars_any.fixed
index d7ab9c339..03e20c16e 100644
--- a/src/tools/clippy/tests/ui/string_lit_chars_any.fixed
+++ b/src/tools/clippy/tests/ui/string_lit_chars_any.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::eq_op, clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
#![warn(clippy::string_lit_chars_any)]
diff --git a/src/tools/clippy/tests/ui/string_lit_chars_any.rs b/src/tools/clippy/tests/ui/string_lit_chars_any.rs
index 9408d7bb2..12e6ffb6a 100644
--- a/src/tools/clippy/tests/ui/string_lit_chars_any.rs
+++ b/src/tools/clippy/tests/ui/string_lit_chars_any.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::eq_op, clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
#![warn(clippy::string_lit_chars_any)]
diff --git a/src/tools/clippy/tests/ui/string_lit_chars_any.stderr b/src/tools/clippy/tests/ui/string_lit_chars_any.stderr
index ff951b73d..09c4f02eb 100644
--- a/src/tools/clippy/tests/ui/string_lit_chars_any.stderr
+++ b/src/tools/clippy/tests/ui/string_lit_chars_any.stderr
@@ -1,57 +1,58 @@
error: usage of `.chars().any(...)` to check if a char matches any from a string literal
- --> $DIR/string_lit_chars_any.rs:19:5
+ --> $DIR/string_lit_chars_any.rs:18:5
|
-LL | "//.+*?()|[]{}^$#&-~".chars().any(|x| x == c);
+LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::string-lit-chars-any` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_lit_chars_any)]`
help: use `matches!(...)` instead
|
-LL | matches!(c, '//' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: usage of `.chars().any(...)` to check if a char matches any from a string literal
- --> $DIR/string_lit_chars_any.rs:20:5
+ --> $DIR/string_lit_chars_any.rs:19:5
|
-LL | r#"/.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c);
+LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `matches!(...)` instead
|
-LL | matches!(c, '//' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: usage of `.chars().any(...)` to check if a char matches any from a string literal
- --> $DIR/string_lit_chars_any.rs:21:5
+ --> $DIR/string_lit_chars_any.rs:20:5
|
-LL | "//.+*?()|[]{}^$#&-~".chars().any(|x| c == x);
+LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `matches!(...)` instead
|
-LL | matches!(c, '//' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: usage of `.chars().any(...)` to check if a char matches any from a string literal
- --> $DIR/string_lit_chars_any.rs:22:5
+ --> $DIR/string_lit_chars_any.rs:21:5
|
-LL | r#"/.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x);
+LL | r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `matches!(...)` instead
|
-LL | matches!(c, '//' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: usage of `.chars().any(...)` to check if a char matches any from a string literal
- --> $DIR/string_lit_chars_any.rs:24:5
+ --> $DIR/string_lit_chars_any.rs:23:5
|
-LL | "//.+*?()|[]{}^$#&-~".chars().any(|x| { x == c });
+LL | "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `matches!(...)` instead
|
-LL | matches!(c, '//' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+LL | matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/string_slice.rs b/src/tools/clippy/tests/ui/string_slice.rs
index be4dfc881..440a86b10 100644
--- a/src/tools/clippy/tests/ui/string_slice.rs
+++ b/src/tools/clippy/tests/ui/string_slice.rs
@@ -3,8 +3,12 @@
fn main() {
&"Ölkanne"[1..];
+ //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character
+ //~| NOTE: `-D clippy::string-slice` implied by `-D warnings`
let m = "Mötörhead";
&m[2..5];
+ //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character
let s = String::from(m);
&s[0..2];
+ //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character
}
diff --git a/src/tools/clippy/tests/ui/string_slice.stderr b/src/tools/clippy/tests/ui/string_slice.stderr
index 55040bf5d..e9e773aaf 100644
--- a/src/tools/clippy/tests/ui/string_slice.stderr
+++ b/src/tools/clippy/tests/ui/string_slice.stderr
@@ -5,15 +5,16 @@ LL | &"Ölkanne"[1..];
| ^^^^^^^^^^^^^^
|
= note: `-D clippy::string-slice` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_slice)]`
error: indexing into a string may panic if the index is within a UTF-8 character
- --> $DIR/string_slice.rs:7:6
+ --> $DIR/string_slice.rs:9:6
|
LL | &m[2..5];
| ^^^^^^^
error: indexing into a string may panic if the index is within a UTF-8 character
- --> $DIR/string_slice.rs:9:6
+ --> $DIR/string_slice.rs:12:6
|
LL | &s[0..2];
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/string_to_string.rs b/src/tools/clippy/tests/ui/string_to_string.rs
index 4c66855f7..007685b60 100644
--- a/src/tools/clippy/tests/ui/string_to_string.rs
+++ b/src/tools/clippy/tests/ui/string_to_string.rs
@@ -4,4 +4,5 @@
fn main() {
let mut message = String::from("Hello");
let mut v = message.to_string();
+ //~^ ERROR: `to_string()` called on a `String`
}
diff --git a/src/tools/clippy/tests/ui/string_to_string.stderr b/src/tools/clippy/tests/ui/string_to_string.stderr
index e304c3e34..27a844315 100644
--- a/src/tools/clippy/tests/ui/string_to_string.stderr
+++ b/src/tools/clippy/tests/ui/string_to_string.stderr
@@ -6,6 +6,7 @@ LL | let mut v = message.to_string();
|
= help: consider using `.clone()`
= note: `-D clippy::string-to-string` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::string_to_string)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
index ef207e28c..8304e2afd 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::strlen_on_c_strings)]
#![allow(dead_code)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
index 03ec5f79d..deba40a9e 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::strlen_on_c_strings)]
#![allow(dead_code)]
#![feature(rustc_private)]
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr b/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr
index fcd17f689..6d8ad3981 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr
@@ -1,43 +1,44 @@
error: using `libc::strlen` on a `CString` or `CStr` value
- --> $DIR/strlen_on_c_strings.rs:15:13
+ --> $DIR/strlen_on_c_strings.rs:13:13
|
LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstring.as_bytes().len()`
|
= note: `-D clippy::strlen-on-c-strings` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`
error: using `libc::strlen` on a `CString` or `CStr` value
- --> $DIR/strlen_on_c_strings.rs:19:13
+ --> $DIR/strlen_on_c_strings.rs:17:13
|
LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
- --> $DIR/strlen_on_c_strings.rs:21:13
+ --> $DIR/strlen_on_c_strings.rs:19:13
|
LL | let _ = unsafe { strlen(cstr.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
- --> $DIR/strlen_on_c_strings.rs:24:22
+ --> $DIR/strlen_on_c_strings.rs:22:22
|
LL | let _ = unsafe { strlen((*pcstr).as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
- --> $DIR/strlen_on_c_strings.rs:29:22
+ --> $DIR/strlen_on_c_strings.rs:27:22
|
LL | let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
- --> $DIR/strlen_on_c_strings.rs:30:13
+ --> $DIR/strlen_on_c_strings.rs:28:13
|
LL | let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
error: using `libc::strlen` on a `CString` or `CStr` value
- --> $DIR/strlen_on_c_strings.rs:33:22
+ --> $DIR/strlen_on_c_strings.rs:31:22
|
LL | let _ = unsafe { strlen(f(cstr).as_ptr()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()`
diff --git a/src/tools/clippy/tests/ui/struct_excessive_bools.rs b/src/tools/clippy/tests/ui/struct_excessive_bools.rs
index ce4fe830a..8137ce7a8 100644
--- a/src/tools/clippy/tests/ui/struct_excessive_bools.rs
+++ b/src/tools/clippy/tests/ui/struct_excessive_bools.rs
@@ -20,6 +20,7 @@ struct Foo {
}
struct BadFoo {
+ //~^ ERROR: more than 3 bools in a struct
a: bool,
b: bool,
c: bool,
@@ -36,6 +37,7 @@ struct Bar {
fn main() {
struct FooFoo {
+ //~^ ERROR: more than 3 bools in a struct
a: bool,
b: bool,
c: bool,
diff --git a/src/tools/clippy/tests/ui/struct_excessive_bools.stderr b/src/tools/clippy/tests/ui/struct_excessive_bools.stderr
index e4d50043a..5284949c2 100644
--- a/src/tools/clippy/tests/ui/struct_excessive_bools.stderr
+++ b/src/tools/clippy/tests/ui/struct_excessive_bools.stderr
@@ -2,6 +2,7 @@ error: more than 3 bools in a struct
--> $DIR/struct_excessive_bools.rs:22:1
|
LL | / struct BadFoo {
+LL | |
LL | | a: bool,
LL | | b: bool,
LL | | c: bool,
@@ -11,11 +12,13 @@ LL | | }
|
= help: consider using a state machine or refactoring bools into two-variant enums
= note: `-D clippy::struct-excessive-bools` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::struct_excessive_bools)]`
error: more than 3 bools in a struct
- --> $DIR/struct_excessive_bools.rs:38:5
+ --> $DIR/struct_excessive_bools.rs:39:5
|
LL | / struct FooFoo {
+LL | |
LL | | a: bool,
LL | | b: bool,
LL | | c: bool,
diff --git a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs
index ae253a048..1bd4cd5fb 100644
--- a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs
+++ b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs
@@ -11,12 +11,16 @@ impl Add for Foo {
fn add(self, other: Self) -> Self {
Foo(self.0 - other.0)
+ //~^ ERROR: suspicious use of `-` in `Add` impl
+ //~| NOTE: `-D clippy::suspicious-arithmetic-impl` implied by `-D warnings`
}
}
impl AddAssign for Foo {
fn add_assign(&mut self, other: Foo) {
*self = *self - other;
+ //~^ ERROR: suspicious use of `-` in `AddAssign` impl
+ //~| NOTE: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings`
}
}
@@ -30,6 +34,7 @@ impl BitOrAssign for Foo {
impl MulAssign for Foo {
fn mul_assign(&mut self, other: Foo) {
self.0 /= other.0;
+ //~^ ERROR: suspicious use of `/` in `MulAssign` impl
}
}
@@ -68,6 +73,7 @@ impl Rem for Foo {
fn rem(self, other: Self) -> Self {
Foo(self.0 / other.0)
+ //~^ ERROR: suspicious use of `/` in `Rem` impl
}
}
@@ -76,6 +82,7 @@ impl BitAnd for Foo {
fn bitand(self, other: Self) -> Self {
Foo(self.0 | other.0)
+ //~^ ERROR: suspicious use of `|` in `BitAnd` impl
}
}
@@ -84,6 +91,7 @@ impl BitOr for Foo {
fn bitor(self, other: Self) -> Self {
Foo(self.0 ^ other.0)
+ //~^ ERROR: suspicious use of `^` in `BitOr` impl
}
}
@@ -92,6 +100,7 @@ impl BitXor for Foo {
fn bitxor(self, other: Self) -> Self {
Foo(self.0 & other.0)
+ //~^ ERROR: suspicious use of `&` in `BitXor` impl
}
}
@@ -100,6 +109,7 @@ impl Shl for Foo {
fn shl(self, other: Self) -> Self {
Foo(self.0 >> other.0)
+ //~^ ERROR: suspicious use of `>>` in `Shl` impl
}
}
@@ -108,6 +118,7 @@ impl Shr for Foo {
fn shr(self, other: Self) -> Self {
Foo(self.0 << other.0)
+ //~^ ERROR: suspicious use of `<<` in `Shr` impl
}
}
diff --git a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
index ced130587..3995c6eb5 100644
--- a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
@@ -5,53 +5,55 @@ LL | Foo(self.0 - other.0)
| ^
|
= note: `-D clippy::suspicious-arithmetic-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_arithmetic_impl)]`
error: suspicious use of `-` in `AddAssign` impl
- --> $DIR/suspicious_arithmetic_impl.rs:19:23
+ --> $DIR/suspicious_arithmetic_impl.rs:21:23
|
LL | *self = *self - other;
| ^
|
= note: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_op_assign_impl)]`
error: suspicious use of `/` in `MulAssign` impl
- --> $DIR/suspicious_arithmetic_impl.rs:32:16
+ --> $DIR/suspicious_arithmetic_impl.rs:36:16
|
LL | self.0 /= other.0;
| ^^
error: suspicious use of `/` in `Rem` impl
- --> $DIR/suspicious_arithmetic_impl.rs:70:20
+ --> $DIR/suspicious_arithmetic_impl.rs:75:20
|
LL | Foo(self.0 / other.0)
| ^
error: suspicious use of `|` in `BitAnd` impl
- --> $DIR/suspicious_arithmetic_impl.rs:78:20
+ --> $DIR/suspicious_arithmetic_impl.rs:84:20
|
LL | Foo(self.0 | other.0)
| ^
error: suspicious use of `^` in `BitOr` impl
- --> $DIR/suspicious_arithmetic_impl.rs:86:20
+ --> $DIR/suspicious_arithmetic_impl.rs:93:20
|
LL | Foo(self.0 ^ other.0)
| ^
error: suspicious use of `&` in `BitXor` impl
- --> $DIR/suspicious_arithmetic_impl.rs:94:20
+ --> $DIR/suspicious_arithmetic_impl.rs:102:20
|
LL | Foo(self.0 & other.0)
| ^
error: suspicious use of `>>` in `Shl` impl
- --> $DIR/suspicious_arithmetic_impl.rs:102:20
+ --> $DIR/suspicious_arithmetic_impl.rs:111:20
|
LL | Foo(self.0 >> other.0)
| ^^
error: suspicious use of `<<` in `Shr` impl
- --> $DIR/suspicious_arithmetic_impl.rs:110:20
+ --> $DIR/suspicious_arithmetic_impl.rs:120:20
|
LL | Foo(self.0 << other.0)
| ^^
diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed b/src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed
new file mode 100644
index 000000000..5d7b1e0c1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed
@@ -0,0 +1,13 @@
+fn main() {
+ // Things it should warn about:
+ std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap();
+ //~^ ERROR: single argument that looks like it should be multiple arguments
+ //~| NOTE: `-D clippy::suspicious-command-arg-space` implied by `-D warnings`
+ std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap();
+ //~^ ERROR: single argument that looks like it should be multiple arguments
+
+ // Things it should not warn about:
+ std::process::Command::new("echo").arg("hello world").spawn().unwrap();
+ std::process::Command::new("a").arg("--fmt=%a %b %c").spawn().unwrap();
+ std::process::Command::new("b").arg("-ldflags=-s -w").spawn().unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs b/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs
index bdc6113a2..8abd9803a 100644
--- a/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs
+++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs
@@ -1,7 +1,10 @@
fn main() {
// Things it should warn about:
std::process::Command::new("echo").arg("-n hello").spawn().unwrap();
+ //~^ ERROR: single argument that looks like it should be multiple arguments
+ //~| NOTE: `-D clippy::suspicious-command-arg-space` implied by `-D warnings`
std::process::Command::new("cat").arg("--number file").spawn().unwrap();
+ //~^ ERROR: single argument that looks like it should be multiple arguments
// Things it should not warn about:
std::process::Command::new("echo").arg("hello world").spawn().unwrap();
diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
index 9bc0ca93a..9bf3128cb 100644
--- a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
@@ -5,13 +5,14 @@ LL | std::process::Command::new("echo").arg("-n hello").spawn().unwrap();
| ^^^^^^^^^^
|
= note: `-D clippy::suspicious-command-arg-space` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_command_arg_space)]`
help: consider splitting the argument
|
LL | std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap();
| ~~~~ ~~~~~~~~~~~~~~~
error: single argument that looks like it should be multiple arguments
- --> $DIR/suspicious_command_arg_space.rs:4:43
+ --> $DIR/suspicious_command_arg_space.rs:6:43
|
LL | std::process::Command::new("cat").arg("--number file").spawn().unwrap();
| ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
index bffda1cc4..614fc0357 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::suspicious_doc_comments)]
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
index cdd972ee3..7dcba0fef 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(unused)]
#![warn(clippy::suspicious_doc_comments)]
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
index 6c167df27..1b238f501 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
@@ -1,17 +1,18 @@
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:6:1
+ --> $DIR/suspicious_doc_comments.rs:5:1
|
LL | ///! Fake module documentation.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::suspicious-doc-comments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_doc_comments)]`
help: use an inner doc comment to document the parent module or crate
|
LL | //! Fake module documentation.
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:10:5
+ --> $DIR/suspicious_doc_comments.rs:9:5
|
LL | ///! This module contains useful functions.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | //! This module contains useful functions.
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:22:5
+ --> $DIR/suspicious_doc_comments.rs:21:5
|
LL | / /**! This module contains useful functions.
LL | | */
@@ -35,7 +36,7 @@ LL + */
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:36:5
+ --> $DIR/suspicious_doc_comments.rs:35:5
|
LL | / ///! This module
LL | | ///! contains
@@ -50,7 +51,7 @@ LL ~ //! useful functions.
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:44:5
+ --> $DIR/suspicious_doc_comments.rs:43:5
|
LL | / ///! a
LL | | ///! b
@@ -63,7 +64,7 @@ LL ~ //! b
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:52:5
+ --> $DIR/suspicious_doc_comments.rs:51:5
|
LL | ///! a
| ^^^^^^
@@ -74,7 +75,7 @@ LL | //! a
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:58:5
+ --> $DIR/suspicious_doc_comments.rs:57:5
|
LL | / ///! a
LL | |
@@ -89,7 +90,7 @@ LL ~ //! b
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:70:5
+ --> $DIR/suspicious_doc_comments.rs:69:5
|
LL | ///! Very cool macro
| ^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +101,7 @@ LL | //! Very cool macro
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments.rs:77:5
+ --> $DIR/suspicious_doc_comments.rs:76:5
|
LL | ///! Huh.
| ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs
index ad98c7f49..9e9c47757 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.rs
@@ -1,13 +1,16 @@
#![allow(unused)]
#![warn(clippy::suspicious_doc_comments)]
-
+//@no-rustfix
///! a
+//~^ ERROR: this is an outer doc comment and does not apply to the parent module or crate
+//~| NOTE: `-D clippy::suspicious-doc-comments` implied by `-D warnings`
///! b
/// c
///! d
pub fn foo() {}
///! a
+//~^ ERROR: this is an outer doc comment and does not apply to the parent module or crate
///! b
/// c
///! d
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr
index f89146dad..ae92c334f 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr
@@ -2,24 +2,30 @@ error: this is an outer doc comment and does not apply to the parent module or c
--> $DIR/suspicious_doc_comments_unfixable.rs:4:1
|
LL | / ///! a
+LL | |
+LL | |
LL | | ///! b
LL | | /// c
LL | | ///! d
| |______^
|
= note: `-D clippy::suspicious-doc-comments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_doc_comments)]`
help: use an inner doc comment to document the parent module or crate
|
LL + //! a
+LL |
+LL |
LL + //! b
LL | /// c
LL + //! d
|
error: this is an outer doc comment and does not apply to the parent module or crate
- --> $DIR/suspicious_doc_comments_unfixable.rs:10:1
+ --> $DIR/suspicious_doc_comments_unfixable.rs:12:1
|
LL | / ///! a
+LL | |
LL | | ///! b
LL | | /// c
LL | | ///! d
@@ -28,6 +34,7 @@ LL | | ///! d
help: use an inner doc comment to document the parent module or crate
|
LL + //! a
+LL |
LL + //! b
LL | /// c
LL + //! d
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
index 0473ccdc3..c0856427e 100644
--- a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macro_suspicious_else_formatting.rs:proc-macro
+//@aux-build:proc_macro_suspicious_else_formatting.rs
#![warn(clippy::suspicious_else_formatting)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
index 723fdd7e9..95047cb95 100644
--- a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
@@ -6,6 +6,7 @@ LL | } {
|
= note: to remove this lint, add the missing `else` or add a new line before the next block
= note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_else_formatting)]`
error: this looks like an `else if` but the `else` is missing
--> $DIR/suspicious_else_formatting.rs:26:6
diff --git a/src/tools/clippy/tests/ui/suspicious_map.rs b/src/tools/clippy/tests/ui/suspicious_map.rs
index 3a2a10cf0..d4247fcd9 100644
--- a/src/tools/clippy/tests/ui/suspicious_map.rs
+++ b/src/tools/clippy/tests/ui/suspicious_map.rs
@@ -2,9 +2,11 @@
fn main() {
let _ = (0..3).map(|x| x + 2).count();
+ //~^ ERROR: this call to `map()` won't have an effect on the call to `count()`
let f = |x| x + 1;
let _ = (0..3).map(f).count();
+ //~^ ERROR: this call to `map()` won't have an effect on the call to `count()`
}
fn negative() {
diff --git a/src/tools/clippy/tests/ui/suspicious_map.stderr b/src/tools/clippy/tests/ui/suspicious_map.stderr
index e25167481..9c065e05c 100644
--- a/src/tools/clippy/tests/ui/suspicious_map.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_map.stderr
@@ -6,9 +6,10 @@ LL | let _ = (0..3).map(|x| x + 2).count();
|
= help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`
= note: `-D clippy::suspicious-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]`
error: this call to `map()` won't have an effect on the call to `count()`
- --> $DIR/suspicious_map.rs:7:13
+ --> $DIR/suspicious_map.rs:8:13
|
LL | let _ = (0..3).map(f).count();
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
index 0e37701ec..9d9732307 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suspicious_operation_groupings)]
#![allow(dead_code, unused_parens, clippy::eq_op)]
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
index dd4f3b71c..201b8e657 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::suspicious_operation_groupings)]
#![allow(dead_code, unused_parens, clippy::eq_op)]
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr b/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
index 29f229245..0784da06e 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
@@ -1,157 +1,158 @@
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:16:9
+ --> $DIR/suspicious_operation_groupings.rs:15:9
|
LL | self.x == other.y && self.y == other.y && self.z == other.z
| ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x`
|
= note: `-D clippy::suspicious-operation-groupings` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_operation_groupings)]`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:29:20
+ --> $DIR/suspicious_operation_groupings.rs:28:20
|
LL | s1.a < s2.a && s1.a < s2.b
| ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:77:33
+ --> $DIR/suspicious_operation_groupings.rs:76:33
|
LL | s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:82:19
+ --> $DIR/suspicious_operation_groupings.rs:81:19
|
LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:82:19
+ --> $DIR/suspicious_operation_groupings.rs:81:19
|
LL | s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:87:19
+ --> $DIR/suspicious_operation_groupings.rs:86:19
|
LL | s1.a * s2.a + s2.b * s2.b + s1.c * s2.c
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:92:19
+ --> $DIR/suspicious_operation_groupings.rs:91:19
|
LL | s1.a * s2.a + s1.b * s1.b + s1.c * s2.c
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:97:5
+ --> $DIR/suspicious_operation_groupings.rs:96:5
|
LL | s1.a * s1.a + s1.b * s2.b + s1.c * s2.c
| ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:102:33
+ --> $DIR/suspicious_operation_groupings.rs:101:33
|
LL | s1.a * s2.a + s1.b * s2.b + s1.c * s1.c
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:115:20
+ --> $DIR/suspicious_operation_groupings.rs:114:20
|
LL | (s1.a * s2.a + s1.b * s1.b)
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:120:34
+ --> $DIR/suspicious_operation_groupings.rs:119:34
|
LL | (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d)
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:125:38
+ --> $DIR/suspicious_operation_groupings.rs:124:38
|
LL | (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:130:39
+ --> $DIR/suspicious_operation_groupings.rs:129:39
|
LL | ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:135:42
+ --> $DIR/suspicious_operation_groupings.rs:134:42
|
LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:135:42
+ --> $DIR/suspicious_operation_groupings.rs:134:42
|
LL | (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:140:40
+ --> $DIR/suspicious_operation_groupings.rs:139:40
|
LL | (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d))
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:145:40
+ --> $DIR/suspicious_operation_groupings.rs:144:40
|
LL | ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)))
| ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:150:20
+ --> $DIR/suspicious_operation_groupings.rs:149:20
|
LL | (s1.a * s2.a + s2.b * s2.b) / 2
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:155:35
+ --> $DIR/suspicious_operation_groupings.rs:154:35
|
LL | i32::swap_bytes(s1.a * s2.a + s2.b * s2.b)
| ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:160:29
+ --> $DIR/suspicious_operation_groupings.rs:159:29
|
LL | s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d
| ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:165:17
+ --> $DIR/suspicious_operation_groupings.rs:164:17
|
LL | s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d
| ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:174:77
+ --> $DIR/suspicious_operation_groupings.rs:173:77
|
LL | (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:188:25
+ --> $DIR/suspicious_operation_groupings.rs:187:25
|
LL | s1.a <= s2.a && s1.a <= s2.b
| ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:194:23
+ --> $DIR/suspicious_operation_groupings.rs:193:23
|
LL | if s1.a < s2.a && s1.a < s2.b {
| ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:201:48
+ --> $DIR/suspicious_operation_groupings.rs:200:48
|
LL | -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d)))
| ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c`
error: this sequence of operators looks suspiciously like a bug
- --> $DIR/suspicious_operation_groupings.rs:206:27
+ --> $DIR/suspicious_operation_groupings.rs:205:27
|
LL | -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a })
| ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b`
diff --git a/src/tools/clippy/tests/ui/suspicious_splitn.rs b/src/tools/clippy/tests/ui/suspicious_splitn.rs
index 528f2ddcc..7aa609706 100644
--- a/src/tools/clippy/tests/ui/suspicious_splitn.rs
+++ b/src/tools/clippy/tests/ui/suspicious_splitn.rs
@@ -8,14 +8,32 @@ fn main() {
let _ = [].splitn(0, |&x: &u32| x == 1);
let _ = "a,b".splitn(0, ',');
+ //~^ ERROR: `splitn` called with `0` splits
+ //~| NOTE: the resulting iterator will always return `None`
let _ = "a,b".rsplitn(0, ',');
+ //~^ ERROR: `rsplitn` called with `0` splits
+ //~| NOTE: the resulting iterator will always return `None`
let _ = "a,b".splitn(1, ',');
+ //~^ ERROR: `splitn` called with `1` split
+ //~| NOTE: the resulting iterator will always return the entire string followed by `No
let _ = [0, 1, 2].splitn(0, |&x| x == 1);
+ //~^ ERROR: `splitn` called with `0` splits
+ //~| NOTE: the resulting iterator will always return `None`
let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1);
+ //~^ ERROR: `splitn_mut` called with `0` splits
+ //~| NOTE: the resulting iterator will always return `None`
let _ = [0, 1, 2].splitn(1, |&x| x == 1);
+ //~^ ERROR: `splitn` called with `1` split
+ //~| NOTE: the resulting iterator will always return the entire slice followed by `Non
let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1);
+ //~^ ERROR: `rsplitn_mut` called with `1` split
+ //~| NOTE: the resulting iterator will always return the entire slice followed by `Non
const X: usize = 0;
let _ = "a,b".splitn(X + 1, ',');
+ //~^ ERROR: `splitn` called with `1` split
+ //~| NOTE: the resulting iterator will always return the entire string followed by `No
let _ = "a,b".splitn(X, ',');
+ //~^ ERROR: `splitn` called with `0` splits
+ //~| NOTE: the resulting iterator will always return `None`
}
diff --git a/src/tools/clippy/tests/ui/suspicious_splitn.stderr b/src/tools/clippy/tests/ui/suspicious_splitn.stderr
index 55ce63d4f..4513beac8 100644
--- a/src/tools/clippy/tests/ui/suspicious_splitn.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_splitn.stderr
@@ -6,9 +6,10 @@ LL | let _ = "a,b".splitn(0, ',');
|
= note: the resulting iterator will always return `None`
= note: `-D clippy::suspicious-splitn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_splitn)]`
error: `rsplitn` called with `0` splits
- --> $DIR/suspicious_splitn.rs:11:13
+ --> $DIR/suspicious_splitn.rs:13:13
|
LL | let _ = "a,b".rsplitn(0, ',');
| ^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let _ = "a,b".rsplitn(0, ',');
= note: the resulting iterator will always return `None`
error: `splitn` called with `1` split
- --> $DIR/suspicious_splitn.rs:12:13
+ --> $DIR/suspicious_splitn.rs:16:13
|
LL | let _ = "a,b".splitn(1, ',');
| ^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let _ = "a,b".splitn(1, ',');
= note: the resulting iterator will always return the entire string followed by `None`
error: `splitn` called with `0` splits
- --> $DIR/suspicious_splitn.rs:13:13
+ --> $DIR/suspicious_splitn.rs:19:13
|
LL | let _ = [0, 1, 2].splitn(0, |&x| x == 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | let _ = [0, 1, 2].splitn(0, |&x| x == 1);
= note: the resulting iterator will always return `None`
error: `splitn_mut` called with `0` splits
- --> $DIR/suspicious_splitn.rs:14:13
+ --> $DIR/suspicious_splitn.rs:22:13
|
LL | let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1);
= note: the resulting iterator will always return `None`
error: `splitn` called with `1` split
- --> $DIR/suspicious_splitn.rs:15:13
+ --> $DIR/suspicious_splitn.rs:25:13
|
LL | let _ = [0, 1, 2].splitn(1, |&x| x == 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | let _ = [0, 1, 2].splitn(1, |&x| x == 1);
= note: the resulting iterator will always return the entire slice followed by `None`
error: `rsplitn_mut` called with `1` split
- --> $DIR/suspicious_splitn.rs:16:13
+ --> $DIR/suspicious_splitn.rs:28:13
|
LL | let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1);
= note: the resulting iterator will always return the entire slice followed by `None`
error: `splitn` called with `1` split
- --> $DIR/suspicious_splitn.rs:19:13
+ --> $DIR/suspicious_splitn.rs:33:13
|
LL | let _ = "a,b".splitn(X + 1, ',');
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | let _ = "a,b".splitn(X + 1, ',');
= note: the resulting iterator will always return the entire string followed by `None`
error: `splitn` called with `0` splits
- --> $DIR/suspicious_splitn.rs:20:13
+ --> $DIR/suspicious_splitn.rs:36:13
|
LL | let _ = "a,b".splitn(X, ',');
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.rs b/src/tools/clippy/tests/ui/suspicious_to_owned.rs
index cba21bf4a..f32b07d45 100644
--- a/src/tools/clippy/tests/ui/suspicious_to_owned.rs
+++ b/src/tools/clippy/tests/ui/suspicious_to_owned.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::suspicious_to_owned)]
#![warn(clippy::implicit_clone)]
#![allow(clippy::redundant_clone)]
@@ -14,6 +15,8 @@ fn main() {
// we expect this to be linted
let cow = Cow::Borrowed(moo);
let _ = cow.to_owned();
+ //~^ ERROR: this `to_owned` call clones the Cow<'_, str> itself and does not cause the
+ //~| NOTE: `-D clippy::suspicious-to-owned` implied by `-D warnings`
// we expect no lints for this
let cow = Cow::Borrowed(moo);
let _ = cow.into_owned();
@@ -24,6 +27,7 @@ fn main() {
// we expect this to be linted
let cow = Cow::Borrowed(&moos);
let _ = cow.to_owned();
+ //~^ ERROR: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cau
// we expect no lints for this
let cow = Cow::Borrowed(&moos);
let _ = cow.into_owned();
@@ -34,6 +38,7 @@ fn main() {
// we expect this to be linted
let cow = Cow::Borrowed(&moos_vec);
let _ = cow.to_owned();
+ //~^ ERROR: this `to_owned` call clones the Cow<'_, Vec<char>> itself and does not cau
// we expect no lints for this
let cow = Cow::Borrowed(&moos_vec);
let _ = cow.into_owned();
@@ -44,6 +49,7 @@ fn main() {
// we expect this to be linted
let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();
let _ = cow.to_owned();
+ //~^ ERROR: this `to_owned` call clones the Cow<'_, str> itself and does not cause the
// we expect no lints for this
let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();
let _ = cow.into_owned();
@@ -58,5 +64,8 @@ fn main() {
// we expect implicit_clone lints for these
let _ = String::from(moo).to_owned();
+ //~^ ERROR: implicitly cloning a `String` by calling `to_owned` on its dereferenced ty
+ //~| NOTE: `-D clippy::implicit-clone` implied by `-D warnings`
let _ = moos_vec.to_owned();
+ //~^ ERROR: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
}
diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
index c4ec7aa88..eb967a714 100644
--- a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
@@ -1,10 +1,11 @@
error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned
- --> $DIR/suspicious_to_owned.rs:16:13
+ --> $DIR/suspicious_to_owned.rs:17:13
|
LL | let _ = cow.to_owned();
| ^^^^^^^^^^^^^^
|
= note: `-D clippy::suspicious-to-owned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]`
help: depending on intent, either make the Cow an Owned variant
|
LL | let _ = cow.into_owned();
@@ -15,7 +16,7 @@ LL | let _ = cow.clone();
| ~~~~~~~~~~~
error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned
- --> $DIR/suspicious_to_owned.rs:26:13
+ --> $DIR/suspicious_to_owned.rs:29:13
|
LL | let _ = cow.to_owned();
| ^^^^^^^^^^^^^^
@@ -30,7 +31,7 @@ LL | let _ = cow.clone();
| ~~~~~~~~~~~
error: this `to_owned` call clones the Cow<'_, Vec<char>> itself and does not cause the Cow<'_, Vec<char>> contents to become owned
- --> $DIR/suspicious_to_owned.rs:36:13
+ --> $DIR/suspicious_to_owned.rs:40:13
|
LL | let _ = cow.to_owned();
| ^^^^^^^^^^^^^^
@@ -45,7 +46,7 @@ LL | let _ = cow.clone();
| ~~~~~~~~~~~
error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned
- --> $DIR/suspicious_to_owned.rs:46:13
+ --> $DIR/suspicious_to_owned.rs:51:13
|
LL | let _ = cow.to_owned();
| ^^^^^^^^^^^^^^
@@ -60,15 +61,16 @@ LL | let _ = cow.clone();
| ~~~~~~~~~~~
error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
- --> $DIR/suspicious_to_owned.rs:60:13
+ --> $DIR/suspicious_to_owned.rs:66:13
|
LL | let _ = String::from(moo).to_owned();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::from(moo).clone()`
|
= note: `-D clippy::implicit-clone` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]`
error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type
- --> $DIR/suspicious_to_owned.rs:61:13
+ --> $DIR/suspicious_to_owned.rs:69:13
|
LL | let _ = moos_vec.to_owned();
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `moos_vec.clone()`
diff --git a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.rs b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.rs
index 3c5ca1762..a7a62154e 100644
--- a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.rs
+++ b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.rs
@@ -7,14 +7,18 @@ fn main() {
let a = 42;
if a >- 30 {}
+ //~^ ERROR: by not having a space between `>` and `-` it looks like `>-` is a single o
if a >=- 30 {}
+ //~^ ERROR: by not having a space between `>=` and `-` it looks like `>=-` is a single
let b = true;
let c = false;
if b &&! c {}
+ //~^ ERROR: by not having a space between `&&` and `!` it looks like `&&!` is a single
if a >- 30 {}
+ //~^ ERROR: by not having a space between `>` and `-` it looks like `>-` is a single o
// those are ok:
if a >-30 {}
diff --git a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr
index 52b0e99a1..3cddde4ec 100644
--- a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr
@@ -6,9 +6,10 @@ LL | if a >- 30 {}
|
= help: put a space between `>` and `-` and remove the space after `-`
= note: `-D clippy::suspicious-unary-op-formatting` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_unary_op_formatting)]`
error: by not having a space between `>=` and `-` it looks like `>=-` is a single operator
- --> $DIR/suspicious_unary_op_formatting.rs:10:9
+ --> $DIR/suspicious_unary_op_formatting.rs:11:9
|
LL | if a >=- 30 {}
| ^^^^^
@@ -16,7 +17,7 @@ LL | if a >=- 30 {}
= help: put a space between `>=` and `-` and remove the space after `-`
error: by not having a space between `&&` and `!` it looks like `&&!` is a single operator
- --> $DIR/suspicious_unary_op_formatting.rs:15:9
+ --> $DIR/suspicious_unary_op_formatting.rs:17:9
|
LL | if b &&! c {}
| ^^^^^
@@ -24,7 +25,7 @@ LL | if b &&! c {}
= help: put a space between `&&` and `!` and remove the space after `!`
error: by not having a space between `>` and `-` it looks like `>-` is a single operator
- --> $DIR/suspicious_unary_op_formatting.rs:17:9
+ --> $DIR/suspicious_unary_op_formatting.rs:20:9
|
LL | if a >- 30 {}
| ^^^^^^
diff --git a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.rs b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.rs
index eb9fc63fb..a5319e1b2 100644
--- a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.rs
+++ b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.rs
@@ -1,7 +1,7 @@
#![allow(unused)]
#![warn(clippy::suspicious_xor_used_as_pow)]
#![allow(clippy::eq_op)]
-
+//@no-rustfix
macro_rules! macro_test {
() => {
13
@@ -17,11 +17,18 @@ macro_rules! macro_test_inside {
fn main() {
// Should warn:
let _ = 2 ^ 5;
+ //~^ ERROR: `^` is not the exponentiation operator
+ //~| NOTE: `-D clippy::suspicious-xor-used-as-pow` implied by `-D warnings`
let _ = 2i32 ^ 9i32;
+ //~^ ERROR: `^` is not the exponentiation operator
let _ = 2i32 ^ 2i32;
+ //~^ ERROR: `^` is not the exponentiation operator
let _ = 50i32 ^ 3i32;
+ //~^ ERROR: `^` is not the exponentiation operator
let _ = 5i32 ^ 8i32;
+ //~^ ERROR: `^` is not the exponentiation operator
let _ = 2i32 ^ 32i32;
+ //~^ ERROR: `^` is not the exponentiation operator
macro_test_inside!();
// Should not warn:
diff --git a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr
index d93a55ba9..29e9fa771 100644
--- a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr
@@ -5,33 +5,34 @@ LL | let _ = 2 ^ 5;
| ^^^^^ help: did you mean to write: `2.pow(5)`
|
= note: `-D clippy::suspicious-xor-used-as-pow` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suspicious_xor_used_as_pow)]`
error: `^` is not the exponentiation operator
- --> $DIR/suspicious_xor_used_as_pow.rs:20:13
+ --> $DIR/suspicious_xor_used_as_pow.rs:22:13
|
LL | let _ = 2i32 ^ 9i32;
| ^^^^^^^^^^^ help: did you mean to write: `2i32.pow(9i32)`
error: `^` is not the exponentiation operator
- --> $DIR/suspicious_xor_used_as_pow.rs:21:13
+ --> $DIR/suspicious_xor_used_as_pow.rs:24:13
|
LL | let _ = 2i32 ^ 2i32;
| ^^^^^^^^^^^ help: did you mean to write: `2i32.pow(2i32)`
error: `^` is not the exponentiation operator
- --> $DIR/suspicious_xor_used_as_pow.rs:22:13
+ --> $DIR/suspicious_xor_used_as_pow.rs:26:13
|
LL | let _ = 50i32 ^ 3i32;
| ^^^^^^^^^^^^ help: did you mean to write: `50i32.pow(3i32)`
error: `^` is not the exponentiation operator
- --> $DIR/suspicious_xor_used_as_pow.rs:23:13
+ --> $DIR/suspicious_xor_used_as_pow.rs:28:13
|
LL | let _ = 5i32 ^ 8i32;
| ^^^^^^^^^^^ help: did you mean to write: `5i32.pow(8i32)`
error: `^` is not the exponentiation operator
- --> $DIR/suspicious_xor_used_as_pow.rs:24:13
+ --> $DIR/suspicious_xor_used_as_pow.rs:30:13
|
LL | let _ = 2i32 ^ 32i32;
| ^^^^^^^^^^^^ help: did you mean to write: `2i32.pow(32i32)`
diff --git a/src/tools/clippy/tests/ui/swap.fixed b/src/tools/clippy/tests/ui/swap.fixed
index 7b74a83b6..888665a17 100644
--- a/src/tools/clippy/tests/ui/swap.fixed
+++ b/src/tools/clippy/tests/ui/swap.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build: macro_rules.rs
#![warn(clippy::all)]
diff --git a/src/tools/clippy/tests/ui/swap.rs b/src/tools/clippy/tests/ui/swap.rs
index 93855cd7b..c9ad77629 100644
--- a/src/tools/clippy/tests/ui/swap.rs
+++ b/src/tools/clippy/tests/ui/swap.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build: macro_rules.rs
#![warn(clippy::all)]
diff --git a/src/tools/clippy/tests/ui/swap.stderr b/src/tools/clippy/tests/ui/swap.stderr
index 1097b29bb..e69ad02b0 100644
--- a/src/tools/clippy/tests/ui/swap.stderr
+++ b/src/tools/clippy/tests/ui/swap.stderr
@@ -1,5 +1,5 @@
error: this looks like you are swapping `bar.a` and `bar.b` manually
- --> $DIR/swap.rs:29:5
+ --> $DIR/swap.rs:28:5
|
LL | / let temp = bar.a;
LL | | bar.a = bar.b;
@@ -8,9 +8,10 @@ LL | | bar.b = temp;
|
= note: or maybe you should use `std::mem::replace`?
= note: `-D clippy::manual-swap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::manual_swap)]`
error: this looks like you are swapping elements of `foo` manually
- --> $DIR/swap.rs:41:5
+ --> $DIR/swap.rs:40:5
|
LL | / let temp = foo[0];
LL | | foo[0] = foo[1];
@@ -18,7 +19,7 @@ LL | | foo[1] = temp;
| |__________________^ help: try: `foo.swap(0, 1);`
error: this looks like you are swapping elements of `foo` manually
- --> $DIR/swap.rs:50:5
+ --> $DIR/swap.rs:49:5
|
LL | / let temp = foo[0];
LL | | foo[0] = foo[1];
@@ -26,7 +27,7 @@ LL | | foo[1] = temp;
| |__________________^ help: try: `foo.swap(0, 1);`
error: this looks like you are swapping elements of `foo` manually
- --> $DIR/swap.rs:69:5
+ --> $DIR/swap.rs:68:5
|
LL | / let temp = foo[0];
LL | | foo[0] = foo[1];
@@ -34,7 +35,7 @@ LL | | foo[1] = temp;
| |__________________^ help: try: `foo.swap(0, 1);`
error: this looks like you are swapping `a` and `b` manually
- --> $DIR/swap.rs:80:5
+ --> $DIR/swap.rs:79:5
|
LL | / a ^= b;
LL | | b ^= a;
@@ -42,7 +43,7 @@ LL | | a ^= b;
| |___________^ help: try: `std::mem::swap(&mut a, &mut b);`
error: this looks like you are swapping `bar.a` and `bar.b` manually
- --> $DIR/swap.rs:88:5
+ --> $DIR/swap.rs:87:5
|
LL | / bar.a ^= bar.b;
LL | | bar.b ^= bar.a;
@@ -50,7 +51,7 @@ LL | | bar.a ^= bar.b;
| |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);`
error: this looks like you are swapping elements of `foo` manually
- --> $DIR/swap.rs:96:5
+ --> $DIR/swap.rs:95:5
|
LL | / foo[0] ^= foo[1];
LL | | foo[1] ^= foo[0];
@@ -58,7 +59,7 @@ LL | | foo[0] ^= foo[1];
| |_____________________^ help: try: `foo.swap(0, 1);`
error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually
- --> $DIR/swap.rs:125:5
+ --> $DIR/swap.rs:124:5
|
LL | / let temp = foo[0][1];
LL | | foo[0][1] = bar[1][0];
@@ -68,7 +69,7 @@ LL | | bar[1][0] = temp;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are swapping `a` and `b` manually
- --> $DIR/swap.rs:139:7
+ --> $DIR/swap.rs:138:7
|
LL | ; let t = a;
| _______^
@@ -79,7 +80,7 @@ LL | | b = t;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are swapping `c.0` and `a` manually
- --> $DIR/swap.rs:148:7
+ --> $DIR/swap.rs:147:7
|
LL | ; let t = c.0;
| _______^
@@ -90,7 +91,7 @@ LL | | a = t;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are swapping `b` and `a` manually
- --> $DIR/swap.rs:174:5
+ --> $DIR/swap.rs:173:5
|
LL | / let t = b;
LL | | b = a;
@@ -100,7 +101,7 @@ LL | | a = t;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are trying to swap `a` and `b`
- --> $DIR/swap.rs:136:5
+ --> $DIR/swap.rs:135:5
|
LL | / a = b;
LL | | b = a;
@@ -108,9 +109,10 @@ LL | | b = a;
|
= note: or maybe you should use `std::mem::replace`?
= note: `-D clippy::almost-swapped` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::almost_swapped)]`
error: this looks like you are trying to swap `c.0` and `a`
- --> $DIR/swap.rs:145:5
+ --> $DIR/swap.rs:144:5
|
LL | / c.0 = a;
LL | | a = c.0;
@@ -119,7 +121,7 @@ LL | | a = c.0;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are trying to swap `a` and `b`
- --> $DIR/swap.rs:152:5
+ --> $DIR/swap.rs:151:5
|
LL | / let a = b;
LL | | let b = a;
@@ -128,7 +130,7 @@ LL | | let b = a;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are trying to swap `d` and `c`
- --> $DIR/swap.rs:157:5
+ --> $DIR/swap.rs:156:5
|
LL | / d = c;
LL | | c = d;
@@ -137,7 +139,7 @@ LL | | c = d;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are trying to swap `a` and `b`
- --> $DIR/swap.rs:161:5
+ --> $DIR/swap.rs:160:5
|
LL | / let a = b;
LL | | b = a;
@@ -146,7 +148,7 @@ LL | | b = a;
= note: or maybe you should use `std::mem::replace`?
error: this looks like you are swapping `s.0.x` and `s.0.y` manually
- --> $DIR/swap.rs:209:5
+ --> $DIR/swap.rs:208:5
|
LL | / let t = s.0.x;
LL | | s.0.x = s.0.y;
diff --git a/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed b/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed
index 3bede3017..599bb0e80 100644
--- a/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed
+++ b/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::swap_ptr_to_ref)]
use core::ptr::addr_of_mut;
diff --git a/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs b/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs
index 726b09d37..3a8a8daef 100644
--- a/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs
+++ b/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::swap_ptr_to_ref)]
use core::ptr::addr_of_mut;
diff --git a/src/tools/clippy/tests/ui/swap_ptr_to_ref.stderr b/src/tools/clippy/tests/ui/swap_ptr_to_ref.stderr
index 401ce0708..42455f492 100644
--- a/src/tools/clippy/tests/ui/swap_ptr_to_ref.stderr
+++ b/src/tools/clippy/tests/ui/swap_ptr_to_ref.stderr
@@ -1,25 +1,26 @@
error: call to `core::mem::swap` with a parameter derived from a raw pointer
- --> $DIR/swap_ptr_to_ref.rs:13:9
+ --> $DIR/swap_ptr_to_ref.rs:11:9
|
LL | core::mem::swap(&mut *y, &mut *z);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(y, z)`
|
= note: `-D clippy::swap-ptr-to-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::swap_ptr_to_ref)]`
error: call to `core::mem::swap` with a parameter derived from a raw pointer
- --> $DIR/swap_ptr_to_ref.rs:14:9
+ --> $DIR/swap_ptr_to_ref.rs:12:9
|
LL | core::mem::swap(&mut *y, &mut x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(y, &mut x)`
error: call to `core::mem::swap` with a parameter derived from a raw pointer
- --> $DIR/swap_ptr_to_ref.rs:15:9
+ --> $DIR/swap_ptr_to_ref.rs:13:9
|
LL | core::mem::swap(&mut x, &mut *y);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(&mut x, y)`
error: call to `core::mem::swap` with a parameter derived from a raw pointer
- --> $DIR/swap_ptr_to_ref.rs:16:9
+ --> $DIR/swap_ptr_to_ref.rs:14:9
|
LL | core::mem::swap(&mut *addr_of_mut!(x), &mut *addr_of_mut!(x));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(addr_of_mut!(x), addr_of_mut!(x))`
diff --git a/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.rs b/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.rs
index 66ea7c652..08e56a5d0 100644
--- a/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.rs
+++ b/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.rs
@@ -12,7 +12,11 @@ fn main() {
unsafe {
core::mem::swap(addr_of_mut_to_ref!(x), &mut *y);
+ //~^ ERROR: call to `core::mem::swap` with a parameter derived from a raw pointer
+ //~| NOTE: `-D clippy::swap-ptr-to-ref` implied by `-D warnings`
core::mem::swap(&mut *y, addr_of_mut_to_ref!(x));
+ //~^ ERROR: call to `core::mem::swap` with a parameter derived from a raw pointer
core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x));
+ //~^ ERROR: call to `core::mem::swap` with a parameter derived from a raw pointer
}
}
diff --git a/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.stderr b/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.stderr
index c261205d5..ce1d78142 100644
--- a/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/swap_ptr_to_ref_unfixable.stderr
@@ -5,15 +5,16 @@ LL | core::mem::swap(addr_of_mut_to_ref!(x), &mut *y);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::swap-ptr-to-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::swap_ptr_to_ref)]`
error: call to `core::mem::swap` with a parameter derived from a raw pointer
- --> $DIR/swap_ptr_to_ref_unfixable.rs:15:9
+ --> $DIR/swap_ptr_to_ref_unfixable.rs:17:9
|
LL | core::mem::swap(&mut *y, addr_of_mut_to_ref!(x));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: call to `core::mem::swap` with a parameter derived from a raw pointer
- --> $DIR/swap_ptr_to_ref_unfixable.rs:16:9
+ --> $DIR/swap_ptr_to_ref_unfixable.rs:19:9
|
LL | core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed b/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed
index 21020182c..26cc5c27e 100644
--- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed
+++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::tabs_in_doc_comments)]
#[allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs b/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs
index df704267d..14b06966e 100644
--- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs
+++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::tabs_in_doc_comments)]
#[allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
index 355f2e805..69ce214ae 100644
--- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
@@ -1,49 +1,50 @@
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:12:9
+ --> $DIR/tabs_in_doc_comments.rs:10:9
|
LL | /// - First String:
| ^^^^ help: consider using four spaces per tab
|
= note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:13:9
+ --> $DIR/tabs_in_doc_comments.rs:11:9
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:16:9
+ --> $DIR/tabs_in_doc_comments.rs:14:9
|
LL | /// - Second String:
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:17:9
+ --> $DIR/tabs_in_doc_comments.rs:15:9
|
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:8:5
+ --> $DIR/tabs_in_doc_comments.rs:6:5
|
LL | /// - first one
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:8:13
+ --> $DIR/tabs_in_doc_comments.rs:6:13
|
LL | /// - first one
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:9:5
+ --> $DIR/tabs_in_doc_comments.rs:7:5
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
- --> $DIR/tabs_in_doc_comments.rs:9:14
+ --> $DIR/tabs_in_doc_comments.rs:7:14
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
diff --git a/src/tools/clippy/tests/ui/temporary_assignment.rs b/src/tools/clippy/tests/ui/temporary_assignment.rs
index b4a931043..383e70be9 100644
--- a/src/tools/clippy/tests/ui/temporary_assignment.rs
+++ b/src/tools/clippy/tests/ui/temporary_assignment.rs
@@ -46,13 +46,18 @@ fn main() {
let mut t = (0, 0);
Struct { field: 0 }.field = 1;
+ //~^ ERROR: assignment to temporary
+ //~| NOTE: `-D clippy::temporary-assignment` implied by `-D warnings`
MultiStruct {
+ //~^ ERROR: assignment to temporary
structure: Struct { field: 0 },
}
.structure
.field = 1;
ArrayStruct { array: [0] }.array[0] = 1;
+ //~^ ERROR: assignment to temporary
(0, 0).0 = 1;
+ //~^ ERROR: assignment to temporary
// no error
s.field = 1;
diff --git a/src/tools/clippy/tests/ui/temporary_assignment.stderr b/src/tools/clippy/tests/ui/temporary_assignment.stderr
index 4cc32c79f..cbb892418 100644
--- a/src/tools/clippy/tests/ui/temporary_assignment.stderr
+++ b/src/tools/clippy/tests/ui/temporary_assignment.stderr
@@ -5,11 +5,13 @@ LL | Struct { field: 0 }.field = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::temporary-assignment` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::temporary_assignment)]`
error: assignment to temporary
- --> $DIR/temporary_assignment.rs:49:5
+ --> $DIR/temporary_assignment.rs:51:5
|
LL | / MultiStruct {
+LL | |
LL | | structure: Struct { field: 0 },
LL | | }
LL | | .structure
@@ -17,13 +19,13 @@ LL | | .field = 1;
| |______________^
error: assignment to temporary
- --> $DIR/temporary_assignment.rs:54:5
+ --> $DIR/temporary_assignment.rs:57:5
|
LL | ArrayStruct { array: [0] }.array[0] = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assignment to temporary
- --> $DIR/temporary_assignment.rs:55:5
+ --> $DIR/temporary_assignment.rs:59:5
|
LL | (0, 0).0 = 1;
| ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/tests_outside_test_module.rs b/src/tools/clippy/tests/ui/tests_outside_test_module.rs
index d53c692b7..0abde4a57 100644
--- a/src/tools/clippy/tests/ui/tests_outside_test_module.rs
+++ b/src/tools/clippy/tests/ui/tests_outside_test_module.rs
@@ -8,6 +8,8 @@ fn main() {
// Should lint
#[test]
fn my_test() {}
+//~^ ERROR: this function marked with #[test] is outside a #[cfg(test)] module
+//~| NOTE: move it to a testing module marked with #[cfg(test)]
#[cfg(test)]
mod tests {
diff --git a/src/tools/clippy/tests/ui/tests_outside_test_module.stderr b/src/tools/clippy/tests/ui/tests_outside_test_module.stderr
index 71c649c5d..112d6ce1f 100644
--- a/src/tools/clippy/tests/ui/tests_outside_test_module.stderr
+++ b/src/tools/clippy/tests/ui/tests_outside_test_module.stderr
@@ -6,6 +6,7 @@ LL | fn my_test() {}
|
= note: move it to a testing module marked with #[cfg(test)]
= note: `-D clippy::tests-outside-test-module` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::tests_outside_test_module)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.fixed b/src/tools/clippy/tests/ui/to_digit_is_some.fixed
index dc9be66d4..2ef4c0528 100644
--- a/src/tools/clippy/tests/ui/to_digit_is_some.fixed
+++ b/src/tools/clippy/tests/ui/to_digit_is_some.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::to_digit_is_some)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.rs b/src/tools/clippy/tests/ui/to_digit_is_some.rs
index d2a09ac30..54d954580 100644
--- a/src/tools/clippy/tests/ui/to_digit_is_some.rs
+++ b/src/tools/clippy/tests/ui/to_digit_is_some.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::to_digit_is_some)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.stderr b/src/tools/clippy/tests/ui/to_digit_is_some.stderr
index c4718825d..5067ad7fb 100644
--- a/src/tools/clippy/tests/ui/to_digit_is_some.stderr
+++ b/src/tools/clippy/tests/ui/to_digit_is_some.stderr
@@ -1,13 +1,14 @@
error: use of `.to_digit(..).is_some()`
- --> $DIR/to_digit_is_some.rs:9:13
+ --> $DIR/to_digit_is_some.rs:7:13
|
LL | let _ = d.to_digit(8).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d.is_digit(8)`
|
= note: `-D clippy::to-digit-is-some` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::to_digit_is_some)]`
error: use of `.to_digit(..).is_some()`
- --> $DIR/to_digit_is_some.rs:10:13
+ --> $DIR/to_digit_is_some.rs:8:13
|
LL | let _ = char::to_digit(c, 8).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `char::is_digit(c, 8)`
diff --git a/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.fixed b/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.fixed
index 9f75ad895..1f7895796 100644
--- a/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.fixed
+++ b/src/tools/clippy/tests/ui/to_string_in_format_args_incremental.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@compile-flags: -C incremental=target/debug/test/incr
// see https://github.com/rust-lang/rust-clippy/issues/10969
diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed b/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed
index 9ad45c7a8..ff5cd7abb 100644
--- a/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed
+++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::toplevel_ref_arg)]
#![allow(clippy::uninlined_format_args, unused, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.rs b/src/tools/clippy/tests/ui/toplevel_ref_arg.rs
index 45ccc024c..ab79b8959 100644
--- a/src/tools/clippy/tests/ui/toplevel_ref_arg.rs
+++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::toplevel_ref_arg)]
#![allow(clippy::uninlined_format_args, unused, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr b/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr
index 407c2d9fc..2c27a3c8e 100644
--- a/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr
+++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.stderr
@@ -1,37 +1,38 @@
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
- --> $DIR/toplevel_ref_arg.rs:15:9
+ --> $DIR/toplevel_ref_arg.rs:14:9
|
LL | let ref _x = 1;
| ----^^^^^^----- help: try: `let _x = &1;`
|
= note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
- --> $DIR/toplevel_ref_arg.rs:17:9
+ --> $DIR/toplevel_ref_arg.rs:16:9
|
LL | let ref _y: (&_, u8) = (&1, 2);
| ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
- --> $DIR/toplevel_ref_arg.rs:19:9
+ --> $DIR/toplevel_ref_arg.rs:18:9
|
LL | let ref _z = 1 + 2;
| ----^^^^^^--------- help: try: `let _z = &(1 + 2);`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
- --> $DIR/toplevel_ref_arg.rs:21:9
+ --> $DIR/toplevel_ref_arg.rs:20:9
|
LL | let ref mut _z = 1 + 2;
| ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
- --> $DIR/toplevel_ref_arg.rs:26:9
+ --> $DIR/toplevel_ref_arg.rs:25:9
|
LL | let ref _x = vec![1, 2, 3];
| ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];`
error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
- --> $DIR/toplevel_ref_arg.rs:36:17
+ --> $DIR/toplevel_ref_arg.rs:35:17
|
LL | inline!(let ref _y = 42;);
| ----^^^^^^------ help: try: `let _y = &42;`
diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs
index 464762af8..8aaf47b1b 100644
--- a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs
+++ b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::toplevel_ref_arg)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr
index 7307bd599..45123dd5e 100644
--- a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr
+++ b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr
@@ -5,6 +5,7 @@ LL | fn the_answer(ref mut x: u8) {
| ^^^^^^^^^
|
= note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]`
error: `ref` directly on a function argument is ignored. Consider using a reference type instead
--> $DIR/toplevel_ref_arg_non_rustfix.rs:20:24
diff --git a/src/tools/clippy/tests/ui/trailing_empty_array.rs b/src/tools/clippy/tests/ui/trailing_empty_array.rs
index 928475b5f..3d06c2621 100644
--- a/src/tools/clippy/tests/ui/trailing_empty_array.rs
+++ b/src/tools/clippy/tests/ui/trailing_empty_array.rs
@@ -3,33 +3,39 @@
// Do lint:
struct RarelyUseful {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
field: i32,
last: [usize; 0],
}
struct OnlyField {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
first_and_last: [usize; 0],
}
struct GenericArrayType<T> {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
field: i32,
last: [T; 0],
}
#[must_use]
struct OnlyAnotherAttribute {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
field: i32,
last: [usize; 0],
}
#[derive(Debug)]
struct OnlyADeriveAttribute {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
field: i32,
last: [usize; 0],
}
const ZERO: usize = 0;
struct ZeroSizedWithConst {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
field: i32,
last: [usize; ZERO],
}
@@ -39,6 +45,7 @@ const fn compute_zero() -> usize {
(4 + 6) - (2 * 5)
}
struct ZeroSizedWithConstFunction {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
field: i32,
last: [usize; compute_zero()],
}
@@ -47,15 +54,19 @@ const fn compute_zero_from_arg(x: usize) -> usize {
x - 1
}
struct ZeroSizedWithConstFunction2 {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
field: i32,
last: [usize; compute_zero_from_arg(1)],
}
struct ZeroSizedArrayWrapper([usize; 0]);
+//~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
struct TupleStruct(i32, [usize; 0]);
+//~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
struct LotsOfFields {
+ //~^ ERROR: trailing zero-sized array in a struct which is not marked with a `repr` attrib
f1: u32,
f2: u32,
f3: u32,
diff --git a/src/tools/clippy/tests/ui/trailing_empty_array.stderr b/src/tools/clippy/tests/ui/trailing_empty_array.stderr
index 2e1484400..ef7fc24c3 100644
--- a/src/tools/clippy/tests/ui/trailing_empty_array.stderr
+++ b/src/tools/clippy/tests/ui/trailing_empty_array.stderr
@@ -2,6 +2,7 @@ error: trailing zero-sized array in a struct which is not marked with a `repr` a
--> $DIR/trailing_empty_array.rs:5:1
|
LL | / struct RarelyUseful {
+LL | |
LL | | field: i32,
LL | | last: [usize; 0],
LL | | }
@@ -9,11 +10,13 @@ LL | | }
|
= help: consider annotating `RarelyUseful` with `#[repr(C)]` or another `repr` attribute
= note: `-D clippy::trailing-empty-array` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::trailing_empty_array)]`
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:10:1
+ --> $DIR/trailing_empty_array.rs:11:1
|
LL | / struct OnlyField {
+LL | |
LL | | first_and_last: [usize; 0],
LL | | }
| |_^
@@ -21,9 +24,10 @@ LL | | }
= help: consider annotating `OnlyField` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:14:1
+ --> $DIR/trailing_empty_array.rs:16:1
|
LL | / struct GenericArrayType<T> {
+LL | |
LL | | field: i32,
LL | | last: [T; 0],
LL | | }
@@ -32,9 +36,10 @@ LL | | }
= help: consider annotating `GenericArrayType` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:20:1
+ --> $DIR/trailing_empty_array.rs:23:1
|
LL | / struct OnlyAnotherAttribute {
+LL | |
LL | | field: i32,
LL | | last: [usize; 0],
LL | | }
@@ -43,9 +48,10 @@ LL | | }
= help: consider annotating `OnlyAnotherAttribute` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:26:1
+ --> $DIR/trailing_empty_array.rs:30:1
|
LL | / struct OnlyADeriveAttribute {
+LL | |
LL | | field: i32,
LL | | last: [usize; 0],
LL | | }
@@ -54,9 +60,10 @@ LL | | }
= help: consider annotating `OnlyADeriveAttribute` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:32:1
+ --> $DIR/trailing_empty_array.rs:37:1
|
LL | / struct ZeroSizedWithConst {
+LL | |
LL | | field: i32,
LL | | last: [usize; ZERO],
LL | | }
@@ -65,9 +72,10 @@ LL | | }
= help: consider annotating `ZeroSizedWithConst` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:41:1
+ --> $DIR/trailing_empty_array.rs:47:1
|
LL | / struct ZeroSizedWithConstFunction {
+LL | |
LL | | field: i32,
LL | | last: [usize; compute_zero()],
LL | | }
@@ -76,9 +84,10 @@ LL | | }
= help: consider annotating `ZeroSizedWithConstFunction` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:49:1
+ --> $DIR/trailing_empty_array.rs:56:1
|
LL | / struct ZeroSizedWithConstFunction2 {
+LL | |
LL | | field: i32,
LL | | last: [usize; compute_zero_from_arg(1)],
LL | | }
@@ -87,7 +96,7 @@ LL | | }
= help: consider annotating `ZeroSizedWithConstFunction2` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:54:1
+ --> $DIR/trailing_empty_array.rs:62:1
|
LL | struct ZeroSizedArrayWrapper([usize; 0]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -95,7 +104,7 @@ LL | struct ZeroSizedArrayWrapper([usize; 0]);
= help: consider annotating `ZeroSizedArrayWrapper` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:56:1
+ --> $DIR/trailing_empty_array.rs:65:1
|
LL | struct TupleStruct(i32, [usize; 0]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -103,12 +112,12 @@ LL | struct TupleStruct(i32, [usize; 0]);
= help: consider annotating `TupleStruct` with `#[repr(C)]` or another `repr` attribute
error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
- --> $DIR/trailing_empty_array.rs:58:1
+ --> $DIR/trailing_empty_array.rs:68:1
|
LL | / struct LotsOfFields {
+LL | |
LL | | f1: u32,
LL | | f2: u32,
-LL | | f3: u32,
... |
LL | | last: [usize; 0],
LL | | }
diff --git a/src/tools/clippy/tests/ui/trailing_zeros.fixed b/src/tools/clippy/tests/ui/trailing_zeros.fixed
new file mode 100644
index 000000000..f7de976f1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/trailing_zeros.fixed
@@ -0,0 +1,13 @@
+#![allow(unused_parens)]
+#![warn(clippy::verbose_bit_mask)]
+
+fn main() {
+ let x: i32 = 42;
+ let _ = x.trailing_zeros() >= 4;
+ //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros`
+ //~| NOTE: `-D clippy::verbose-bit-mask` implied by `-D warnings`
+ let _ = x.trailing_zeros() >= 5;
+ //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros`
+ let _ = x & 0b1_1010 == 0; // do not lint
+ let _ = x & 1 == 0; // do not lint
+}
diff --git a/src/tools/clippy/tests/ui/trailing_zeros.rs b/src/tools/clippy/tests/ui/trailing_zeros.rs
index fbdc977b7..a05b09233 100644
--- a/src/tools/clippy/tests/ui/trailing_zeros.rs
+++ b/src/tools/clippy/tests/ui/trailing_zeros.rs
@@ -3,8 +3,11 @@
fn main() {
let x: i32 = 42;
- let _ = (x & 0b1111 == 0); // suggest trailing_zeros
- let _ = x & 0b1_1111 == 0; // suggest trailing_zeros
+ let _ = (x & 0b1111 == 0);
+ //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros`
+ //~| NOTE: `-D clippy::verbose-bit-mask` implied by `-D warnings`
+ let _ = x & 0b1_1111 == 0;
+ //~^ ERROR: bit mask could be simplified with a call to `trailing_zeros`
let _ = x & 0b1_1010 == 0; // do not lint
let _ = x & 1 == 0; // do not lint
}
diff --git a/src/tools/clippy/tests/ui/trailing_zeros.stderr b/src/tools/clippy/tests/ui/trailing_zeros.stderr
index 798551118..10924ad12 100644
--- a/src/tools/clippy/tests/ui/trailing_zeros.stderr
+++ b/src/tools/clippy/tests/ui/trailing_zeros.stderr
@@ -1,15 +1,16 @@
error: bit mask could be simplified with a call to `trailing_zeros`
--> $DIR/trailing_zeros.rs:6:13
|
-LL | let _ = (x & 0b1111 == 0); // suggest trailing_zeros
+LL | let _ = (x & 0b1111 == 0);
| ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 4`
|
= note: `-D clippy::verbose-bit-mask` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]`
error: bit mask could be simplified with a call to `trailing_zeros`
- --> $DIR/trailing_zeros.rs:7:13
+ --> $DIR/trailing_zeros.rs:9:13
|
-LL | let _ = x & 0b1_1111 == 0; // suggest trailing_zeros
+LL | let _ = x & 0b1_1111 == 0;
| ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 5`
error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
index fdac0e4cb..4fca29698 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::trait_duplication_in_bounds)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index a0300da55..f67c8e35e 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::trait_duplication_in_bounds)]
#![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
index 539b6114c..61a45538b 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
@@ -1,59 +1,59 @@
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:7:15
+ --> $DIR/trait_duplication_in_bounds.rs:6:15
|
LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
|
note: the lint level is defined here
- --> $DIR/trait_duplication_in_bounds.rs:2:9
+ --> $DIR/trait_duplication_in_bounds.rs:1:9
|
LL | #![deny(clippy::trait_duplication_in_bounds)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: these where clauses contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:13:8
+ --> $DIR/trait_duplication_in_bounds.rs:12:8
|
LL | T: Clone + Clone + Clone + Copy,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:41:26
+ --> $DIR/trait_duplication_in_bounds.rs:40:26
|
LL | trait BadSelfTraitBound: Clone + Clone + Clone {
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
error: these where clauses contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:48:15
+ --> $DIR/trait_duplication_in_bounds.rs:47:15
|
LL | Self: Clone + Clone + Clone;
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:62:24
+ --> $DIR/trait_duplication_in_bounds.rs:61:24
|
LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
error: these where clauses contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:69:12
+ --> $DIR/trait_duplication_in_bounds.rs:68:12
|
LL | T: Clone + Clone + Clone + Copy,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:102:19
+ --> $DIR/trait_duplication_in_bounds.rs:101:19
|
LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait<u64> + GenericTrait<u32>`
error: these bounds contain repeated elements
- --> $DIR/trait_duplication_in_bounds.rs:110:22
+ --> $DIR/trait_duplication_in_bounds.rs:109:22
|
LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone`
error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds.rs:118:33
+ --> $DIR/trait_duplication_in_bounds.rs:117:33
|
LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {
| ^^^^^^^^^^^^^^^^^ help: try: `Any + Send`
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs
index 5630a0345..effed3a26 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.rs
@@ -4,6 +4,8 @@ use std::collections::BTreeMap;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
+//~^ ERROR: this trait bound is already specified in the where clause
+//~| ERROR: this trait bound is already specified in the where clause
where
T: Clone,
T: Default,
@@ -33,6 +35,7 @@ trait T: Default {
fn f()
where
Self: Default;
+ //~^ ERROR: this trait bound is already specified in trait declaration
}
trait U: Default {
@@ -47,15 +50,19 @@ trait ZZ: Default {
fn f()
where
Self: Default + Clone;
+ //~^ ERROR: this trait bound is already specified in trait declaration
}
trait BadTrait: Default + Clone {
fn f()
where
Self: Default + Clone;
+ //~^ ERROR: this trait bound is already specified in trait declaration
+ //~| ERROR: this trait bound is already specified in trait declaration
fn g()
where
Self: Default;
+ //~^ ERROR: this trait bound is already specified in trait declaration
fn h()
where
Self: Copy;
@@ -91,6 +98,7 @@ trait FooIter: Iterator<Item = Foo> {
fn bar()
where
Self: Iterator<Item = Foo>,
+ //~^ ERROR: this trait bound is already specified in trait declaration
{
}
}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
index 4d56a9464..80dc7d8b6 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
@@ -20,7 +20,7 @@ LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
= help: consider removing this trait bound
error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds_unfixable.rs:35:15
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:37:15
|
LL | Self: Default;
| ^^^^^^^
@@ -28,7 +28,7 @@ LL | Self: Default;
= help: consider removing this trait bound
error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds_unfixable.rs:49:15
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:52:15
|
LL | Self: Default + Clone;
| ^^^^^^^
@@ -36,7 +36,7 @@ LL | Self: Default + Clone;
= help: consider removing this trait bound
error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds_unfixable.rs:55:15
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:59:15
|
LL | Self: Default + Clone;
| ^^^^^^^
@@ -44,7 +44,7 @@ LL | Self: Default + Clone;
= help: consider removing this trait bound
error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds_unfixable.rs:55:25
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:59:25
|
LL | Self: Default + Clone;
| ^^^^^
@@ -52,7 +52,7 @@ LL | Self: Default + Clone;
= help: consider removing this trait bound
error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds_unfixable.rs:58:15
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:64:15
|
LL | Self: Default;
| ^^^^^^^
@@ -60,7 +60,7 @@ LL | Self: Default;
= help: consider removing this trait bound
error: this trait bound is already specified in trait declaration
- --> $DIR/trait_duplication_in_bounds_unfixable.rs:93:15
+ --> $DIR/trait_duplication_in_bounds_unfixable.rs:100:15
|
LL | Self: Iterator<Item = Foo>,
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs
index 1cbacf0fe..32f6027e9 100644
--- a/src/tools/clippy/tests/ui/transmute.rs
+++ b/src/tools/clippy/tests/ui/transmute.rs
@@ -1,5 +1,5 @@
#![allow(dead_code, clippy::borrow_as_ptr, clippy::needless_lifetimes)]
-
+//@no-rustfix
extern crate core;
use std::mem::transmute as my_transmute;
@@ -22,30 +22,41 @@ unsafe fn _generic<'a, T, U: 'a>(t: &'a T) {
let _: &'a U = core::intrinsics::transmute(t);
let _: *const T = core::intrinsics::transmute(t);
+ //~^ ERROR: transmute from a reference to a pointer
+ //~| NOTE: `-D clippy::useless-transmute` implied by `-D warnings`
let _: *mut T = core::intrinsics::transmute(t);
+ //~^ ERROR: transmute from a reference to a pointer
let _: *const U = core::intrinsics::transmute(t);
+ //~^ ERROR: transmute from a reference to a pointer
}
#[warn(clippy::useless_transmute)]
fn useless() {
unsafe {
let _: Vec<i32> = core::intrinsics::transmute(my_vec());
+ //~^ ERROR: transmute from a type (`std::vec::Vec<i32>`) to itself
let _: Vec<i32> = core::mem::transmute(my_vec());
+ //~^ ERROR: transmute from a type (`std::vec::Vec<i32>`) to itself
let _: Vec<i32> = std::intrinsics::transmute(my_vec());
+ //~^ ERROR: transmute from a type (`std::vec::Vec<i32>`) to itself
let _: Vec<i32> = std::mem::transmute(my_vec());
+ //~^ ERROR: transmute from a type (`std::vec::Vec<i32>`) to itself
let _: Vec<i32> = my_transmute(my_vec());
+ //~^ ERROR: transmute from a type (`std::vec::Vec<i32>`) to itself
let _: *const usize = std::mem::transmute(5_isize);
+ //~^ ERROR: transmute from an integer to a pointer
let _ = 5_isize as *const usize;
let _: *const usize = std::mem::transmute(1 + 1usize);
+ //~^ ERROR: transmute from an integer to a pointer
let _ = (1 + 1_usize) as *const usize;
}
@@ -77,19 +88,27 @@ fn crosspointer() {
unsafe {
let _: Usize = core::intrinsics::transmute(int_const_ptr);
+ //~^ ERROR: transmute from a type (`*const Usize`) to the type that it points to (
+ //~| NOTE: `-D clippy::crosspointer-transmute` implied by `-D warnings`
let _: Usize = core::intrinsics::transmute(int_mut_ptr);
+ //~^ ERROR: transmute from a type (`*mut Usize`) to the type that it points to (`U
let _: *const Usize = core::intrinsics::transmute(my_int());
+ //~^ ERROR: transmute from a type (`Usize`) to a pointer to that type (`*const Usi
let _: *mut Usize = core::intrinsics::transmute(my_int());
+ //~^ ERROR: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize
}
}
#[warn(clippy::transmute_int_to_char)]
fn int_to_char() {
let _: char = unsafe { std::mem::transmute(0_u32) };
+ //~^ ERROR: transmute from a `u32` to a `char`
+ //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
let _: char = unsafe { std::mem::transmute(0_i32) };
+ //~^ ERROR: transmute from a `i32` to a `char`
// These shouldn't warn
const _: char = unsafe { std::mem::transmute(0_u32) };
@@ -99,15 +118,22 @@ fn int_to_char() {
#[warn(clippy::transmute_int_to_bool)]
fn int_to_bool() {
let _: bool = unsafe { std::mem::transmute(0_u8) };
+ //~^ ERROR: transmute from a `u8` to a `bool`
+ //~| NOTE: `-D clippy::transmute-int-to-bool` implied by `-D warnings`
}
#[warn(clippy::transmute_int_to_float)]
mod int_to_float {
fn test() {
let _: f32 = unsafe { std::mem::transmute(0_u32) };
+ //~^ ERROR: transmute from a `u32` to a `f32`
+ //~| NOTE: `-D clippy::transmute-int-to-float` implied by `-D warnings`
let _: f32 = unsafe { std::mem::transmute(0_i32) };
+ //~^ ERROR: transmute from a `i32` to a `f32`
let _: f64 = unsafe { std::mem::transmute(0_u64) };
+ //~^ ERROR: transmute from a `u64` to a `f64`
let _: f64 = unsafe { std::mem::transmute(0_i64) };
+ //~^ ERROR: transmute from a `i64` to a `f64`
}
mod issue_5747 {
@@ -128,23 +154,38 @@ mod num_to_bytes {
fn test() {
unsafe {
let _: [u8; 1] = std::mem::transmute(0u8);
+ //~^ ERROR: transmute from a `u8` to a `[u8; 1]`
+ //~| NOTE: `-D clippy::transmute-num-to-bytes` implied by `-D warnings`
let _: [u8; 4] = std::mem::transmute(0u32);
+ //~^ ERROR: transmute from a `u32` to a `[u8; 4]`
let _: [u8; 16] = std::mem::transmute(0u128);
+ //~^ ERROR: transmute from a `u128` to a `[u8; 16]`
let _: [u8; 1] = std::mem::transmute(0i8);
+ //~^ ERROR: transmute from a `i8` to a `[u8; 1]`
let _: [u8; 4] = std::mem::transmute(0i32);
+ //~^ ERROR: transmute from a `i32` to a `[u8; 4]`
let _: [u8; 16] = std::mem::transmute(0i128);
+ //~^ ERROR: transmute from a `i128` to a `[u8; 16]`
let _: [u8; 4] = std::mem::transmute(0.0f32);
+ //~^ ERROR: transmute from a `f32` to a `[u8; 4]`
let _: [u8; 8] = std::mem::transmute(0.0f64);
+ //~^ ERROR: transmute from a `f64` to a `[u8; 8]`
}
}
const fn test_const() {
unsafe {
let _: [u8; 1] = std::mem::transmute(0u8);
+ //~^ ERROR: transmute from a `u8` to a `[u8; 1]`
let _: [u8; 4] = std::mem::transmute(0u32);
+ //~^ ERROR: transmute from a `u32` to a `[u8; 4]`
let _: [u8; 16] = std::mem::transmute(0u128);
+ //~^ ERROR: transmute from a `u128` to a `[u8; 16]`
let _: [u8; 1] = std::mem::transmute(0i8);
+ //~^ ERROR: transmute from a `i8` to a `[u8; 1]`
let _: [u8; 4] = std::mem::transmute(0i32);
+ //~^ ERROR: transmute from a `i32` to a `[u8; 4]`
let _: [u8; 16] = std::mem::transmute(0i128);
+ //~^ ERROR: transmute from a `i128` to a `[u8; 16]`
let _: [u8; 4] = std::mem::transmute(0.0f32);
let _: [u8; 8] = std::mem::transmute(0.0f64);
}
@@ -155,8 +196,12 @@ fn bytes_to_str(mb: &mut [u8]) {
const B: &[u8] = b"";
let _: &str = unsafe { std::mem::transmute(B) };
+ //~^ ERROR: transmute from a `&[u8]` to a `&str`
+ //~| NOTE: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
let _: &mut str = unsafe { std::mem::transmute(mb) };
+ //~^ ERROR: transmute from a `&mut [u8]` to a `&mut str`
const _: &str = unsafe { std::mem::transmute(B) };
+ //~^ ERROR: transmute from a `&[u8]` to a `&str`
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute.stderr b/src/tools/clippy/tests/ui/transmute.stderr
index 008b4a981..cdc733b54 100644
--- a/src/tools/clippy/tests/ui/transmute.stderr
+++ b/src/tools/clippy/tests/ui/transmute.stderr
@@ -5,237 +5,244 @@ LL | let _: *const T = core::intrinsics::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T`
|
= note: `-D clippy::useless-transmute` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]`
error: transmute from a reference to a pointer
- --> $DIR/transmute.rs:26:21
+ --> $DIR/transmute.rs:28:21
|
LL | let _: *mut T = core::intrinsics::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T`
error: transmute from a reference to a pointer
- --> $DIR/transmute.rs:28:23
+ --> $DIR/transmute.rs:31:23
|
LL | let _: *const U = core::intrinsics::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U`
error: transmute from a type (`std::vec::Vec<i32>`) to itself
- --> $DIR/transmute.rs:34:27
+ --> $DIR/transmute.rs:38:27
|
LL | let _: Vec<i32> = core::intrinsics::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself
- --> $DIR/transmute.rs:36:27
+ --> $DIR/transmute.rs:41:27
|
LL | let _: Vec<i32> = core::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself
- --> $DIR/transmute.rs:38:27
+ --> $DIR/transmute.rs:44:27
|
LL | let _: Vec<i32> = std::intrinsics::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself
- --> $DIR/transmute.rs:40:27
+ --> $DIR/transmute.rs:47:27
|
LL | let _: Vec<i32> = std::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself
- --> $DIR/transmute.rs:42:27
+ --> $DIR/transmute.rs:50:27
|
LL | let _: Vec<i32> = my_transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^
error: transmute from an integer to a pointer
- --> $DIR/transmute.rs:44:31
+ --> $DIR/transmute.rs:53:31
|
LL | let _: *const usize = std::mem::transmute(5_isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize`
error: transmute from an integer to a pointer
- --> $DIR/transmute.rs:48:31
+ --> $DIR/transmute.rs:58:31
|
LL | let _: *const usize = std::mem::transmute(1 + 1usize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize`
error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`)
- --> $DIR/transmute.rs:79:24
+ --> $DIR/transmute.rs:90:24
|
LL | let _: Usize = core::intrinsics::transmute(int_const_ptr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::crosspointer-transmute` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::crosspointer_transmute)]`
error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`)
- --> $DIR/transmute.rs:81:24
+ --> $DIR/transmute.rs:94:24
|
LL | let _: Usize = core::intrinsics::transmute(int_mut_ptr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`)
- --> $DIR/transmute.rs:83:31
+ --> $DIR/transmute.rs:97:31
|
LL | let _: *const Usize = core::intrinsics::transmute(my_int());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
- --> $DIR/transmute.rs:85:29
+ --> $DIR/transmute.rs:100:29
|
LL | let _: *mut Usize = core::intrinsics::transmute(my_int());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a `u32` to a `char`
- --> $DIR/transmute.rs:91:28
+ --> $DIR/transmute.rs:107:28
|
LL | let _: char = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
|
= note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
error: transmute from a `i32` to a `char`
- --> $DIR/transmute.rs:92:28
+ --> $DIR/transmute.rs:110:28
|
LL | let _: char = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
error: transmute from a `u8` to a `bool`
- --> $DIR/transmute.rs:101:28
+ --> $DIR/transmute.rs:120:28
|
LL | let _: bool = unsafe { std::mem::transmute(0_u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
|
= note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]`
error: transmute from a `u32` to a `f32`
- --> $DIR/transmute.rs:107:31
+ --> $DIR/transmute.rs:128:31
|
LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
|
= note: `-D clippy::transmute-int-to-float` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]`
error: transmute from a `i32` to a `f32`
- --> $DIR/transmute.rs:108:31
+ --> $DIR/transmute.rs:131:31
|
LL | let _: f32 = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
error: transmute from a `u64` to a `f64`
- --> $DIR/transmute.rs:109:31
+ --> $DIR/transmute.rs:133:31
|
LL | let _: f64 = unsafe { std::mem::transmute(0_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
error: transmute from a `i64` to a `f64`
- --> $DIR/transmute.rs:110:31
+ --> $DIR/transmute.rs:135:31
|
LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
error: transmute from a `u8` to a `[u8; 1]`
- --> $DIR/transmute.rs:130:30
+ --> $DIR/transmute.rs:156:30
|
LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
|
= note: `-D clippy::transmute-num-to-bytes` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
error: transmute from a `u32` to a `[u8; 4]`
- --> $DIR/transmute.rs:131:30
+ --> $DIR/transmute.rs:159:30
|
LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]`
- --> $DIR/transmute.rs:132:31
+ --> $DIR/transmute.rs:161:31
|
LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]`
- --> $DIR/transmute.rs:133:30
+ --> $DIR/transmute.rs:163:30
|
LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]`
- --> $DIR/transmute.rs:134:30
+ --> $DIR/transmute.rs:165:30
|
LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]`
- --> $DIR/transmute.rs:135:31
+ --> $DIR/transmute.rs:167:31
|
LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `f32` to a `[u8; 4]`
- --> $DIR/transmute.rs:136:30
+ --> $DIR/transmute.rs:169:30
|
LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
error: transmute from a `f64` to a `[u8; 8]`
- --> $DIR/transmute.rs:137:30
+ --> $DIR/transmute.rs:171:30
|
LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
error: transmute from a `u8` to a `[u8; 1]`
- --> $DIR/transmute.rs:142:30
+ --> $DIR/transmute.rs:177:30
|
LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
error: transmute from a `u32` to a `[u8; 4]`
- --> $DIR/transmute.rs:143:30
+ --> $DIR/transmute.rs:179:30
|
LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]`
- --> $DIR/transmute.rs:144:31
+ --> $DIR/transmute.rs:181:31
|
LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]`
- --> $DIR/transmute.rs:145:30
+ --> $DIR/transmute.rs:183:30
|
LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]`
- --> $DIR/transmute.rs:146:30
+ --> $DIR/transmute.rs:185:30
|
LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]`
- --> $DIR/transmute.rs:147:31
+ --> $DIR/transmute.rs:187:31
|
LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `&[u8]` to a `&str`
- --> $DIR/transmute.rs:157:28
+ --> $DIR/transmute.rs:198:28
|
LL | let _: &str = unsafe { std::mem::transmute(B) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
|
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
error: transmute from a `&mut [u8]` to a `&mut str`
- --> $DIR/transmute.rs:158:32
+ --> $DIR/transmute.rs:201:32
|
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
error: transmute from a `&[u8]` to a `&str`
- --> $DIR/transmute.rs:159:30
+ --> $DIR/transmute.rs:203:30
|
LL | const _: &str = unsafe { std::mem::transmute(B) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
diff --git a/src/tools/clippy/tests/ui/transmute_32bit.stderr b/src/tools/clippy/tests/ui/transmute_32bit.stderr
index 75ddca60d..baa819e30 100644
--- a/src/tools/clippy/tests/ui/transmute_32bit.stderr
+++ b/src/tools/clippy/tests/ui/transmute_32bit.stderr
@@ -1,39 +1,29 @@
-error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+error: transmute from a `f32` to a pointer
--> $DIR/transmute_32bit.rs:6:31
|
LL | let _: *const usize = std::mem::transmute(6.0f32);
- | ^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: source type: `f32` (32 bits)
- = note: target type: `*const usize` (64 bits)
+ = note: `-D clippy::wrong-transmute` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wrong_transmute)]`
-error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+error: transmute from a `f32` to a pointer
--> $DIR/transmute_32bit.rs:8:29
|
LL | let _: *mut usize = std::mem::transmute(6.0f32);
- | ^^^^^^^^^^^^^^^^^^^
- |
- = note: source type: `f32` (32 bits)
- = note: target type: `*mut usize` (64 bits)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+error: transmute from a `char` to a pointer
--> $DIR/transmute_32bit.rs:10:31
|
LL | let _: *const usize = std::mem::transmute('x');
- | ^^^^^^^^^^^^^^^^^^^
- |
- = note: source type: `char` (32 bits)
- = note: target type: `*const usize` (64 bits)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+error: transmute from a `char` to a pointer
--> $DIR/transmute_32bit.rs:12:29
|
LL | let _: *mut usize = std::mem::transmute('x');
- | ^^^^^^^^^^^^^^^^^^^
- |
- = note: source type: `char` (32 bits)
- = note: target type: `*mut usize` (64 bits)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
-For more information about this error, try `rustc --explain E0512`.
diff --git a/src/tools/clippy/tests/ui/transmute_64bit.rs b/src/tools/clippy/tests/ui/transmute_64bit.rs
index ceecf9b27..767cc503a 100644
--- a/src/tools/clippy/tests/ui/transmute_64bit.rs
+++ b/src/tools/clippy/tests/ui/transmute_64bit.rs
@@ -4,7 +4,10 @@
fn main() {
unsafe {
let _: *const usize = std::mem::transmute(6.0f64);
+ //~^ ERROR: transmute from a `f64` to a pointer
+ //~| NOTE: `-D clippy::wrong-transmute` implied by `-D warnings`
let _: *mut usize = std::mem::transmute(6.0f64);
+ //~^ ERROR: transmute from a `f64` to a pointer
}
}
diff --git a/src/tools/clippy/tests/ui/transmute_64bit.stderr b/src/tools/clippy/tests/ui/transmute_64bit.stderr
index d1854c009..a30480eb7 100644
--- a/src/tools/clippy/tests/ui/transmute_64bit.stderr
+++ b/src/tools/clippy/tests/ui/transmute_64bit.stderr
@@ -5,9 +5,10 @@ LL | let _: *const usize = std::mem::transmute(6.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::wrong-transmute` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wrong_transmute)]`
error: transmute from a `f64` to a pointer
- --> $DIR/transmute_64bit.rs:8:29
+ --> $DIR/transmute_64bit.rs:10:29
|
LL | let _: *mut usize = std::mem::transmute(6.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/transmute_collection.rs b/src/tools/clippy/tests/ui/transmute_collection.rs
index 5a431bee0..8bf454573 100644
--- a/src/tools/clippy/tests/ui/transmute_collection.rs
+++ b/src/tools/clippy/tests/ui/transmute_collection.rs
@@ -7,42 +7,61 @@ fn main() {
unsafe {
// wrong size
let _ = transmute::<_, Vec<u32>>(vec![0u8]);
+ //~^ ERROR: transmute from `std::vec::Vec<u8>` to `std::vec::Vec<u32>` with mismat
+ //~| NOTE: `-D clippy::unsound-collection-transmute` implied by `-D warnings`
// wrong layout
let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]);
+ //~^ ERROR: transmute from `std::vec::Vec<u32>` to `std::vec::Vec<[u8; 4]>` with m
// wrong size
let _ = transmute::<_, VecDeque<u32>>(VecDeque::<u8>::new());
+ //~^ ERROR: transmute from `std::collections::VecDeque<u8>` to `std::collections::
// wrong layout
let _ = transmute::<_, VecDeque<u32>>(VecDeque::<[u8; 4]>::new());
+ //~^ ERROR: transmute from `std::collections::VecDeque<[u8; 4]>` to `std::collecti
// wrong size
let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<u8>::new());
+ //~^ ERROR: transmute from `std::collections::BinaryHeap<u8>` to `std::collections
// wrong layout
let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<[u8; 4]>::new());
+ //~^ ERROR: transmute from `std::collections::BinaryHeap<[u8; 4]>` to `std::collec
// wrong size
let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<u8>::new());
+ //~^ ERROR: transmute from `std::collections::BTreeSet<u8>` to `std::collections::
// wrong layout
let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<[u8; 4]>::new());
+ //~^ ERROR: transmute from `std::collections::BTreeSet<[u8; 4]>` to `std::collecti
// wrong size
let _ = transmute::<_, HashSet<u32>>(HashSet::<u8>::new());
+ //~^ ERROR: transmute from `std::collections::HashSet<u8>` to `std::collections::H
// wrong layout
let _ = transmute::<_, HashSet<u32>>(HashSet::<[u8; 4]>::new());
+ //~^ ERROR: transmute from `std::collections::HashSet<[u8; 4]>` to `std::collectio
// wrong size
let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, u8>::new());
+ //~^ ERROR: transmute from `std::collections::BTreeMap<u8, u8>` to `std::collectio
let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u32, u32>::new());
+ //~^ ERROR: transmute from `std::collections::BTreeMap<u32, u32>` to `std::collect
// wrong layout
let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, [u8; 4]>::new());
+ //~^ ERROR: transmute from `std::collections::BTreeMap<u8, [u8; 4]>` to `std::coll
let _ = transmute::<_, BTreeMap<u32, u32>>(BTreeMap::<[u8; 4], u32>::new());
+ //~^ ERROR: transmute from `std::collections::BTreeMap<[u8; 4], u32>` to `std::col
// wrong size
let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, u8>::new());
+ //~^ ERROR: transmute from `std::collections::HashMap<u8, u8>` to `std::collection
let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u32, u32>::new());
+ //~^ ERROR: transmute from `std::collections::HashMap<u32, u32>` to `std::collecti
// wrong layout
let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, [u8; 4]>::new());
+ //~^ ERROR: transmute from `std::collections::HashMap<u8, [u8; 4]>` to `std::colle
let _ = transmute::<_, HashMap<u32, u32>>(HashMap::<[u8; 4], u32>::new());
+ //~^ ERROR: transmute from `std::collections::HashMap<[u8; 4], u32>` to `std::coll
let _ = transmute::<_, Vec<u8>>(Vec::<MaybeUninit<u8>>::new());
let _ = transmute::<_, Vec<*mut u32>>(Vec::<Box<u32>>::new());
diff --git a/src/tools/clippy/tests/ui/transmute_collection.stderr b/src/tools/clippy/tests/ui/transmute_collection.stderr
index ebc05c402..2163142ee 100644
--- a/src/tools/clippy/tests/ui/transmute_collection.stderr
+++ b/src/tools/clippy/tests/ui/transmute_collection.stderr
@@ -5,105 +5,106 @@ LL | let _ = transmute::<_, Vec<u32>>(vec![0u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unsound-collection-transmute` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unsound_collection_transmute)]`
error: transmute from `std::vec::Vec<u32>` to `std::vec::Vec<[u8; 4]>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:11:17
+ --> $DIR/transmute_collection.rs:13:17
|
LL | let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::VecDeque<u8>` to `std::collections::VecDeque<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:14:17
+ --> $DIR/transmute_collection.rs:17:17
|
LL | let _ = transmute::<_, VecDeque<u32>>(VecDeque::<u8>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::VecDeque<[u8; 4]>` to `std::collections::VecDeque<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:16:17
+ --> $DIR/transmute_collection.rs:20:17
|
LL | let _ = transmute::<_, VecDeque<u32>>(VecDeque::<[u8; 4]>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BinaryHeap<u8>` to `std::collections::BinaryHeap<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:19:17
+ --> $DIR/transmute_collection.rs:24:17
|
LL | let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<u8>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BinaryHeap<[u8; 4]>` to `std::collections::BinaryHeap<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:21:17
+ --> $DIR/transmute_collection.rs:27:17
|
LL | let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<[u8; 4]>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BTreeSet<u8>` to `std::collections::BTreeSet<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:24:17
+ --> $DIR/transmute_collection.rs:31:17
|
LL | let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<u8>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BTreeSet<[u8; 4]>` to `std::collections::BTreeSet<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:26:17
+ --> $DIR/transmute_collection.rs:34:17
|
LL | let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<[u8; 4]>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::HashSet<u8>` to `std::collections::HashSet<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:29:17
+ --> $DIR/transmute_collection.rs:38:17
|
LL | let _ = transmute::<_, HashSet<u32>>(HashSet::<u8>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::HashSet<[u8; 4]>` to `std::collections::HashSet<u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:31:17
+ --> $DIR/transmute_collection.rs:41:17
|
LL | let _ = transmute::<_, HashSet<u32>>(HashSet::<[u8; 4]>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BTreeMap<u8, u8>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:34:17
+ --> $DIR/transmute_collection.rs:45:17
|
LL | let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, u8>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BTreeMap<u32, u32>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:35:17
+ --> $DIR/transmute_collection.rs:47:17
|
LL | let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u32, u32>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BTreeMap<u8, [u8; 4]>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:37:17
+ --> $DIR/transmute_collection.rs:50:17
|
LL | let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, [u8; 4]>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::BTreeMap<[u8; 4], u32>` to `std::collections::BTreeMap<u32, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:38:17
+ --> $DIR/transmute_collection.rs:52:17
|
LL | let _ = transmute::<_, BTreeMap<u32, u32>>(BTreeMap::<[u8; 4], u32>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::HashMap<u8, u8>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:41:17
+ --> $DIR/transmute_collection.rs:56:17
|
LL | let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, u8>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::HashMap<u32, u32>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:42:17
+ --> $DIR/transmute_collection.rs:58:17
|
LL | let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u32, u32>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::HashMap<u8, [u8; 4]>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:44:17
+ --> $DIR/transmute_collection.rs:61:17
|
LL | let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, [u8; 4]>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `std::collections::HashMap<[u8; 4], u32>` to `std::collections::HashMap<u32, u32>` with mismatched layout is unsound
- --> $DIR/transmute_collection.rs:45:17
+ --> $DIR/transmute_collection.rs:63:17
|
LL | let _ = transmute::<_, HashMap<u32, u32>>(HashMap::<[u8; 4], u32>::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
new file mode 100644
index 000000000..cef0bcfa6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
@@ -0,0 +1,32 @@
+#![warn(clippy::transmute_float_to_int)]
+
+fn float_to_int() {
+ let _: u32 = unsafe { 1f32.to_bits() };
+ //~^ ERROR: transmute from a `f32` to a `u32`
+ //~| NOTE: `-D clippy::transmute-float-to-int` implied by `-D warnings`
+ let _: i32 = unsafe { 1f32.to_bits() as i32 };
+ //~^ ERROR: transmute from a `f32` to a `i32`
+ let _: u64 = unsafe { 1f64.to_bits() };
+ //~^ ERROR: transmute from a `f64` to a `u64`
+ let _: i64 = unsafe { 1f64.to_bits() as i64 };
+ //~^ ERROR: transmute from a `f64` to a `i64`
+ let _: u64 = unsafe { 1.0f64.to_bits() };
+ //~^ ERROR: transmute from a `f64` to a `u64`
+ let _: u64 = unsafe { (-1.0f64).to_bits() };
+ //~^ ERROR: transmute from a `f64` to a `u64`
+}
+
+mod issue_5747 {
+ const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
+ const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
+
+ const fn to_bits_32(v: f32) -> u32 {
+ unsafe { std::mem::transmute(v) }
+ }
+
+ const fn to_bits_64(v: f64) -> i64 {
+ unsafe { std::mem::transmute(v) }
+ }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.rs b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
index 806b2d77d..3d95bec2a 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.rs
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
@@ -2,11 +2,18 @@
fn float_to_int() {
let _: u32 = unsafe { std::mem::transmute(1f32) };
+ //~^ ERROR: transmute from a `f32` to a `u32`
+ //~| NOTE: `-D clippy::transmute-float-to-int` implied by `-D warnings`
let _: i32 = unsafe { std::mem::transmute(1f32) };
+ //~^ ERROR: transmute from a `f32` to a `i32`
let _: u64 = unsafe { std::mem::transmute(1f64) };
+ //~^ ERROR: transmute from a `f64` to a `u64`
let _: i64 = unsafe { std::mem::transmute(1f64) };
+ //~^ ERROR: transmute from a `f64` to a `i64`
let _: u64 = unsafe { std::mem::transmute(1.0) };
+ //~^ ERROR: transmute from a `f64` to a `u64`
let _: u64 = unsafe { std::mem::transmute(-1.0) };
+ //~^ ERROR: transmute from a `f64` to a `u64`
}
mod issue_5747 {
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.stderr b/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
index eb786bb39..1895120c0 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
@@ -5,33 +5,34 @@ LL | let _: u32 = unsafe { std::mem::transmute(1f32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits()`
|
= note: `-D clippy::transmute-float-to-int` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_float_to_int)]`
error: transmute from a `f32` to a `i32`
- --> $DIR/transmute_float_to_int.rs:5:27
+ --> $DIR/transmute_float_to_int.rs:7:27
|
LL | let _: i32 = unsafe { std::mem::transmute(1f32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32`
error: transmute from a `f64` to a `u64`
- --> $DIR/transmute_float_to_int.rs:6:27
+ --> $DIR/transmute_float_to_int.rs:9:27
|
LL | let _: u64 = unsafe { std::mem::transmute(1f64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()`
error: transmute from a `f64` to a `i64`
- --> $DIR/transmute_float_to_int.rs:7:27
+ --> $DIR/transmute_float_to_int.rs:11:27
|
LL | let _: i64 = unsafe { std::mem::transmute(1f64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits() as i64`
error: transmute from a `f64` to a `u64`
- --> $DIR/transmute_float_to_int.rs:8:27
+ --> $DIR/transmute_float_to_int.rs:13:27
|
LL | let _: u64 = unsafe { std::mem::transmute(1.0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.0f64.to_bits()`
error: transmute from a `f64` to a `u64`
- --> $DIR/transmute_float_to_int.rs:9:27
+ --> $DIR/transmute_float_to_int.rs:15:27
|
LL | let _: u64 = unsafe { std::mem::transmute(-1.0) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()`
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed
new file mode 100644
index 000000000..866c0bbf1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed
@@ -0,0 +1,52 @@
+#![warn(clippy::transmute_int_to_non_zero)]
+
+use core::num::*;
+
+fn main() {
+ let int_u8: u8 = 1;
+ let int_u16: u16 = 1;
+ let int_u32: u32 = 1;
+ let int_u64: u64 = 1;
+ let int_u128: u128 = 1;
+
+ let int_i8: i8 = 1;
+ let int_i16: i16 = 1;
+ let int_i32: i32 = 1;
+ let int_i64: i64 = 1;
+ let int_i128: i128 = 1;
+
+ let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) };
+ //~^ ERROR: transmute from a `u8` to a `NonZeroU8`
+ //~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings`
+ let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) };
+ //~^ ERROR: transmute from a `u16` to a `NonZeroU16`
+ let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) };
+ //~^ ERROR: transmute from a `u32` to a `NonZeroU32`
+ let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) };
+ //~^ ERROR: transmute from a `u64` to a `NonZeroU64`
+ let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) };
+ //~^ ERROR: transmute from a `u128` to a `NonZeroU128`
+
+ let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) };
+ //~^ ERROR: transmute from a `i8` to a `NonZeroI8`
+ let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) };
+ //~^ ERROR: transmute from a `i16` to a `NonZeroI16`
+ let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) };
+ //~^ ERROR: transmute from a `i32` to a `NonZeroI32`
+ let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) };
+ //~^ ERROR: transmute from a `i64` to a `NonZeroI64`
+ let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) };
+ //~^ ERROR: transmute from a `i128` to a `NonZeroI128`
+
+ let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) };
+ let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) };
+ let _: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(int_u32) };
+ let _: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(int_u64) };
+ let _: NonZeroU128 = unsafe { NonZeroU128::new_unchecked(int_u128) };
+
+ let _: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(int_i8) };
+ let _: NonZeroI16 = unsafe { NonZeroI16::new_unchecked(int_i16) };
+ let _: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(int_i32) };
+ let _: NonZeroI64 = unsafe { NonZeroI64::new_unchecked(int_i64) };
+ let _: NonZeroI128 = unsafe { NonZeroI128::new_unchecked(int_i128) };
+}
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs
index a38406782..803c4945c 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs
+++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs
@@ -16,16 +16,27 @@ fn main() {
let int_i128: i128 = 1;
let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) };
+ //~^ ERROR: transmute from a `u8` to a `NonZeroU8`
+ //~| NOTE: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings`
let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) };
+ //~^ ERROR: transmute from a `u16` to a `NonZeroU16`
let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) };
+ //~^ ERROR: transmute from a `u32` to a `NonZeroU32`
let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) };
+ //~^ ERROR: transmute from a `u64` to a `NonZeroU64`
let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) };
+ //~^ ERROR: transmute from a `u128` to a `NonZeroU128`
let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) };
+ //~^ ERROR: transmute from a `i8` to a `NonZeroI8`
let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) };
+ //~^ ERROR: transmute from a `i16` to a `NonZeroI16`
let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) };
+ //~^ ERROR: transmute from a `i32` to a `NonZeroI32`
let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) };
+ //~^ ERROR: transmute from a `i64` to a `NonZeroI64`
let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) };
+ //~^ ERROR: transmute from a `i128` to a `NonZeroI128`
let _: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(int_u8) };
let _: NonZeroU16 = unsafe { NonZeroU16::new_unchecked(int_u16) };
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr
index 33f8ce79e..b79a80c32 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr
+++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr
@@ -5,57 +5,58 @@ LL | let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU8::new_unchecked(int_u8)`
|
= note: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_non_zero)]`
error: transmute from a `u16` to a `NonZeroU16`
- --> $DIR/transmute_int_to_non_zero.rs:19:34
+ --> $DIR/transmute_int_to_non_zero.rs:21:34
|
LL | let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU16::new_unchecked(int_u16)`
error: transmute from a `u32` to a `NonZeroU32`
- --> $DIR/transmute_int_to_non_zero.rs:20:34
+ --> $DIR/transmute_int_to_non_zero.rs:23:34
|
LL | let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU32::new_unchecked(int_u32)`
error: transmute from a `u64` to a `NonZeroU64`
- --> $DIR/transmute_int_to_non_zero.rs:21:34
+ --> $DIR/transmute_int_to_non_zero.rs:25:34
|
LL | let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU64::new_unchecked(int_u64)`
error: transmute from a `u128` to a `NonZeroU128`
- --> $DIR/transmute_int_to_non_zero.rs:22:35
+ --> $DIR/transmute_int_to_non_zero.rs:27:35
|
LL | let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU128::new_unchecked(int_u128)`
error: transmute from a `i8` to a `NonZeroI8`
- --> $DIR/transmute_int_to_non_zero.rs:24:33
+ --> $DIR/transmute_int_to_non_zero.rs:30:33
|
LL | let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI8::new_unchecked(int_i8)`
error: transmute from a `i16` to a `NonZeroI16`
- --> $DIR/transmute_int_to_non_zero.rs:25:34
+ --> $DIR/transmute_int_to_non_zero.rs:32:34
|
LL | let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI16::new_unchecked(int_i16)`
error: transmute from a `i32` to a `NonZeroI32`
- --> $DIR/transmute_int_to_non_zero.rs:26:34
+ --> $DIR/transmute_int_to_non_zero.rs:34:34
|
LL | let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI32::new_unchecked(int_i32)`
error: transmute from a `i64` to a `NonZeroI64`
- --> $DIR/transmute_int_to_non_zero.rs:27:34
+ --> $DIR/transmute_int_to_non_zero.rs:36:34
|
LL | let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI64::new_unchecked(int_i64)`
error: transmute from a `i128` to a `NonZeroI128`
- --> $DIR/transmute_int_to_non_zero.rs:28:35
+ --> $DIR/transmute_int_to_non_zero.rs:38:35
|
LL | let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI128::new_unchecked(int_i128)`
diff --git a/src/tools/clippy/tests/ui/transmute_null_to_fn.rs b/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
index b3ea3d903..b07851e86 100644
--- a/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
+++ b/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
@@ -6,7 +6,9 @@
fn one_liners() {
unsafe {
let _: fn() = std::mem::transmute(0 as *const ());
+ //~^ ERROR: transmuting a known null pointer into a function pointer
let _: fn() = std::mem::transmute(std::ptr::null::<()>());
+ //~^ ERROR: transmuting a known null pointer into a function pointer
}
}
@@ -17,11 +19,23 @@ fn transmute_const() {
unsafe {
// Should raise a lint.
let _: fn() = std::mem::transmute(ZPTR);
+ //~^ ERROR: transmuting a known null pointer into a function pointer
// Should NOT raise a lint.
let _: fn() = std::mem::transmute(NOT_ZPTR);
}
}
+fn issue_11485() {
+ unsafe {
+ let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
+ //~^ ERROR: transmuting a known null pointer into a function pointer
+ let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+ //~^ ERROR: transmuting a known null pointer into a function pointer
+ let _: fn() = std::mem::transmute(ZPTR as *const u8);
+ //~^ ERROR: transmuting a known null pointer into a function pointer
+ }
+}
+
fn main() {
one_liners();
transmute_const();
diff --git a/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr b/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
index f0c65497d..9073080cb 100644
--- a/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
+++ b/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
@@ -6,9 +6,10 @@ LL | let _: fn() = std::mem::transmute(0 as *const ());
|
= help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
= note: `-D clippy::transmute-null-to-fn` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_null_to_fn)]`
error: transmuting a known null pointer into a function pointer
- --> $DIR/transmute_null_to_fn.rs:9:23
+ --> $DIR/transmute_null_to_fn.rs:10:23
|
LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
@@ -16,12 +17,36 @@ LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>());
= help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
error: transmuting a known null pointer into a function pointer
- --> $DIR/transmute_null_to_fn.rs:19:23
+ --> $DIR/transmute_null_to_fn.rs:21:23
|
LL | let _: fn() = std::mem::transmute(ZPTR);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
|
= help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
-error: aborting due to 3 previous errors
+error: transmuting a known null pointer into a function pointer
+ --> $DIR/transmute_null_to_fn.rs:30:23
+ |
+LL | let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+ |
+ = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: transmuting a known null pointer into a function pointer
+ --> $DIR/transmute_null_to_fn.rs:32:23
+ |
+LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+ |
+ = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: transmuting a known null pointer into a function pointer
+ --> $DIR/transmute_null_to_fn.rs:34:23
+ |
+LL | let _: fn() = std::mem::transmute(ZPTR as *const u8);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+ |
+ = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed
new file mode 100644
index 000000000..19abced98
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed
@@ -0,0 +1,70 @@
+#![warn(clippy::transmute_ptr_to_ptr)]
+#![allow(clippy::borrow_as_ptr)]
+
+// Make sure we can modify lifetimes, which is one of the recommended uses
+// of transmute
+
+// Make sure we can do static lifetime transmutes
+unsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {
+ std::mem::transmute::<&'a T, &'static T>(t)
+}
+
+// Make sure we can do non-static lifetime transmutes
+unsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {
+ std::mem::transmute::<&'a T, &'b T>(t)
+}
+
+struct LifetimeParam<'a> {
+ s: &'a str,
+}
+
+struct GenericParam<T> {
+ t: T,
+}
+
+fn transmute_ptr_to_ptr() {
+ let ptr = &1u32 as *const u32;
+ let mut_ptr = &mut 1u32 as *mut u32;
+ unsafe {
+ // pointer-to-pointer transmutes; bad
+ let _: *const f32 = ptr as *const f32;
+ //~^ ERROR: transmute from a pointer to a pointer
+ //~| NOTE: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
+ let _: *mut f32 = mut_ptr as *mut f32;
+ //~^ ERROR: transmute from a pointer to a pointer
+ // ref-ref transmutes; bad
+ let _: &f32 = &*(&1u32 as *const u32 as *const f32);
+ //~^ ERROR: transmute from a reference to a reference
+ let _: &f64 = &*(&1f32 as *const f32 as *const f64);
+ //~^ ERROR: transmute from a reference to a reference
+ //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not
+ // the same type
+ let _: &mut f32 = &mut *(&mut 1u32 as *mut u32 as *mut f32);
+ //~^ ERROR: transmute from a reference to a reference
+ let _: &GenericParam<f32> = &*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>);
+ //~^ ERROR: transmute from a reference to a reference
+ }
+
+ // these are recommendations for solving the above; if these lint we need to update
+ // those suggestions
+ let _ = ptr as *const f32;
+ let _ = mut_ptr as *mut f32;
+ let _ = unsafe { &*(&1u32 as *const u32 as *const f32) };
+ let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) };
+
+ // transmute internal lifetimes, should not lint
+ let s = "hello world".to_owned();
+ let lp = LifetimeParam { s: &s };
+ let _: &LifetimeParam<'static> = unsafe { std::mem::transmute(&lp) };
+ let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
+}
+
+// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
+const _: &() = {
+ struct Zst;
+ let zst = &Zst;
+
+ unsafe { std::mem::transmute::<&'static Zst, &'static ()>(zst) }
+};
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
index 61a6c98ed..abba2b8e5 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
@@ -28,14 +28,21 @@ fn transmute_ptr_to_ptr() {
unsafe {
// pointer-to-pointer transmutes; bad
let _: *const f32 = std::mem::transmute(ptr);
+ //~^ ERROR: transmute from a pointer to a pointer
+ //~| NOTE: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
let _: *mut f32 = std::mem::transmute(mut_ptr);
+ //~^ ERROR: transmute from a pointer to a pointer
// ref-ref transmutes; bad
let _: &f32 = std::mem::transmute(&1u32);
+ //~^ ERROR: transmute from a reference to a reference
let _: &f64 = std::mem::transmute(&1f32);
+ //~^ ERROR: transmute from a reference to a reference
//:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not
// the same type
let _: &mut f32 = std::mem::transmute(&mut 1u32);
+ //~^ ERROR: transmute from a reference to a reference
let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 });
+ //~^ ERROR: transmute from a reference to a reference
}
// these are recommendations for solving the above; if these lint we need to update
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr
index 49a8a3347..564339c06 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr
@@ -5,33 +5,34 @@ LL | let _: *const f32 = std::mem::transmute(ptr);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr as *const f32`
|
= note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
error: transmute from a pointer to a pointer
- --> $DIR/transmute_ptr_to_ptr.rs:31:27
+ --> $DIR/transmute_ptr_to_ptr.rs:33:27
|
LL | let _: *mut f32 = std::mem::transmute(mut_ptr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `mut_ptr as *mut f32`
error: transmute from a reference to a reference
- --> $DIR/transmute_ptr_to_ptr.rs:33:23
+ --> $DIR/transmute_ptr_to_ptr.rs:36:23
|
LL | let _: &f32 = std::mem::transmute(&1u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)`
error: transmute from a reference to a reference
- --> $DIR/transmute_ptr_to_ptr.rs:34:23
+ --> $DIR/transmute_ptr_to_ptr.rs:38:23
|
LL | let _: &f64 = std::mem::transmute(&1f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1f32 as *const f32 as *const f64)`
error: transmute from a reference to a reference
- --> $DIR/transmute_ptr_to_ptr.rs:37:27
+ --> $DIR/transmute_ptr_to_ptr.rs:42:27
|
LL | let _: &mut f32 = std::mem::transmute(&mut 1u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)`
error: transmute from a reference to a reference
- --> $DIR/transmute_ptr_to_ptr.rs:38:37
+ --> $DIR/transmute_ptr_to_ptr.rs:44:37
|
LL | let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)`
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
index 215f0ac18..acec14ccb 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::transmute_ptr_to_ref)]
#![allow(clippy::match_single_binding, clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
index 3528e1379..3376401e2 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::transmute_ptr_to_ref)]
#![allow(clippy::match_single_binding, clippy::unnecessary_cast)]
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
index b3e6c09d2..9d1b22a79 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
@@ -1,133 +1,134 @@
error: transmute from a pointer type (`*const T`) to a reference type (`&T`)
- --> $DIR/transmute_ptr_to_ref.rs:7:17
+ --> $DIR/transmute_ptr_to_ref.rs:5:17
|
LL | let _: &T = std::mem::transmute(p);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*p`
|
= note: `-D clippy::transmute-ptr-to-ref` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ref)]`
error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)
- --> $DIR/transmute_ptr_to_ref.rs:10:21
+ --> $DIR/transmute_ptr_to_ref.rs:8:21
|
LL | let _: &mut T = std::mem::transmute(m);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *m`
error: transmute from a pointer type (`*mut T`) to a reference type (`&T`)
- --> $DIR/transmute_ptr_to_ref.rs:13:17
+ --> $DIR/transmute_ptr_to_ref.rs:11:17
|
LL | let _: &T = std::mem::transmute(m);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*m`
error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)
- --> $DIR/transmute_ptr_to_ref.rs:16:21
+ --> $DIR/transmute_ptr_to_ref.rs:14:21
|
LL | let _: &mut T = std::mem::transmute(p as *mut T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(p as *mut T)`
error: transmute from a pointer type (`*const U`) to a reference type (`&T`)
- --> $DIR/transmute_ptr_to_ref.rs:19:17
+ --> $DIR/transmute_ptr_to_ref.rs:17:17
|
LL | let _: &T = std::mem::transmute(o);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(o as *const T)`
error: transmute from a pointer type (`*mut U`) to a reference type (`&mut T`)
- --> $DIR/transmute_ptr_to_ref.rs:22:21
+ --> $DIR/transmute_ptr_to_ref.rs:20:21
|
LL | let _: &mut T = std::mem::transmute(om);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(om as *mut T)`
error: transmute from a pointer type (`*mut U`) to a reference type (`&T`)
- --> $DIR/transmute_ptr_to_ref.rs:25:17
+ --> $DIR/transmute_ptr_to_ref.rs:23:17
|
LL | let _: &T = std::mem::transmute(om);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(om as *const T)`
error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, u8>`)
- --> $DIR/transmute_ptr_to_ref.rs:35:32
+ --> $DIR/transmute_ptr_to_ref.rs:33:32
|
LL | let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<_>>()`
error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, &u8>`)
- --> $DIR/transmute_ptr_to_ref.rs:37:33
+ --> $DIR/transmute_ptr_to_ref.rs:35:33
|
LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<&_>>()`
error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`)
- --> $DIR/transmute_ptr_to_ref.rs:41:14
+ --> $DIR/transmute_ptr_to_ref.rs:39:14
|
LL | unsafe { std::mem::transmute::<_, Bar>(raw) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:46:14
+ --> $DIR/transmute_ptr_to_ref.rs:44:14
|
LL | 0 => std::mem::transmute(x),
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:47:14
+ --> $DIR/transmute_ptr_to_ref.rs:45:14
|
LL | 1 => std::mem::transmute(y),
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&u32>()`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:48:14
+ --> $DIR/transmute_ptr_to_ref.rs:46:14
|
LL | 2 => std::mem::transmute::<_, &&'b u32>(x),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:49:14
+ --> $DIR/transmute_ptr_to_ref.rs:47:14
|
LL | _ => std::mem::transmute::<_, &&'b u32>(y),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&'b u32>()`
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:57:19
+ --> $DIR/transmute_ptr_to_ref.rs:55:19
|
LL | let _: &u32 = std::mem::transmute(a);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:58:19
+ --> $DIR/transmute_ptr_to_ref.rs:56:19
|
LL | let _: &u32 = std::mem::transmute::<_, &u32>(a);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a.cast::<u32>()`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:60:14
+ --> $DIR/transmute_ptr_to_ref.rs:58:14
|
LL | 0 => std::mem::transmute(x),
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:61:14
+ --> $DIR/transmute_ptr_to_ref.rs:59:14
|
LL | _ => std::mem::transmute::<_, &&'b u32>(x),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:69:19
+ --> $DIR/transmute_ptr_to_ref.rs:67:19
|
LL | let _: &u32 = std::mem::transmute(a);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`
error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:70:19
+ --> $DIR/transmute_ptr_to_ref.rs:68:19
|
LL | let _: &u32 = std::mem::transmute::<_, &u32>(a);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const u32)`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:72:14
+ --> $DIR/transmute_ptr_to_ref.rs:70:14
|
LL | 0 => std::mem::transmute(x),
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &u32)`
error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
- --> $DIR/transmute_ptr_to_ref.rs:73:14
+ --> $DIR/transmute_ptr_to_ref.rs:71:14
|
LL | _ => std::mem::transmute::<_, &&'b u32>(x),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &'b u32)`
diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
index 5aad0b442..a087d09c1 100644
--- a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
+++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
@@ -25,102 +25,179 @@ fn main() {
let _: Ty<u32> = transmute(value::<u32>());
let _: Ty<u32> = transmute(value::<u32>());
- let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
- let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
-
- let _: Ty2<u32, i32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Ok, Ty2 types are the same
- let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
-
- let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
- let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
+ // Lint, Ty2 is unordered
+ let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>());
+ //~^ ERROR: transmute from `Ty2<u32, i32>` which has an undefined layout
+ //~| NOTE: `-D clippy::transmute-undefined-repr` implied by `-D warnings`
+ // Lint, Ty2 is unordered
+ let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>());
+ //~^ ERROR: transmute into `Ty2<u32, i32>` which has an undefined layout
+
+ // Ok, Ty2 types are the same
+ let _: Ty2<u32, i32> = transmute(value::<Ty<Ty2<u32, i32>>>());
+ // Ok, Ty2 types are the same
+ let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, i32>>());
+
+ // Lint, different Ty2 instances
+ let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>());
+ //~^ ERROR: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which h
+ //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou
+ // Lint, different Ty2 instances
+ let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>());
+ //~^ ERROR: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which h
+ //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou
let _: Ty<&()> = transmute(value::<&()>());
let _: &() = transmute(value::<Ty<&()>>());
- let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
- let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
-
- let _: Ty<usize> = transmute(value::<&Ty2<u32, i32>>()); // Ok, pointer to usize conversion
- let _: &Ty2<u32, i32> = transmute(value::<Ty<usize>>()); // Ok, pointer to usize conversion
-
- let _: Ty<[u8; 8]> = transmute(value::<Ty2<u32, i32>>()); // Ok, transmute to byte array
- let _: Ty2<u32, i32> = transmute(value::<Ty<[u8; 8]>>()); // Ok, transmute from byte array
+ // Lint, different Ty2 instances
+ let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>());
+ //~^ ERROR: transmute from `Ty<&Ty2<u32, i32>>` to `&Ty2<u32, f32>`, both of which
+ //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou
+ // Lint, different Ty2 instances
+ let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>());
+ //~^ ERROR: transmute from `&Ty2<u32, f32>` to `Ty<&Ty2<u32, i32>>`, both of which
+ //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou
+
+ // Ok, pointer to usize conversion
+ let _: Ty<usize> = transmute(value::<&Ty2<u32, i32>>());
+ // Ok, pointer to usize conversion
+ let _: &Ty2<u32, i32> = transmute(value::<Ty<usize>>());
+
+ // Ok, transmute to byte array
+ let _: Ty<[u8; 8]> = transmute(value::<Ty2<u32, i32>>());
+ // Ok, transmute from byte array
+ let _: Ty2<u32, i32> = transmute(value::<Ty<[u8; 8]>>());
// issue #8417
- let _: Ty2C<Ty2<u32, i32>, ()> = transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
- let _: Ty2<u32, i32> = transmute(value::<Ty2C<Ty2<u32, i32>, ()>>()); // Ok, Ty2 types are the same
-
- let _: &'static mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Ok, Ty2 types are the same
- let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, u32>>()); // Ok, Ty2 types are the same
- let _: *mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Ok, Ty2 types are the same
- let _: Box<Ty2<u32, u32>> = transmute(value::<*mut Ty2<u32, u32>>()); // Ok, Ty2 types are the same
-
- let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Lint, different Ty2 instances
- let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>()); // Lint, different Ty2 instances
-
- let _: *const () = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
- let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const ()>()); // Ok, reverse type erasure
-
- let _: *const c_void = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
- let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const c_void>()); // Ok, reverse type erasure
+ // Ok, Ty2 types are the same
+ let _: Ty2C<Ty2<u32, i32>, ()> = transmute(value::<Ty2<u32, i32>>());
+ // Ok, Ty2 types are the same
+ let _: Ty2<u32, i32> = transmute(value::<Ty2C<Ty2<u32, i32>, ()>>());
+
+ // Ok, Ty2 types are the same
+ let _: &'static mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>());
+ // Ok, Ty2 types are the same
+ let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, u32>>());
+ // Ok, Ty2 types are the same
+ let _: *mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>());
+ // Ok, Ty2 types are the same
+ let _: Box<Ty2<u32, u32>> = transmute(value::<*mut Ty2<u32, u32>>());
+
+ // Lint, different Ty2 instances
+ let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>());
+ //~^ ERROR: transmute from `std::boxed::Box<Ty2<u32, u32>>` to `&mut Ty2<u32, f32>
+ //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou
+ // Lint, different Ty2 instances
+ let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>());
+ //~^ ERROR: transmute from `&mut Ty2<u32, f32>` to `std::boxed::Box<Ty2<u32, u32>>
+ //~| NOTE: two instances of the same generic type (`Ty2`) may have different layou
+
+ // Ok, type erasure
+ let _: *const () = transmute(value::<Ty<&Ty2<u32, f32>>>());
+ // Ok, reverse type erasure
+ let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const ()>());
+
+ // Ok, type erasure
+ let _: *const c_void = transmute(value::<Ty<&Ty2<u32, f32>>>());
+ // Ok, reverse type erasure
+ let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const c_void>());
enum Erase {}
- let _: *const Erase = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
- let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase>()); // Ok, reverse type erasure
+ // Ok, type erasure
+ let _: *const Erase = transmute(value::<Ty<&Ty2<u32, f32>>>());
+ // Ok, reverse type erasure
+ let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase>());
struct Erase2(
[u8; 0],
core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
);
- let _: *const Erase2 = transmute(value::<Ty<&Ty2<u32, f32>>>()); // Ok, type erasure
- let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase2>()); // Ok, reverse type erasure
-
- let _: *const () = transmute(value::<&&[u8]>()); // Ok, type erasure
- let _: &&[u8] = transmute(value::<*const ()>()); // Ok, reverse type erasure
-
- let _: *mut c_void = transmute(value::<&mut &[u8]>()); // Ok, type erasure
- let _: &mut &[u8] = transmute(value::<*mut c_void>()); // Ok, reverse type erasure
-
- let _: [u8; size_of::<&[u8]>()] = transmute(value::<&[u8]>()); // Ok, transmute to byte array
- let _: &[u8] = transmute(value::<[u8; size_of::<&[u8]>()]>()); // Ok, transmute from byte array
-
- let _: [usize; 2] = transmute(value::<&[u8]>()); // Ok, transmute to int array
- let _: &[u8] = transmute(value::<[usize; 2]>()); // Ok, transmute from int array
-
- let _: *const [u8] = transmute(value::<Box<[u8]>>()); // Ok
- let _: Box<[u8]> = transmute(value::<*mut [u8]>()); // Ok
-
- let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>,)>()); // Ok
- let _: (Ty2<u32, u32>,) = transmute(value::<Ty2<u32, u32>>()); // Ok
-
- let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>, ())>()); // Ok
- let _: (Ty2<u32, u32>, ()) = transmute(value::<Ty2<u32, u32>>()); // Ok
-
- let _: Ty2<u32, u32> = transmute(value::<((), Ty2<u32, u32>)>()); // Ok
- let _: ((), Ty2<u32, u32>) = transmute(value::<Ty2<u32, u32>>()); // Ok
-
- let _: (usize, usize) = transmute(value::<&[u8]>()); // Ok
- let _: &[u8] = transmute(value::<(usize, usize)>()); // Ok
+ // Ok, type erasure
+ let _: *const Erase2 = transmute(value::<Ty<&Ty2<u32, f32>>>());
+ // Ok, reverse type erasure
+ let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase2>());
+
+ // Ok, type erasure
+ let _: *const () = transmute(value::<&&[u8]>());
+ // Ok, reverse type erasure
+ let _: &&[u8] = transmute(value::<*const ()>());
+
+ // Ok, type erasure
+ let _: *mut c_void = transmute(value::<&mut &[u8]>());
+ // Ok, reverse type erasure
+ let _: &mut &[u8] = transmute(value::<*mut c_void>());
+
+ // Ok, transmute to byte array
+ let _: [u8; size_of::<&[u8]>()] = transmute(value::<&[u8]>());
+ // Ok, transmute from byte array
+ let _: &[u8] = transmute(value::<[u8; size_of::<&[u8]>()]>());
+
+ // Ok, transmute to int array
+ let _: [usize; 2] = transmute(value::<&[u8]>());
+ // Ok, transmute from int array
+ let _: &[u8] = transmute(value::<[usize; 2]>());
+
+ // Ok
+ let _: *const [u8] = transmute(value::<Box<[u8]>>());
+ // Ok
+ let _: Box<[u8]> = transmute(value::<*mut [u8]>());
+
+ // Ok
+ let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>,)>());
+ // Ok
+ let _: (Ty2<u32, u32>,) = transmute(value::<Ty2<u32, u32>>());
+
+ // Ok
+ let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>, ())>());
+ // Ok
+ let _: (Ty2<u32, u32>, ()) = transmute(value::<Ty2<u32, u32>>());
+
+ // Ok
+ let _: Ty2<u32, u32> = transmute(value::<((), Ty2<u32, u32>)>());
+ // Ok
+ let _: ((), Ty2<u32, u32>) = transmute(value::<Ty2<u32, u32>>());
+
+ // Ok
+ let _: (usize, usize) = transmute(value::<&[u8]>());
+ // Ok
+ let _: &[u8] = transmute(value::<(usize, usize)>());
trait Trait {}
- let _: (isize, isize) = transmute(value::<&dyn Trait>()); // Ok
- let _: &dyn Trait = transmute(value::<(isize, isize)>()); // Ok
-
- let _: MaybeUninit<Ty2<u32, u32>> = transmute(value::<Ty2<u32, u32>>()); // Ok
- let _: Ty2<u32, u32> = transmute(value::<MaybeUninit<Ty2<u32, u32>>>()); // Ok
-
- let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec<u32>>()); // Ok
-
- let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<Ty2<u32, u32>, u32>>()); // Ok
- let _: *const Ty2C<Ty2<u32, u32>, u32> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
- let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<(), Ty2<u32, u32>>>()); // Ok
- let _: *const Ty2C<(), Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Ok
-
- let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err
- let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err
-
- let _: NonNull<u8> = transmute(value::<NonNull<(String, String)>>()); // Ok
- let _: NonNull<(String, String)> = transmute(value::<NonNull<u8>>()); // Ok
+ // Ok
+ let _: (isize, isize) = transmute(value::<&dyn Trait>());
+ let _: &dyn Trait = transmute(value::<(isize, isize)>());
+
+ // Ok
+ let _: MaybeUninit<Ty2<u32, u32>> = transmute(value::<Ty2<u32, u32>>());
+ // Ok
+ let _: Ty2<u32, u32> = transmute(value::<MaybeUninit<Ty2<u32, u32>>>());
+
+ // Ok
+ let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec<u32>>());
+
+ // Ok
+ let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<Ty2<u32, u32>, u32>>());
+ // Ok
+ let _: *const Ty2C<Ty2<u32, u32>, u32> = transmute(value::<*const Ty2<u32, u32>>());
+ // Ok
+ let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<(), Ty2<u32, u32>>>());
+ // Ok
+ let _: *const Ty2C<(), Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>());
+
+ // Err
+ let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>());
+ //~^ ERROR: transmute into `*const Ty2<u32, u32>` which has an undefined layout
+ //~| NOTE: the contained type `Ty2<u32, u32>` has an undefined layout
+ // Err
+ let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>());
+ //~^ ERROR: transmute from `*const Ty2<u32, u32>` which has an undefined layout
+ //~| NOTE: the contained type `Ty2<u32, u32>` has an undefined layout
+
+ // Ok
+ let _: NonNull<u8> = transmute(value::<NonNull<(String, String)>>());
+ // Ok
+ let _: NonNull<(String, String)> = transmute(value::<NonNull<u8>>());
}
}
@@ -129,28 +206,48 @@ fn _with_generics<T: 'static, U: 'static>() {
return;
}
unsafe {
- let _: &u32 = transmute(value::<&T>()); // Ok
- let _: &T = transmute(value::<&u32>()); // Ok
-
- let _: Vec<U> = transmute(value::<Vec<T>>()); // Ok
- let _: Vec<T> = transmute(value::<Vec<U>>()); // Ok
-
- let _: Ty<&u32> = transmute(value::<&T>()); // Ok
- let _: Ty<&T> = transmute(value::<&u32>()); // Ok
-
- let _: Vec<u32> = transmute(value::<Vec<T>>()); // Ok
- let _: Vec<T> = transmute(value::<Vec<u32>>()); // Ok
-
- let _: &Ty2<u32, u32> = transmute(value::<&Ty2<T, U>>()); // Ok
- let _: &Ty2<T, U> = transmute(value::<&Ty2<u32, u32>>()); // Ok
-
- let _: Vec<Vec<u32>> = transmute(value::<Vec<Vec<T>>>()); // Ok
- let _: Vec<Vec<T>> = transmute(value::<Vec<Vec<u32>>>()); // Ok
-
- let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); // Err
- let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>()); // Err
-
- let _: *const u32 = transmute(value::<Box<T>>()); // Ok
- let _: Box<T> = transmute(value::<*const u32>()); // Ok
+ // Ok
+ let _: &u32 = transmute(value::<&T>());
+ // Ok
+ let _: &T = transmute(value::<&u32>());
+
+ // Ok
+ let _: Vec<U> = transmute(value::<Vec<T>>());
+ // Ok
+ let _: Vec<T> = transmute(value::<Vec<U>>());
+
+ // Ok
+ let _: Ty<&u32> = transmute(value::<&T>());
+ // Ok
+ let _: Ty<&T> = transmute(value::<&u32>());
+
+ // Ok
+ let _: Vec<u32> = transmute(value::<Vec<T>>());
+ // Ok
+ let _: Vec<T> = transmute(value::<Vec<u32>>());
+
+ // Ok
+ let _: &Ty2<u32, u32> = transmute(value::<&Ty2<T, U>>());
+ // Ok
+ let _: &Ty2<T, U> = transmute(value::<&Ty2<u32, u32>>());
+
+ // Ok
+ let _: Vec<Vec<u32>> = transmute(value::<Vec<Vec<T>>>());
+ // Ok
+ let _: Vec<Vec<T>> = transmute(value::<Vec<Vec<u32>>>());
+
+ // Err
+ let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>());
+ //~^ ERROR: transmute from `std::vec::Vec<Ty2<U, i32>>` to `std::vec::Vec<Ty2<T, u
+ //~| NOTE: two instances of the same generic type (`Vec`) may have different layou
+ // Err
+ let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>());
+ //~^ ERROR: transmute from `std::vec::Vec<Ty2<T, u32>>` to `std::vec::Vec<Ty2<U, i
+ //~| NOTE: two instances of the same generic type (`Vec`) may have different layou
+
+ // Ok
+ let _: *const u32 = transmute(value::<Box<T>>());
+ // Ok
+ let _: Box<T> = transmute(value::<*const u32>());
}
}
diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
index e50a77329..f87b1ece9 100644
--- a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
+++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
@@ -1,93 +1,94 @@
error: transmute from `Ty2<u32, i32>` which has an undefined layout
- --> $DIR/transmute_undefined_repr.rs:28:33
+ --> $DIR/transmute_undefined_repr.rs:29:33
|
-LL | let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>()); // Lint, Ty2 is unordered
+LL | let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::transmute-undefined-repr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_undefined_repr)]`
error: transmute into `Ty2<u32, i32>` which has an undefined layout
- --> $DIR/transmute_undefined_repr.rs:29:32
+ --> $DIR/transmute_undefined_repr.rs:33:32
|
-LL | let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>()); // Lint, Ty2 is unordered
+LL | let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:34:32
+ --> $DIR/transmute_undefined_repr.rs:42:32
|
-LL | let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>()); // Lint, different Ty2 instances
+LL | let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:35:36
+ --> $DIR/transmute_undefined_repr.rs:46:36
|
-LL | let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>()); // Lint, different Ty2 instances
+LL | let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `Ty<&Ty2<u32, i32>>` to `&Ty2<u32, f32>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:40:33
+ --> $DIR/transmute_undefined_repr.rs:54:33
|
-LL | let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>()); // Lint, different Ty2 instances
+LL | let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `&Ty2<u32, f32>` to `Ty<&Ty2<u32, i32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:41:37
+ --> $DIR/transmute_undefined_repr.rs:58:37
|
-LL | let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>()); // Lint, different Ty2 instances
+LL | let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `std::boxed::Box<Ty2<u32, u32>>` to `&mut Ty2<u32, f32>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:58:45
+ --> $DIR/transmute_undefined_repr.rs:88:45
|
-LL | let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>()); // Lint, different Ty2 instances
+LL | let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute from `&mut Ty2<u32, f32>` to `std::boxed::Box<Ty2<u32, u32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:59:37
+ --> $DIR/transmute_undefined_repr.rs:92:37
|
-LL | let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>()); // Lint, different Ty2 instances
+LL | let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Ty2`) may have different layouts
error: transmute into `*const Ty2<u32, u32>` which has an undefined layout
- --> $DIR/transmute_undefined_repr.rs:119:39
+ --> $DIR/transmute_undefined_repr.rs:189:39
|
-LL | let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>()); // Err
+LL | let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the contained type `Ty2<u32, u32>` has an undefined layout
error: transmute from `*const Ty2<u32, u32>` which has an undefined layout
- --> $DIR/transmute_undefined_repr.rs:120:50
+ --> $DIR/transmute_undefined_repr.rs:193:50
|
-LL | let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>()); // Err
+LL | let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the contained type `Ty2<u32, u32>` has an undefined layout
error: transmute from `std::vec::Vec<Ty2<U, i32>>` to `std::vec::Vec<Ty2<T, u32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:150:35
+ --> $DIR/transmute_undefined_repr.rs:240:35
|
-LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>()); // Err
+LL | let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Vec`) may have different layouts
error: transmute from `std::vec::Vec<Ty2<T, u32>>` to `std::vec::Vec<Ty2<U, i32>>`, both of which have an undefined layout
- --> $DIR/transmute_undefined_repr.rs:151:35
+ --> $DIR/transmute_undefined_repr.rs:244:35
|
-LL | let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>()); // Err
+LL | let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: two instances of the same generic type (`Vec`) may have different layouts
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
index 05aa86c47..08b8e7866 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::transmutes_expressible_as_ptr_casts)]
// These two warnings currently cover the cases transmutes_expressible_as_ptr_casts
// would otherwise be responsible for
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
index 29fa6914c..92eb765e5 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::transmutes_expressible_as_ptr_casts)]
// These two warnings currently cover the cases transmutes_expressible_as_ptr_casts
// would otherwise be responsible for
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr
index 58f5162c7..a7988dc4b 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr
@@ -1,65 +1,68 @@
error: transmute from an integer to a pointer
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:18:39
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:17:39
|
LL | let _ptr_i32_transmute = unsafe { transmute::<usize, *const i32>(usize::MAX) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `usize::MAX as *const i32`
|
= note: `-D clippy::useless-transmute` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]`
error: transmute from a pointer to a pointer
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:22:38
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:21:38
|
LL | let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as *const i8`
|
= note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
error: transmute from a pointer to a pointer
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:28:46
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:27:46
|
LL | let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `slice_ptr as *const [u32]`
error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:34:50
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:33:50
|
LL | let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, usize>(ptr_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as usize`
|
= note: `-D clippy::transmutes-expressible-as-ptr-casts` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmutes_expressible_as_ptr_casts)]`
error: transmute from a reference to a pointer
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:40:41
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:39:41
|
LL | let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; 4]>(array_ref) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array_ref as *const [i32; 4]`
error: transmute from `fn(usize) -> u8` to `*const usize` which could be expressed as a pointer cast instead
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:48:41
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:47:41
|
LL | let _usize_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, *const usize>(foo) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as *const usize`
error: transmute from `fn(usize) -> u8` to `usize` which could be expressed as a pointer cast instead
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:52:49
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:51:49
|
LL | let _usize_from_fn_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, usize>(foo) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize`
error: transmute from `*const u32` to `usize` which could be expressed as a pointer cast instead
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:55:36
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:54:36
|
LL | let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&1u32 as *const u32 as usize`
error: transmute from a reference to a pointer
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:66:14
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:65:14
|
LL | unsafe { transmute::<&[i32; 1], *const u8>(in_param) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8`
error: transmute from `fn()` to `*const u8` which could be expressed as a pointer cast instead
- --> $DIR/transmutes_expressible_as_ptr_casts.rs:84:28
+ --> $DIR/transmutes_expressible_as_ptr_casts.rs:83:28
|
LL | let _x: u8 = unsafe { *std::mem::transmute::<fn(), *const u8>(f) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(f as *const u8)`
diff --git a/src/tools/clippy/tests/ui/transmuting_null.rs b/src/tools/clippy/tests/ui/transmuting_null.rs
index ea3ee8edc..88b8c9965 100644
--- a/src/tools/clippy/tests/ui/transmuting_null.rs
+++ b/src/tools/clippy/tests/ui/transmuting_null.rs
@@ -8,7 +8,10 @@
fn one_liners() {
unsafe {
let _: &u64 = std::mem::transmute(0 as *const u64);
+ //~^ ERROR: transmuting a known null pointer into a reference
+ //~| NOTE: `-D clippy::transmuting-null` implied by `-D warnings`
let _: &u64 = std::mem::transmute(std::ptr::null::<u64>());
+ //~^ ERROR: transmuting a known null pointer into a reference
}
}
@@ -19,6 +22,7 @@ fn transmute_const() {
unsafe {
// Should raise a lint.
let _: &u64 = std::mem::transmute(ZPTR);
+ //~^ ERROR: transmuting a known null pointer into a reference
// Should NOT raise a lint.
let _: &u64 = std::mem::transmute(NOT_ZPTR);
}
diff --git a/src/tools/clippy/tests/ui/transmuting_null.stderr b/src/tools/clippy/tests/ui/transmuting_null.stderr
index 1848fc249..402de38fe 100644
--- a/src/tools/clippy/tests/ui/transmuting_null.stderr
+++ b/src/tools/clippy/tests/ui/transmuting_null.stderr
@@ -5,15 +5,16 @@ LL | let _: &u64 = std::mem::transmute(0 as *const u64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::transmuting-null` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::transmuting_null)]`
error: transmuting a known null pointer into a reference
- --> $DIR/transmuting_null.rs:11:23
+ --> $DIR/transmuting_null.rs:13:23
|
LL | let _: &u64 = std::mem::transmute(std::ptr::null::<u64>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmuting a known null pointer into a reference
- --> $DIR/transmuting_null.rs:21:23
+ --> $DIR/transmuting_null.rs:24:23
|
LL | let _: &u64 = std::mem::transmute(ZPTR);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.fixed b/src/tools/clippy/tests/ui/trim_split_whitespace.fixed
index 7909b319d..6d3daf798 100644
--- a/src/tools/clippy/tests/ui/trim_split_whitespace.fixed
+++ b/src/tools/clippy/tests/ui/trim_split_whitespace.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::trim_split_whitespace)]
#![allow(clippy::let_unit_value)]
diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.rs b/src/tools/clippy/tests/ui/trim_split_whitespace.rs
index 0cf58979f..b49d9e8b3 100644
--- a/src/tools/clippy/tests/ui/trim_split_whitespace.rs
+++ b/src/tools/clippy/tests/ui/trim_split_whitespace.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::trim_split_whitespace)]
#![allow(clippy::let_unit_value)]
diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.stderr b/src/tools/clippy/tests/ui/trim_split_whitespace.stderr
index 5ae7849e2..a1c66eea0 100644
--- a/src/tools/clippy/tests/ui/trim_split_whitespace.stderr
+++ b/src/tools/clippy/tests/ui/trim_split_whitespace.stderr
@@ -1,49 +1,50 @@
error: found call to `str::trim` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:62:23
+ --> $DIR/trim_split_whitespace.rs:61:23
|
LL | let _ = " A B C ".trim().split_whitespace(); // should trigger lint
| ^^^^^^^ help: remove `trim()`
|
= note: `-D clippy::trim-split-whitespace` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::trim_split_whitespace)]`
error: found call to `str::trim_start` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:63:23
+ --> $DIR/trim_split_whitespace.rs:62:23
|
LL | let _ = " A B C ".trim_start().split_whitespace(); // should trigger lint
| ^^^^^^^^^^^^^ help: remove `trim_start()`
error: found call to `str::trim_end` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:64:23
+ --> $DIR/trim_split_whitespace.rs:63:23
|
LL | let _ = " A B C ".trim_end().split_whitespace(); // should trigger lint
| ^^^^^^^^^^^ help: remove `trim_end()`
error: found call to `str::trim` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:67:37
+ --> $DIR/trim_split_whitespace.rs:66:37
|
LL | let _ = (" A B C ").to_string().trim().split_whitespace(); // should trigger lint
| ^^^^^^^ help: remove `trim()`
error: found call to `str::trim_start` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:68:37
+ --> $DIR/trim_split_whitespace.rs:67:37
|
LL | let _ = (" A B C ").to_string().trim_start().split_whitespace(); // should trigger lint
| ^^^^^^^^^^^^^ help: remove `trim_start()`
error: found call to `str::trim_end` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:69:37
+ --> $DIR/trim_split_whitespace.rs:68:37
|
LL | let _ = (" A B C ").to_string().trim_end().split_whitespace(); // should trigger lint
| ^^^^^^^^^^^ help: remove `trim_end()`
error: found call to `str::trim` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:76:15
+ --> $DIR/trim_split_whitespace.rs:75:15
|
LL | let _ = s.trim().split_whitespace(); // should trigger lint
| ^^^^^^^ help: remove `trim()`
error: found call to `str::trim` before `str::split_whitespace`
- --> $DIR/trim_split_whitespace.rs:84:15
+ --> $DIR/trim_split_whitespace.rs:83:15
|
LL | let _ = s.trim().split_whitespace(); // should trigger lint
| ^^^^^^^ help: remove `trim()`
diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
index 86f5cc937..043a7b63a 100644
--- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
+++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
@@ -1,5 +1,5 @@
//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)"
-//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)"
+//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: 8 byte)"
#![deny(clippy::trivially_copy_pass_by_ref)]
#![allow(
clippy::disallowed_names,
@@ -8,7 +8,7 @@
clippy::uninlined_format_args,
clippy::needless_pass_by_ref_mut
)]
-
+//@no-rustfix
#[derive(Copy, Clone)]
struct Foo(u32);
@@ -50,6 +50,8 @@ fn good_return_explicit_lt_struct<'a>(foo: &'a Foo) -> FooRef<'a> {
}
fn bad(x: &u32, y: &Foo, z: &Baz) {}
+//~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
+//~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
impl Foo {
fn good(self, a: &mut u32, b: u32, c: &Bar) {}
@@ -57,10 +59,18 @@ impl Foo {
fn good2(&mut self) {}
fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
+ //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
+ //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
+ //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
fn bad2(x: &u32, y: &Foo, z: &Baz) {}
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
+ //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
+ //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
fn bad_issue7518(self, other: &Self) {}
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if
}
impl AsRef<u32> for Foo {
@@ -73,10 +83,14 @@ impl Bar {
fn good(&self, a: &mut u32, b: u32, c: &Bar) {}
fn bad2(x: &u32, y: &Foo, z: &Baz) {}
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if
+ //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if
+ //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if
}
trait MyTrait {
fn trait_method(&self, _foo: &Foo);
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if
}
pub trait MyTrait2 {
@@ -109,11 +123,13 @@ mod issue5876 {
#[inline(never)]
fn foo_never(x: &i32) {
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
println!("{}", x);
}
#[inline]
fn foo(x: &i32) {
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
println!("{}", x);
}
}
@@ -141,6 +157,7 @@ async fn _async_explicit<'a>(x: &'a u32) -> &'a u32 {
}
fn _unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 {
+ //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by
y
}
diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr
index 2af668537..c9585e519 100644
--- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr
+++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr
@@ -1,4 +1,4 @@
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
--> $DIR/trivially_copy_pass_by_ref.rs:52:11
|
LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
@@ -10,104 +10,104 @@ note: the lint level is defined here
LL | #![deny(clippy::trivially_copy_pass_by_ref)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
--> $DIR/trivially_copy_pass_by_ref.rs:52:20
|
LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
--> $DIR/trivially_copy_pass_by_ref.rs:52:29
|
LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:59:12
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:61:12
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^^ help: consider passing by value instead: `self`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:59:22
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:61:22
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:59:31
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:61:31
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:59:40
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:61:40
|
LL | fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:61:16
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:67:16
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:61:25
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:67:25
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:61:34
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:67:34
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:63:35
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:72:35
|
LL | fn bad_issue7518(self, other: &Self) {}
| ^^^^^ help: consider passing by value instead: `Self`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:75:16
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:85:16
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:75:25
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:85:25
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Foo`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:75:34
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:85:34
|
LL | fn bad2(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `Baz`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:79:34
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:92:34
|
LL | fn trait_method(&self, _foo: &Foo);
| ^^^^ help: consider passing by value instead: `Foo`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:111:21
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:125:21
|
LL | fn foo_never(x: &i32) {
| ^^^^ help: consider passing by value instead: `i32`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:116:15
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:131:15
|
LL | fn foo(x: &i32) {
| ^^^^ help: consider passing by value instead: `i32`
-error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)
- --> $DIR/trivially_copy_pass_by_ref.rs:143:37
+error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
+ --> $DIR/trivially_copy_pass_by_ref.rs:159:37
|
LL | fn _unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 {
| ^^^^^^^ help: consider passing by value instead: `u32`
diff --git a/src/tools/clippy/tests/ui/try_err.fixed b/src/tools/clippy/tests/ui/try_err.fixed
index 930489fab..aae4f8ac4 100644
--- a/src/tools/clippy/tests/ui/try_err.fixed
+++ b/src/tools/clippy/tests/ui/try_err.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![deny(clippy::try_err)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/try_err.rs b/src/tools/clippy/tests/ui/try_err.rs
index f5baf3d8f..927eccf2d 100644
--- a/src/tools/clippy/tests/ui/try_err.rs
+++ b/src/tools/clippy/tests/ui/try_err.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![deny(clippy::try_err)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/try_err.stderr b/src/tools/clippy/tests/ui/try_err.stderr
index 9968b383e..887889ffd 100644
--- a/src/tools/clippy/tests/ui/try_err.stderr
+++ b/src/tools/clippy/tests/ui/try_err.stderr
@@ -1,35 +1,35 @@
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:23:9
+ --> $DIR/try_err.rs:22:9
|
LL | Err(err)?;
| ^^^^^^^^^ help: try: `return Err(err)`
|
note: the lint level is defined here
- --> $DIR/try_err.rs:4:9
+ --> $DIR/try_err.rs:3:9
|
LL | #![deny(clippy::try_err)]
| ^^^^^^^^^^^^^^^
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:33:9
+ --> $DIR/try_err.rs:32:9
|
LL | Err(err)?;
| ^^^^^^^^^ help: try: `return Err(err.into())`
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:53:17
+ --> $DIR/try_err.rs:52:17
|
LL | Err(err)?;
| ^^^^^^^^^ help: try: `return Err(err)`
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:72:17
+ --> $DIR/try_err.rs:71:17
|
LL | Err(err)?;
| ^^^^^^^^^ help: try: `return Err(err.into())`
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:92:23
+ --> $DIR/try_err.rs:91:23
|
LL | Err(_) => Err(1)?,
| ^^^^^^^ help: try: `return Err(1)`
@@ -37,7 +37,7 @@ LL | Err(_) => Err(1)?,
= note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:99:23
+ --> $DIR/try_err.rs:98:23
|
LL | Err(_) => Err(inline!(1))?,
| ^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(1))`
@@ -45,31 +45,31 @@ LL | Err(_) => Err(inline!(1))?,
= note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:126:9
+ --> $DIR/try_err.rs:125:9
|
LL | Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))`
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:133:9
+ --> $DIR/try_err.rs:132:9
|
LL | Err(io::ErrorKind::WriteZero)?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))`
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:135:9
+ --> $DIR/try_err.rs:134:9
|
LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))`
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:143:9
+ --> $DIR/try_err.rs:142:9
|
LL | Err(io::ErrorKind::NotFound)?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))`
error: returning an `Err(_)` with the `?` operator
- --> $DIR/try_err.rs:152:16
+ --> $DIR/try_err.rs:151:16
|
LL | return Err(42)?;
| ^^^^^^^^ help: try: `Err(42)`
diff --git a/src/tools/clippy/tests/ui/tuple_array_conversions.rs b/src/tools/clippy/tests/ui/tuple_array_conversions.rs
index 569415acb..ca79cc104 100644
--- a/src/tools/clippy/tests/ui/tuple_array_conversions.rs
+++ b/src/tools/clippy/tests/ui/tuple_array_conversions.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::no_effect, clippy::useless_vec, unused)]
#![warn(clippy::tuple_array_conversions)]
@@ -82,6 +82,11 @@ fn main() {
[a, c];
let [[a, b], [c, d]] = [[1, 2], [3, 4]];
(a, c);
+ // Array length is not usize (#11144)
+ fn generic_array_length<const N: usize>() {
+ let src = [0; N];
+ let dest: (u8,) = (src[0],);
+ }
}
#[clippy::msrv = "1.70.0"]
diff --git a/src/tools/clippy/tests/ui/tuple_array_conversions.stderr b/src/tools/clippy/tests/ui/tuple_array_conversions.stderr
index 50bdcf29d..f8f5b3e75 100644
--- a/src/tools/clippy/tests/ui/tuple_array_conversions.stderr
+++ b/src/tools/clippy/tests/ui/tuple_array_conversions.stderr
@@ -6,6 +6,7 @@ LL | let x = (x[0], x[1]);
|
= help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed
= note: `-D clippy::tuple-array-conversions` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::tuple_array_conversions)]`
error: it looks like you're trying to convert a tuple to an array
--> $DIR/tuple_array_conversions.rs:11:13
@@ -64,7 +65,7 @@ LL | (src, dest);
= help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed
error: it looks like you're trying to convert an array to a tuple
- --> $DIR/tuple_array_conversions.rs:99:13
+ --> $DIR/tuple_array_conversions.rs:104:13
|
LL | let x = (x[0], x[1]);
| ^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | let x = (x[0], x[1]);
= help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed
error: it looks like you're trying to convert a tuple to an array
- --> $DIR/tuple_array_conversions.rs:100:13
+ --> $DIR/tuple_array_conversions.rs:105:13
|
LL | let x = [x.0, x.1];
| ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/type_complexity.rs b/src/tools/clippy/tests/ui/type_complexity.rs
index 816950110..be28ee2da 100644
--- a/src/tools/clippy/tests/ui/type_complexity.rs
+++ b/src/tools/clippy/tests/ui/type_complexity.rs
@@ -5,29 +5,42 @@
type Alias = Vec<Vec<Box<(u32, u32, u32, u32)>>>; // no warning here
const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
+//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
+//~| NOTE: `-D clippy::type-complexity` implied by `-D warnings`
static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
+//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
struct S {
f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
}
struct Ts(Vec<Vec<Box<(u32, u32, u32, u32)>>>);
+//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
enum E {
Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
}
impl S {
const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
}
trait T {
const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
}
// Should not warn since there is likely no way to simplify this (#1013)
@@ -40,13 +53,16 @@ impl T for () {
}
fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> {
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
vec![]
}
fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
+//~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
fn test3() {
let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
+ //~^ ERROR: very complex type used. Consider factoring parts into `type` definitions
}
#[repr(C)]
diff --git a/src/tools/clippy/tests/ui/type_complexity.stderr b/src/tools/clippy/tests/ui/type_complexity.stderr
index 9da7edb1c..a3cf6ffe9 100644
--- a/src/tools/clippy/tests/ui/type_complexity.stderr
+++ b/src/tools/clippy/tests/ui/type_complexity.stderr
@@ -5,87 +5,88 @@ LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::type-complexity` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:8:12
+ --> $DIR/type_complexity.rs:10:12
|
LL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:11:8
+ --> $DIR/type_complexity.rs:14:8
|
LL | f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:14:11
+ --> $DIR/type_complexity.rs:18:11
|
LL | struct Ts(Vec<Vec<Box<(u32, u32, u32, u32)>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:17:11
+ --> $DIR/type_complexity.rs:22:11
|
LL | Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:18:17
+ --> $DIR/type_complexity.rs:24:17
|
LL | Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:22:14
+ --> $DIR/type_complexity.rs:29:14
|
LL | const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:23:30
+ --> $DIR/type_complexity.rs:31:30
|
LL | fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:27:14
+ --> $DIR/type_complexity.rs:36:14
|
LL | const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:28:14
+ --> $DIR/type_complexity.rs:38:14
|
LL | type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:29:25
+ --> $DIR/type_complexity.rs:40:25
|
LL | fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:30:29
+ --> $DIR/type_complexity.rs:42:29
|
LL | fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:42:15
+ --> $DIR/type_complexity.rs:55:15
|
LL | fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:46:14
+ --> $DIR/type_complexity.rs:60:14
|
LL | fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
- --> $DIR/type_complexity.rs:49:13
+ --> $DIR/type_complexity.rs:64:13
|
LL | let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/type_id_on_box.fixed b/src/tools/clippy/tests/ui/type_id_on_box.fixed
index 615d809c8..538c38b70 100644
--- a/src/tools/clippy/tests/ui/type_id_on_box.fixed
+++ b/src/tools/clippy/tests/ui/type_id_on_box.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::type_id_on_box)]
use std::any::{Any, TypeId};
diff --git a/src/tools/clippy/tests/ui/type_id_on_box.rs b/src/tools/clippy/tests/ui/type_id_on_box.rs
index 74b6c74ae..f224d273b 100644
--- a/src/tools/clippy/tests/ui/type_id_on_box.rs
+++ b/src/tools/clippy/tests/ui/type_id_on_box.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::type_id_on_box)]
use std::any::{Any, TypeId};
diff --git a/src/tools/clippy/tests/ui/type_id_on_box.stderr b/src/tools/clippy/tests/ui/type_id_on_box.stderr
index 1525328c0..844dae158 100644
--- a/src/tools/clippy/tests/ui/type_id_on_box.stderr
+++ b/src/tools/clippy/tests/ui/type_id_on_box.stderr
@@ -1,5 +1,5 @@
error: calling `.type_id()` on a `Box<dyn Any>`
- --> $DIR/type_id_on_box.rs:26:13
+ --> $DIR/type_id_on_box.rs:24:13
|
LL | let _ = any_box.type_id();
| -------^^^^^^^^^^
@@ -9,9 +9,10 @@ LL | let _ = any_box.type_id();
= note: this returns the type id of the literal type `Box<dyn Any>` instead of the type id of the boxed value, which is most likely not what you want
= note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear
= note: `-D clippy::type-id-on-box` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]`
error: calling `.type_id()` on a `Box<dyn Any>`
- --> $DIR/type_id_on_box.rs:30:13
+ --> $DIR/type_id_on_box.rs:28:13
|
LL | let _ = any_box.type_id(); // 2 derefs are needed here to get to the `dyn Any`
| -------^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | let _ = any_box.type_id(); // 2 derefs are needed here to get to the `d
= note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear
error: calling `.type_id()` on a `Box<dyn Any>`
- --> $DIR/type_id_on_box.rs:36:13
+ --> $DIR/type_id_on_box.rs:34:13
|
LL | let _ = b.type_id();
| -^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs b/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs
index 874d97f7a..504a00394 100644
--- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs
@@ -8,6 +8,7 @@ pub fn foo<T>(_t: T)
where
T: Copy,
T: Clone,
+ //~^ ERROR: this type has already been used as a bound predicate
{
unimplemented!();
}
@@ -25,6 +26,7 @@ trait LintBounds
where
Self: Clone,
Self: Copy + Default + Ord,
+ //~^ ERROR: this type has already been used as a bound predicate
Self: Add<Output = Self> + AddAssign + Sub<Output = Self> + SubAssign,
Self: Mul<Output = Self> + MulAssign + Div<Output = Self> + DivAssign,
{
@@ -99,11 +101,13 @@ where
pub fn f<T: ?Sized>()
where
T: Clone,
+ //~^ ERROR: this type has already been used as a bound predicate
{
}
pub fn g<T: Clone>()
where
T: ?Sized,
+ //~^ ERROR: this type has already been used as a bound predicate
{
}
@@ -129,6 +133,7 @@ mod issue8772_pass {
pub fn f<T: ?Sized, U>(arg: usize)
where
T: Trait<Option<usize>, Box<[String]>, bool> + 'static,
+ //~^ ERROR: this type has already been used as a bound predicate
U: Clone + Sync + 'static,
{
}
diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
index 54973c5bd..607cd1fbf 100644
--- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
@@ -12,7 +12,7 @@ LL | #![deny(clippy::type_repetition_in_bounds)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this type has already been used as a bound predicate
- --> $DIR/type_repetition_in_bounds.rs:27:5
+ --> $DIR/type_repetition_in_bounds.rs:28:5
|
LL | Self: Copy + Default + Ord,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL | Self: Copy + Default + Ord,
= help: consider combining the bounds: `Self: Clone + Copy + Default + Ord`
error: this type has already been used as a bound predicate
- --> $DIR/type_repetition_in_bounds.rs:101:5
+ --> $DIR/type_repetition_in_bounds.rs:103:5
|
LL | T: Clone,
| ^^^^^^^^
@@ -28,7 +28,7 @@ LL | T: Clone,
= help: consider combining the bounds: `T: ?Sized + Clone`
error: this type has already been used as a bound predicate
- --> $DIR/type_repetition_in_bounds.rs:106:5
+ --> $DIR/type_repetition_in_bounds.rs:109:5
|
LL | T: ?Sized,
| ^^^^^^^^^
@@ -36,7 +36,7 @@ LL | T: ?Sized,
= help: consider combining the bounds: `T: Clone + ?Sized`
error: this type has already been used as a bound predicate
- --> $DIR/type_repetition_in_bounds.rs:131:9
+ --> $DIR/type_repetition_in_bounds.rs:135:9
|
LL | T: Trait<Option<usize>, Box<[String]>, bool> + 'static,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/types.fixed b/src/tools/clippy/tests/ui/types.fixed
index 4a2616a7a..6f1f55f0e 100644
--- a/src/tools/clippy/tests/ui/types.fixed
+++ b/src/tools/clippy/tests/ui/types.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code, unused_variables)]
#![warn(clippy::cast_lossless)]
diff --git a/src/tools/clippy/tests/ui/types.rs b/src/tools/clippy/tests/ui/types.rs
index 5e0917907..960aee460 100644
--- a/src/tools/clippy/tests/ui/types.rs
+++ b/src/tools/clippy/tests/ui/types.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code, unused_variables)]
#![warn(clippy::cast_lossless)]
diff --git a/src/tools/clippy/tests/ui/types.stderr b/src/tools/clippy/tests/ui/types.stderr
index 59c3e05a1..b253cf338 100644
--- a/src/tools/clippy/tests/ui/types.stderr
+++ b/src/tools/clippy/tests/ui/types.stderr
@@ -1,10 +1,11 @@
error: casting `i32` to `i64` may become silently lossy if you later change the type
- --> $DIR/types.rs:14:22
+ --> $DIR/types.rs:12:22
|
LL | let c_i64: i64 = c as i64;
| ^^^^^^^^ help: try: `i64::from(c)`
|
= note: `-D clippy::cast-lossless` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed
index 757d15921..a0c3330d1 100644
--- a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed
+++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unchecked_duration_subtraction)]
use std::time::{Duration, Instant};
diff --git a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs
index da7faab67..fff1d1372 100644
--- a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs
+++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unchecked_duration_subtraction)]
use std::time::{Duration, Instant};
diff --git a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr
index a2e0aa1d7..2b62bc964 100644
--- a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr
+++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr
@@ -1,25 +1,26 @@
error: unchecked subtraction of a 'Duration' from an 'Instant'
- --> $DIR/unchecked_duration_subtraction.rs:10:13
+ --> $DIR/unchecked_duration_subtraction.rs:9:13
|
LL | let _ = _first - second;
| ^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(second).unwrap()`
|
= note: `-D clippy::unchecked-duration-subtraction` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unchecked_duration_subtraction)]`
error: unchecked subtraction of a 'Duration' from an 'Instant'
- --> $DIR/unchecked_duration_subtraction.rs:12:13
+ --> $DIR/unchecked_duration_subtraction.rs:11:13
|
LL | let _ = Instant::now() - Duration::from_secs(5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(Duration::from_secs(5)).unwrap()`
error: unchecked subtraction of a 'Duration' from an 'Instant'
- --> $DIR/unchecked_duration_subtraction.rs:14:13
+ --> $DIR/unchecked_duration_subtraction.rs:13:13
|
LL | let _ = _first - Duration::from_secs(5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(Duration::from_secs(5)).unwrap()`
error: unchecked subtraction of a 'Duration' from an 'Instant'
- --> $DIR/unchecked_duration_subtraction.rs:16:13
+ --> $DIR/unchecked_duration_subtraction.rs:15:13
|
LL | let _ = Instant::now() - second;
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(second).unwrap()`
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
deleted file mode 100644
index a9cc42954..000000000
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
+++ /dev/null
@@ -1,534 +0,0 @@
-//@aux-build:proc_macro_unsafe.rs:proc-macro
-
-#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
-#![allow(clippy::let_unit_value, clippy::missing_safety_doc)]
-
-extern crate proc_macro_unsafe;
-
-// Valid comments
-
-fn nested_local() {
- let _ = {
- let _ = {
- // SAFETY:
- let _ = unsafe {};
- };
- };
-}
-
-fn deep_nest() {
- let _ = {
- let _ = {
- // SAFETY:
- let _ = unsafe {};
-
- // Safety:
- unsafe {};
-
- let _ = {
- let _ = {
- let _ = {
- let _ = {
- let _ = {
- // Safety:
- let _ = unsafe {};
-
- // SAFETY:
- unsafe {};
- };
- };
- };
-
- // Safety:
- unsafe {};
- };
- };
- };
-
- // Safety:
- unsafe {};
- };
-
- // SAFETY:
- unsafe {};
-}
-
-fn local_tuple_expression() {
- // Safety:
- let _ = (42, unsafe {});
-}
-
-fn line_comment() {
- // Safety:
- unsafe {}
-}
-
-fn line_comment_newlines() {
- // SAFETY:
-
- unsafe {}
-}
-
-fn line_comment_empty() {
- // Safety:
- //
- //
- //
- unsafe {}
-}
-
-fn line_comment_with_extras() {
- // This is a description
- // Safety:
- unsafe {}
-}
-
-fn block_comment() {
- /* Safety: */
- unsafe {}
-}
-
-fn block_comment_newlines() {
- /* SAFETY: */
-
- unsafe {}
-}
-
-fn block_comment_with_extras() {
- /* This is a description
- * SAFETY:
- */
- unsafe {}
-}
-
-fn block_comment_terminator_same_line() {
- /* This is a description
- * Safety: */
- unsafe {}
-}
-
-fn buried_safety() {
- // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
- // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
- // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
- // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
- // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
- // laborum. Safety:
- // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi
- // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio
- // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl
- // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.
- unsafe {}
-}
-
-fn safety_with_prepended_text() {
- // This is a test. safety:
- unsafe {}
-}
-
-fn local_line_comment() {
- // Safety:
- let _ = unsafe {};
-}
-
-fn local_block_comment() {
- /* SAFETY: */
- let _ = unsafe {};
-}
-
-fn comment_array() {
- // Safety:
- let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-}
-
-fn comment_tuple() {
- // sAFETY:
- let _ = (42, unsafe {}, "test", unsafe {});
-}
-
-fn comment_unary() {
- // SAFETY:
- let _ = *unsafe { &42 };
-}
-
-#[allow(clippy::match_single_binding)]
-fn comment_match() {
- // SAFETY:
- let _ = match unsafe {} {
- _ => {},
- };
-}
-
-fn comment_addr_of() {
- // Safety:
- let _ = &unsafe {};
-}
-
-fn comment_repeat() {
- // Safety:
- let _ = [unsafe {}; 5];
-}
-
-fn comment_macro_call() {
- macro_rules! t {
- ($b:expr) => {
- $b
- };
- }
-
- t!(
- // SAFETY:
- unsafe {}
- );
-}
-
-fn comment_macro_def() {
- macro_rules! t {
- () => {
- // Safety:
- unsafe {}
- };
- }
-
- t!();
-}
-
-fn non_ascii_comment() {
- // ॐ᧻໒ SaFeTy: ௵∰
- unsafe {};
-}
-
-fn local_commented_block() {
- let _ =
- // safety:
- unsafe {};
-}
-
-fn local_nest() {
- // safety:
- let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})];
-}
-
-fn in_fn_call(x: *const u32) {
- fn f(x: u32) {}
-
- // Safety: reason
- f(unsafe { *x });
-}
-
-fn multi_in_fn_call(x: *const u32) {
- fn f(x: u32, y: u32) {}
-
- // Safety: reason
- f(unsafe { *x }, unsafe { *x });
-}
-
-fn in_multiline_fn_call(x: *const u32) {
- fn f(x: u32, y: u32) {}
-
- f(
- // Safety: reason
- unsafe { *x },
- 0,
- );
-}
-
-fn in_macro_call(x: *const u32) {
- // Safety: reason
- println!("{}", unsafe { *x });
-}
-
-fn in_multiline_macro_call(x: *const u32) {
- println!(
- "{}",
- // Safety: reason
- unsafe { *x },
- );
-}
-
-fn from_proc_macro() {
- proc_macro_unsafe::unsafe_block!(token);
-}
-
-fn in_closure(x: *const u32) {
- // Safety: reason
- let _ = || unsafe { *x };
-}
-
-// Invalid comments
-
-#[rustfmt::skip]
-fn inline_block_comment() {
- /* Safety: */ unsafe {}
-}
-
-fn no_comment() {
- unsafe {}
-}
-
-fn no_comment_array() {
- let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-}
-
-fn no_comment_tuple() {
- let _ = (42, unsafe {}, "test", unsafe {});
-}
-
-fn no_comment_unary() {
- let _ = *unsafe { &42 };
-}
-
-#[allow(clippy::match_single_binding)]
-fn no_comment_match() {
- let _ = match unsafe {} {
- _ => {},
- };
-}
-
-fn no_comment_addr_of() {
- let _ = &unsafe {};
-}
-
-fn no_comment_repeat() {
- let _ = [unsafe {}; 5];
-}
-
-fn local_no_comment() {
- let _ = unsafe {};
-}
-
-fn no_comment_macro_call() {
- macro_rules! t {
- ($b:expr) => {
- $b
- };
- }
-
- t!(unsafe {});
-}
-
-fn no_comment_macro_def() {
- macro_rules! t {
- () => {
- unsafe {}
- };
- }
-
- t!();
-}
-
-fn trailing_comment() {
- unsafe {} // SAFETY:
-}
-
-fn internal_comment() {
- unsafe {
- // SAFETY:
- }
-}
-
-fn interference() {
- // SAFETY
-
- let _ = 42;
-
- unsafe {};
-}
-
-pub fn print_binary_tree() {
- println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
-}
-
-mod unsafe_impl_smoke_test {
- unsafe trait A {}
-
- // error: no safety comment
- unsafe impl A for () {}
-
- // Safety: ok
- unsafe impl A for (i32) {}
-
- mod sub_mod {
- // error:
- unsafe impl B for (u32) {}
- unsafe trait B {}
- }
-
- #[rustfmt::skip]
- mod sub_mod2 {
- //
- // SAFETY: ok
- //
-
- unsafe impl B for (u32) {}
- unsafe trait B {}
- }
-}
-
-mod unsafe_impl_from_macro {
- unsafe trait T {}
-
- // error
- macro_rules! no_safety_comment {
- ($t:ty) => {
- unsafe impl T for $t {}
- };
- }
-
- // ok
- no_safety_comment!(());
-
- // ok
- macro_rules! with_safety_comment {
- ($t:ty) => {
- // SAFETY:
- unsafe impl T for $t {}
- };
- }
-
- // ok
- with_safety_comment!((i32));
-}
-
-mod unsafe_impl_macro_and_not_macro {
- unsafe trait T {}
-
- // error
- macro_rules! no_safety_comment {
- ($t:ty) => {
- unsafe impl T for $t {}
- };
- }
-
- // ok
- no_safety_comment!(());
-
- // error
- unsafe impl T for (i32) {}
-
- // ok
- no_safety_comment!(u32);
-
- // error
- unsafe impl T for (bool) {}
-}
-
-#[rustfmt::skip]
-mod unsafe_impl_valid_comment {
- unsafe trait SaFety {}
- // SaFety:
- unsafe impl SaFety for () {}
-
- unsafe trait MultiLineComment {}
- // The following impl is safe
- // ...
- // Safety: reason
- unsafe impl MultiLineComment for () {}
-
- unsafe trait NoAscii {}
- // 安全 SAFETY: 以下のコードは安全です
- unsafe impl NoAscii for () {}
-
- unsafe trait InlineAndPrecedingComment {}
- // SAFETY:
- /* comment */ unsafe impl InlineAndPrecedingComment for () {}
-
- unsafe trait BuriedSafety {}
- // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
- // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
- // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
- // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
- // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
- // laborum. Safety:
- // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi
- // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio
- // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl
- // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.
- unsafe impl BuriedSafety for () {}
-
- unsafe trait MultiLineBlockComment {}
- /* This is a description
- * Safety: */
- unsafe impl MultiLineBlockComment for () {}
-}
-
-#[rustfmt::skip]
-mod unsafe_impl_invalid_comment {
- unsafe trait NoComment {}
-
- unsafe impl NoComment for () {}
-
- unsafe trait InlineComment {}
-
- /* SAFETY: */ unsafe impl InlineComment for () {}
-
- unsafe trait TrailingComment {}
-
- unsafe impl TrailingComment for () {} // SAFETY:
-
- unsafe trait Interference {}
- // SAFETY:
- const BIG_NUMBER: i32 = 1000000;
- unsafe impl Interference for () {}
-}
-
-unsafe trait ImplInFn {}
-
-fn impl_in_fn() {
- // error
- unsafe impl ImplInFn for () {}
-
- // SAFETY: ok
- unsafe impl ImplInFn for (i32) {}
-}
-
-unsafe trait CrateRoot {}
-
-// error
-unsafe impl CrateRoot for () {}
-
-// SAFETY: ok
-unsafe impl CrateRoot for (i32) {}
-
-fn issue_9142() {
- // SAFETY: ok
- let _ =
- // we need this comment to avoid rustfmt putting
- // it all on one line
- unsafe {};
-
- // SAFETY: this is more than one level away, so it should warn
- let _ = {
- if unsafe { true } {
- todo!();
- } else {
- let bar = unsafe {};
- todo!();
- bar
- }
- };
-}
-
-pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 {
- 1
-}
-
-pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 {
- 2
-}
-
-fn issue_10832() {
- // Safety: A safety comment. But it will warn anyways
- let _some_variable_with_a_very_long_name_to_break_the_line =
- unsafe { a_function_with_a_very_long_name_to_break_the_line() };
-
- // Safety: Another safety comment. But it will warn anyways
- const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
- unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
-
- // Safety: Yet another safety comment. But it will warn anyways
- static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
- unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
-}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/unicode.fixed b/src/tools/clippy/tests/ui/unicode.fixed
index 032040c48..f9efb4ec3 100644
--- a/src/tools/clippy/tests/ui/unicode.fixed
+++ b/src/tools/clippy/tests/ui/unicode.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#[warn(clippy::invisible_characters)]
diff --git a/src/tools/clippy/tests/ui/unicode.rs b/src/tools/clippy/tests/ui/unicode.rs
index dd215bc60..bba613e22 100644
--- a/src/tools/clippy/tests/ui/unicode.rs
+++ b/src/tools/clippy/tests/ui/unicode.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![allow(dead_code)]
#[warn(clippy::invisible_characters)]
diff --git a/src/tools/clippy/tests/ui/unicode.stderr b/src/tools/clippy/tests/ui/unicode.stderr
index 21cc22a77..0b6e20664 100644
--- a/src/tools/clippy/tests/ui/unicode.stderr
+++ b/src/tools/clippy/tests/ui/unicode.stderr
@@ -1,63 +1,65 @@
error: invisible character detected
- --> $DIR/unicode.rs:6:12
+ --> $DIR/unicode.rs:5:12
|
LL | print!("Here >​< is a ZWS, and ​another");
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{200B}< is a ZWS, and /u{200B}another"`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{200B}< is a ZWS, and \u{200B}another"`
|
= note: `-D clippy::invisible-characters` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::invisible_characters)]`
error: invisible character detected
- --> $DIR/unicode.rs:8:12
+ --> $DIR/unicode.rs:7:12
|
LL | print!("Here >­< is a SHY, and ­another");
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{AD}< is a SHY, and /u{AD}another"`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{AD}< is a SHY, and \u{AD}another"`
error: invisible character detected
- --> $DIR/unicode.rs:10:12
+ --> $DIR/unicode.rs:9:12
|
LL | print!("Here >⁠< is a WJ, and ⁠another");
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{2060}< is a WJ, and /u{2060}another"`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{2060}< is a WJ, and \u{2060}another"`
error: non-NFC Unicode sequence detected
- --> $DIR/unicode.rs:16:12
+ --> $DIR/unicode.rs:15:12
|
LL | print!("̀àh?");
| ^^^^^ help: consider replacing the string with: `"̀àh?"`
|
= note: `-D clippy::unicode-not-nfc` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unicode_not_nfc)]`
error: literal non-ASCII character detected
- --> $DIR/unicode.rs:24:16
+ --> $DIR/unicode.rs:23:16
|
LL | print!("Üben!");
- | ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"`
+ | ^^^^^^^ help: consider replacing the string with: `"\u{dc}ben!"`
|
note: the lint level is defined here
- --> $DIR/unicode.rs:21:13
+ --> $DIR/unicode.rs:20:13
|
LL | #![deny(clippy::non_ascii_literal)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: literal non-ASCII character detected
- --> $DIR/unicode.rs:30:36
+ --> $DIR/unicode.rs:29:36
|
LL | const _EMPTY_BLOCK: char = '▱';
- | ^^^ help: consider replacing the string with: `'/u{25b1}'`
+ | ^^^ help: consider replacing the string with: `'\u{25b1}'`
error: literal non-ASCII character detected
- --> $DIR/unicode.rs:31:35
+ --> $DIR/unicode.rs:30:35
|
LL | const _FULL_BLOCK: char = '▰';
- | ^^^ help: consider replacing the string with: `'/u{25b0}'`
+ | ^^^ help: consider replacing the string with: `'\u{25b0}'`
error: literal non-ASCII character detected
- --> $DIR/unicode.rs:51:21
+ --> $DIR/unicode.rs:50:21
|
LL | let _ = "悲しいかな、ここに日本語を書くことはできない。";
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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}"`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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}"`
|
note: the lint level is defined here
- --> $DIR/unicode.rs:40:17
+ --> $DIR/unicode.rs:39:17
|
LL | #![deny(clippy::non_ascii_literal)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/uninit.rs b/src/tools/clippy/tests/ui/uninit.rs
index 2d567630e..10a4c22b5 100644
--- a/src/tools/clippy/tests/ui/uninit.rs
+++ b/src/tools/clippy/tests/ui/uninit.rs
@@ -10,6 +10,8 @@ union MyOwnMaybeUninit {
fn main() {
let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
+ //~^ ERROR: this call for this type may be undefined behavior
+ //~| NOTE: `#[deny(clippy::uninit_assumed_init)]` on by default
// This is OK, because ZSTs do not contain data.
let _: () = unsafe { MaybeUninit::uninit().assume_init() };
@@ -31,6 +33,7 @@ fn main() {
// Was a false negative.
let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
+ //~^ ERROR: this call for this type may be undefined behavior
polymorphic::<()>();
polymorphic_maybe_uninit_array::<10>();
@@ -39,6 +42,7 @@ fn main() {
fn polymorphic<T>() {
// We are conservative around polymorphic types.
let _: T = unsafe { MaybeUninit::uninit().assume_init() };
+ //~^ ERROR: this call for this type may be undefined behavior
}
fn polymorphic_maybe_uninit_array<const N: usize>() {
diff --git a/src/tools/clippy/tests/ui/uninit.stderr b/src/tools/clippy/tests/ui/uninit.stderr
index 248de56da..1cc27ffe7 100644
--- a/src/tools/clippy/tests/ui/uninit.stderr
+++ b/src/tools/clippy/tests/ui/uninit.stderr
@@ -7,13 +7,13 @@ LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
= note: `#[deny(clippy::uninit_assumed_init)]` on by default
error: this call for this type may be undefined behavior
- --> $DIR/uninit.rs:33:29
+ --> $DIR/uninit.rs:35:29
|
LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this call for this type may be undefined behavior
- --> $DIR/uninit.rs:41:29
+ --> $DIR/uninit.rs:44:29
|
LL | let _: T = unsafe { MaybeUninit::uninit().assume_init() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/uninit_vec.rs b/src/tools/clippy/tests/ui/uninit_vec.rs
index 79effc82f..c069b9adf 100644
--- a/src/tools/clippy/tests/ui/uninit_vec.rs
+++ b/src/tools/clippy/tests/ui/uninit_vec.rs
@@ -15,29 +15,34 @@ union MyOwnMaybeUninit {
fn main() {
// with_capacity() -> set_len() should be detected
let mut vec: Vec<u8> = Vec::with_capacity(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial
unsafe {
vec.set_len(200);
}
// reserve() -> set_len() should be detected
vec.reserve(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial
unsafe {
vec.set_len(200);
}
// new() -> set_len() should be detected
let mut vec: Vec<u8> = Vec::new();
+ //~^ ERROR: calling `set_len()` on empty `Vec` creates out-of-bound values
unsafe {
vec.set_len(200);
}
// default() -> set_len() should be detected
let mut vec: Vec<u8> = Default::default();
+ //~^ ERROR: calling `set_len()` on empty `Vec` creates out-of-bound values
unsafe {
vec.set_len(200);
}
let mut vec: Vec<u8> = Vec::default();
+ //~^ ERROR: calling `set_len()` on empty `Vec` creates out-of-bound values
unsafe {
vec.set_len(200);
}
@@ -45,13 +50,16 @@ fn main() {
// test when both calls are enclosed in the same unsafe block
unsafe {
let mut vec: Vec<u8> = Vec::with_capacity(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates unini
vec.set_len(200);
vec.reserve(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates unini
vec.set_len(200);
}
let mut vec: Vec<u8> = Vec::with_capacity(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial
unsafe {
// test the case where there are other statements in the following unsafe block
vec.set_len(200);
@@ -61,11 +69,13 @@ fn main() {
// handle vec stored in the field of a struct
let mut my_vec = MyVec::default();
my_vec.vec.reserve(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial
unsafe {
my_vec.vec.set_len(200);
}
my_vec.vec = Vec::with_capacity(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates uninitial
unsafe {
my_vec.vec.set_len(200);
}
@@ -120,6 +130,7 @@ fn main() {
fn polymorphic<T>() {
// We are conservative around polymorphic types.
let mut vec: Vec<T> = Vec::with_capacity(1000);
+ //~^ ERROR: calling `set_len()` immediately after reserving a buffer creates unini
unsafe {
vec.set_len(10);
}
diff --git a/src/tools/clippy/tests/ui/uninit_vec.stderr b/src/tools/clippy/tests/ui/uninit_vec.stderr
index 9cdf0c95a..d39f05839 100644
--- a/src/tools/clippy/tests/ui/uninit_vec.stderr
+++ b/src/tools/clippy/tests/ui/uninit_vec.stderr
@@ -3,53 +3,54 @@ error: calling `set_len()` immediately after reserving a buffer creates uninitia
|
LL | let mut vec: Vec<u8> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
= note: `-D clippy::uninit-vec` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::uninit_vec)]`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
- --> $DIR/uninit_vec.rs:23:5
+ --> $DIR/uninit_vec.rs:24:5
|
LL | vec.reserve(1000);
| ^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` on empty `Vec` creates out-of-bound values
- --> $DIR/uninit_vec.rs:29:5
+ --> $DIR/uninit_vec.rs:31:5
|
LL | let mut vec: Vec<u8> = Vec::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
error: calling `set_len()` on empty `Vec` creates out-of-bound values
- --> $DIR/uninit_vec.rs:35:5
+ --> $DIR/uninit_vec.rs:38:5
|
LL | let mut vec: Vec<u8> = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
error: calling `set_len()` on empty `Vec` creates out-of-bound values
- --> $DIR/uninit_vec.rs:40:5
+ --> $DIR/uninit_vec.rs:44:5
|
LL | let mut vec: Vec<u8> = Vec::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
- --> $DIR/uninit_vec.rs:54:5
+ --> $DIR/uninit_vec.rs:61:5
|
LL | let mut vec: Vec<u8> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,53 +61,55 @@ LL | vec.set_len(200);
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
- --> $DIR/uninit_vec.rs:63:5
+ --> $DIR/uninit_vec.rs:71:5
|
LL | my_vec.vec.reserve(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | my_vec.vec.set_len(200);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
- --> $DIR/uninit_vec.rs:68:5
+ --> $DIR/uninit_vec.rs:77:5
|
LL | my_vec.vec = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | my_vec.vec.set_len(200);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
- --> $DIR/uninit_vec.rs:47:9
+ --> $DIR/uninit_vec.rs:52:9
|
LL | let mut vec: Vec<u8> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
- --> $DIR/uninit_vec.rs:50:9
+ --> $DIR/uninit_vec.rs:56:9
|
LL | vec.reserve(1000);
| ^^^^^^^^^^^^^^^^^^
+LL |
LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
- --> $DIR/uninit_vec.rs:122:9
+ --> $DIR/uninit_vec.rs:132:9
|
LL | let mut vec: Vec<T> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL | unsafe {
+...
LL | vec.set_len(10);
| ^^^^^^^^^^^^^^^
|
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.fixed b/src/tools/clippy/tests/ui/uninlined_format_args.fixed
index a042731a9..3f5b0e52e 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.fixed
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.fixed
@@ -1,5 +1,5 @@
-//@aux-build:proc_macros.rs:proc-macro
-//@run-rustfix
+//@aux-build:proc_macros.rs
+
#![warn(clippy::uninlined_format_args)]
#![allow(named_arguments_used_positionally, unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.rs b/src/tools/clippy/tests/ui/uninlined_format_args.rs
index d830b74d6..b311aa491 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.rs
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.rs
@@ -1,5 +1,5 @@
-//@aux-build:proc_macros.rs:proc-macro
-//@run-rustfix
+//@aux-build:proc_macros.rs
+
#![warn(clippy::uninlined_format_args)]
#![allow(named_arguments_used_positionally, unused)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.stderr b/src/tools/clippy/tests/ui/uninlined_format_args.stderr
index 44ca61f00..829d646b8 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.stderr
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.stderr
@@ -5,6 +5,7 @@ LL | println!("val='{}'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`
help: change this to
|
LL - println!("val='{}'", local_i32);
@@ -216,24 +217,24 @@ LL + println!("{val}");
error: variables can be used directly in the `format!` string
--> $DIR/uninlined_format_args.rs:72:5
|
-LL | println!("val='{/t }'", local_i32);
+LL | println!("val='{\t }'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: change this to
|
-LL - println!("val='{/t }'", local_i32);
+LL - println!("val='{\t }'", local_i32);
LL + println!("val='{local_i32}'");
|
error: variables can be used directly in the `format!` string
--> $DIR/uninlined_format_args.rs:73:5
|
-LL | println!("val='{/n }'", local_i32);
+LL | println!("val='{\n }'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: change this to
|
-LL - println!("val='{/n }'", local_i32);
+LL - println!("val='{\n }'", local_i32);
LL + println!("val='{local_i32}'");
|
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed
index 559050b3d..f0d570efd 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed
+++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed
@@ -1,7 +1,6 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
#![warn(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr
index 2c8061259..221efeb50 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.stderr
@@ -1,10 +1,11 @@
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args_panic.rs:11:5
+ --> $DIR/uninlined_format_args_panic.rs:10:5
|
LL | println!("val='{}'", var);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`
help: change this to
|
LL - println!("val='{}'", var);
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed
index 3a753b49c..7c0f28c45 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed
@@ -1,7 +1,6 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
#![warn(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.stderr b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.stderr
index fc7b12508..ec1e3a1cf 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.stderr
@@ -1,10 +1,11 @@
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args_panic.rs:11:5
+ --> $DIR/uninlined_format_args_panic.rs:10:5
|
LL | println!("val='{}'", var);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`
help: change this to
|
LL - println!("val='{}'", var);
@@ -12,7 +13,7 @@ LL + println!("val='{var}'");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args_panic.rs:14:9
+ --> $DIR/uninlined_format_args_panic.rs:13:9
|
LL | panic!("p1 {}", var);
| ^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + panic!("p1 {var}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args_panic.rs:17:9
+ --> $DIR/uninlined_format_args_panic.rs:16:9
|
LL | panic!("p2 {0}", var);
| ^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL + panic!("p2 {var}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args_panic.rs:20:9
+ --> $DIR/uninlined_format_args_panic.rs:19:9
|
LL | panic!("p3 {var}", var = var);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL + panic!("p3 {var}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args_panic.rs:30:5
+ --> $DIR/uninlined_format_args_panic.rs:29:5
|
LL | assert!(var == 1, "p5 {}", var);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL + assert!(var == 1, "p5 {var}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args_panic.rs:31:5
+ --> $DIR/uninlined_format_args_panic.rs:30:5
|
LL | debug_assert!(var == 1, "p6 {}", var);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs b/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs
index 83fbb9afd..fa594d9a9 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs
+++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs
@@ -1,7 +1,6 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
#![warn(clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs
index fded8db5d..2e1390621 100644
--- a/src/tools/clippy/tests/ui/unit_arg.rs
+++ b/src/tools/clippy/tests/ui/unit_arg.rs
@@ -1,4 +1,5 @@
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
+//@no-rustfix: overlapping suggestions
#![warn(clippy::unit_arg)]
#![allow(unused_must_use, unused_variables)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr
index 74d4d2f40..8656c8fdd 100644
--- a/src/tools/clippy/tests/ui/unit_arg.stderr
+++ b/src/tools/clippy/tests/ui/unit_arg.stderr
@@ -1,5 +1,5 @@
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:62:5
+ --> $DIR/unit_arg.rs:63:5
|
LL | / foo({
LL | | 1;
@@ -7,6 +7,7 @@ LL | | });
| |______^
|
= note: `-D clippy::unit-arg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]`
help: remove the semicolon from the last statement in the block
|
LL | 1
@@ -20,7 +21,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:65:5
+ --> $DIR/unit_arg.rs:66:5
|
LL | foo(foo(1));
| ^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:66:5
+ --> $DIR/unit_arg.rs:67:5
|
LL | / foo({
LL | | foo(1);
@@ -54,7 +55,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:71:5
+ --> $DIR/unit_arg.rs:72:5
|
LL | / b.bar({
LL | | 1;
@@ -74,7 +75,7 @@ LL ~ b.bar(());
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:74:5
+ --> $DIR/unit_arg.rs:75:5
|
LL | taking_multiple_units(foo(0), foo(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +88,7 @@ LL ~ taking_multiple_units((), ());
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:75:5
+ --> $DIR/unit_arg.rs:76:5
|
LL | / taking_multiple_units(foo(0), {
LL | | foo(1);
@@ -110,7 +111,7 @@ LL ~ taking_multiple_units((), ());
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:79:5
+ --> $DIR/unit_arg.rs:80:5
|
LL | / taking_multiple_units(
LL | | {
@@ -146,7 +147,7 @@ LL ~ );
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:90:13
+ --> $DIR/unit_arg.rs:91:13
|
LL | None.or(Some(foo(2)));
| ^^^^^^^^^^^^
@@ -160,7 +161,7 @@ LL ~ });
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:93:5
+ --> $DIR/unit_arg.rs:94:5
|
LL | foo(foo(()));
| ^^^^^^^^^^^^
@@ -172,7 +173,7 @@ LL ~ foo(());
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:130:5
+ --> $DIR/unit_arg.rs:131:5
|
LL | Some(foo(1))
| ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed
index 8c065115a..a947ded7b 100644
--- a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed
+++ b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unit_arg)]
#![allow(unused_must_use, unused_variables)]
#![allow(clippy::no_effect, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs
index af166b56f..058c4f84a 100644
--- a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs
+++ b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unit_arg)]
#![allow(unused_must_use, unused_variables)]
#![allow(clippy::no_effect, clippy::uninlined_format_args)]
diff --git a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr
index c697dfb1e..b207acb59 100644
--- a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr
+++ b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr
@@ -1,5 +1,5 @@
error: passing a unit value to a function
- --> $DIR/unit_arg_empty_blocks.rs:17:5
+ --> $DIR/unit_arg_empty_blocks.rs:16:5
|
LL | foo({});
| ^^^^--^
@@ -7,9 +7,10 @@ LL | foo({});
| help: use a unit literal instead: `()`
|
= note: `-D clippy::unit-arg` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]`
error: passing a unit value to a function
- --> $DIR/unit_arg_empty_blocks.rs:18:5
+ --> $DIR/unit_arg_empty_blocks.rs:17:5
|
LL | foo3({}, 2, 2);
| ^^^^^--^^^^^^^
@@ -17,7 +18,7 @@ LL | foo3({}, 2, 2);
| help: use a unit literal instead: `()`
error: passing unit values to a function
- --> $DIR/unit_arg_empty_blocks.rs:19:5
+ --> $DIR/unit_arg_empty_blocks.rs:18:5
|
LL | taking_two_units({}, foo(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -29,7 +30,7 @@ LL ~ taking_two_units((), ());
|
error: passing unit values to a function
- --> $DIR/unit_arg_empty_blocks.rs:20:5
+ --> $DIR/unit_arg_empty_blocks.rs:19:5
|
LL | taking_three_units({}, foo(0), foo(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unit_cmp.rs b/src/tools/clippy/tests/ui/unit_cmp.rs
index fc75f548a..cea89026d 100644
--- a/src/tools/clippy/tests/ui/unit_cmp.rs
+++ b/src/tools/clippy/tests/ui/unit_cmp.rs
@@ -15,18 +15,22 @@ fn main() {
// this warns
if {
+ //~^ ERROR: ==-comparison of unit values detected. This will always be true
+ //~| NOTE: `-D clippy::unit-cmp` implied by `-D warnings`
true;
} == {
false;
} {}
if {
+ //~^ ERROR: >-comparison of unit values detected. This will always be false
true;
} > {
false;
} {}
assert_eq!(
+ //~^ ERROR: `assert_eq` of unit values detected. This will always succeed
{
true;
},
@@ -35,6 +39,7 @@ fn main() {
}
);
debug_assert_eq!(
+ //~^ ERROR: `debug_assert_eq` of unit values detected. This will always succeed
{
true;
},
@@ -44,6 +49,7 @@ fn main() {
);
assert_ne!(
+ //~^ ERROR: `assert_ne` of unit values detected. This will always fail
{
true;
},
@@ -52,6 +58,7 @@ fn main() {
}
);
debug_assert_ne!(
+ //~^ ERROR: `debug_assert_ne` of unit values detected. This will always fail
{
true;
},
diff --git a/src/tools/clippy/tests/ui/unit_cmp.stderr b/src/tools/clippy/tests/ui/unit_cmp.stderr
index 79c890d64..17355e237 100644
--- a/src/tools/clippy/tests/ui/unit_cmp.stderr
+++ b/src/tools/clippy/tests/ui/unit_cmp.stderr
@@ -3,6 +3,8 @@ error: ==-comparison of unit values detected. This will always be true
|
LL | if {
| ________^
+LL | |
+LL | |
LL | | true;
LL | | } == {
LL | | false;
@@ -10,12 +12,14 @@ LL | | } {}
| |_____^
|
= note: `-D clippy::unit-cmp` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unit_cmp)]`
error: >-comparison of unit values detected. This will always be false
- --> $DIR/unit_cmp.rs:23:8
+ --> $DIR/unit_cmp.rs:25:8
|
LL | if {
| ________^
+LL | |
LL | | true;
LL | | } > {
LL | | false;
@@ -23,48 +27,48 @@ LL | | } {}
| |_____^
error: `assert_eq` of unit values detected. This will always succeed
- --> $DIR/unit_cmp.rs:29:5
+ --> $DIR/unit_cmp.rs:32:5
|
LL | / assert_eq!(
+LL | |
LL | | {
LL | | true;
-LL | | },
... |
LL | | }
LL | | );
| |_____^
error: `debug_assert_eq` of unit values detected. This will always succeed
- --> $DIR/unit_cmp.rs:37:5
+ --> $DIR/unit_cmp.rs:41:5
|
LL | / debug_assert_eq!(
+LL | |
LL | | {
LL | | true;
-LL | | },
... |
LL | | }
LL | | );
| |_____^
error: `assert_ne` of unit values detected. This will always fail
- --> $DIR/unit_cmp.rs:46:5
+ --> $DIR/unit_cmp.rs:51:5
|
LL | / assert_ne!(
+LL | |
LL | | {
LL | | true;
-LL | | },
... |
LL | | }
LL | | );
| |_____^
error: `debug_assert_ne` of unit values detected. This will always fail
- --> $DIR/unit_cmp.rs:54:5
+ --> $DIR/unit_cmp.rs:60:5
|
LL | / debug_assert_ne!(
+LL | |
LL | | {
LL | | true;
-LL | | },
... |
LL | | }
LL | | );
diff --git a/src/tools/clippy/tests/ui/unit_hash.fixed b/src/tools/clippy/tests/ui/unit_hash.fixed
new file mode 100644
index 000000000..ed0facf1b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unit_hash.fixed
@@ -0,0 +1,34 @@
+#![warn(clippy::unit_hash)]
+#![allow(clippy::let_unit_value)]
+
+use std::collections::hash_map::DefaultHasher;
+use std::hash::Hash;
+
+enum Foo {
+ Empty,
+ WithValue(u8),
+}
+
+fn do_nothing() {}
+
+fn main() {
+ let mut state = DefaultHasher::new();
+ let my_enum = Foo::Empty;
+
+ match my_enum {
+ Foo::Empty => 0_u8.hash(&mut state),
+ //~^ ERROR: this call to `hash` on the unit type will do nothing
+ //~| NOTE: the implementation of `Hash` for `()` is a no-op
+ Foo::WithValue(x) => x.hash(&mut state),
+ }
+
+ let res = ();
+ 0_u8.hash(&mut state);
+ //~^ ERROR: this call to `hash` on the unit type will do nothing
+ //~| NOTE: the implementation of `Hash` for `()` is a no-op
+
+ #[allow(clippy::unit_arg)]
+ 0_u8.hash(&mut state);
+ //~^ ERROR: this call to `hash` on the unit type will do nothing
+ //~| NOTE: the implementation of `Hash` for `()` is a no-op
+}
diff --git a/src/tools/clippy/tests/ui/unit_hash.rs b/src/tools/clippy/tests/ui/unit_hash.rs
index 43eb54eff..f3636d164 100644
--- a/src/tools/clippy/tests/ui/unit_hash.rs
+++ b/src/tools/clippy/tests/ui/unit_hash.rs
@@ -17,12 +17,18 @@ fn main() {
match my_enum {
Foo::Empty => ().hash(&mut state),
+ //~^ ERROR: this call to `hash` on the unit type will do nothing
+ //~| NOTE: the implementation of `Hash` for `()` is a no-op
Foo::WithValue(x) => x.hash(&mut state),
}
let res = ();
res.hash(&mut state);
+ //~^ ERROR: this call to `hash` on the unit type will do nothing
+ //~| NOTE: the implementation of `Hash` for `()` is a no-op
#[allow(clippy::unit_arg)]
do_nothing().hash(&mut state);
+ //~^ ERROR: this call to `hash` on the unit type will do nothing
+ //~| NOTE: the implementation of `Hash` for `()` is a no-op
}
diff --git a/src/tools/clippy/tests/ui/unit_hash.stderr b/src/tools/clippy/tests/ui/unit_hash.stderr
index 089d1212d..a26fd7344 100644
--- a/src/tools/clippy/tests/ui/unit_hash.stderr
+++ b/src/tools/clippy/tests/ui/unit_hash.stderr
@@ -6,9 +6,10 @@ LL | Foo::Empty => ().hash(&mut state),
|
= note: the implementation of `Hash` for `()` is a no-op
= note: `-D clippy::unit-hash` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unit_hash)]`
error: this call to `hash` on the unit type will do nothing
- --> $DIR/unit_hash.rs:24:5
+ --> $DIR/unit_hash.rs:26:5
|
LL | res.hash(&mut state);
| ^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
@@ -16,7 +17,7 @@ LL | res.hash(&mut state);
= note: the implementation of `Hash` for `()` is a no-op
error: this call to `hash` on the unit type will do nothing
- --> $DIR/unit_hash.rs:27:5
+ --> $DIR/unit_hash.rs:31:5
|
LL | do_nothing().hash(&mut state);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
diff --git a/src/tools/clippy/tests/ui/unit_return_expecting_ord.rs b/src/tools/clippy/tests/ui/unit_return_expecting_ord.rs
index f2a9694f9..59b2f7e35 100644
--- a/src/tools/clippy/tests/ui/unit_return_expecting_ord.rs
+++ b/src/tools/clippy/tests/ui/unit_return_expecting_ord.rs
@@ -17,13 +17,16 @@ fn unit(_i: isize) {}
fn main() {
let mut structs = vec![Struct { field: 2 }, Struct { field: 1 }];
structs.sort_by_key(|s| {
+ //~^ ERROR: this closure returns the unit type which also implements Ord
double(s.field);
});
structs.sort_by_key(|s| double(s.field));
structs.is_sorted_by_key(|s| {
+ //~^ ERROR: this closure returns the unit type which also implements PartialOrd
double(s.field);
});
structs.is_sorted_by_key(|s| {
+ //~^ ERROR: this closure returns the unit type which also implements PartialOrd
if s.field > 0 {
()
} else {
@@ -34,4 +37,5 @@ fn main() {
return double(s.field);
});
structs.sort_by_key(|s| unit(s.field));
+ //~^ ERROR: this closure returns the unit type which also implements Ord
}
diff --git a/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr b/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr
index 3a295af55..9220fb89e 100644
--- a/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr
+++ b/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr
@@ -5,32 +5,33 @@ LL | structs.sort_by_key(|s| {
| ^^^
|
help: probably caused by this trailing semicolon
- --> $DIR/unit_return_expecting_ord.rs:20:24
+ --> $DIR/unit_return_expecting_ord.rs:21:24
|
LL | double(s.field);
| ^
= note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unit_return_expecting_ord)]`
error: this closure returns the unit type which also implements PartialOrd
- --> $DIR/unit_return_expecting_ord.rs:23:30
+ --> $DIR/unit_return_expecting_ord.rs:24:30
|
LL | structs.is_sorted_by_key(|s| {
| ^^^
|
help: probably caused by this trailing semicolon
- --> $DIR/unit_return_expecting_ord.rs:24:24
+ --> $DIR/unit_return_expecting_ord.rs:26:24
|
LL | double(s.field);
| ^
error: this closure returns the unit type which also implements PartialOrd
- --> $DIR/unit_return_expecting_ord.rs:26:30
+ --> $DIR/unit_return_expecting_ord.rs:28:30
|
LL | structs.is_sorted_by_key(|s| {
| ^^^
error: this closure returns the unit type which also implements Ord
- --> $DIR/unit_return_expecting_ord.rs:36:25
+ --> $DIR/unit_return_expecting_ord.rs:39:25
|
LL | structs.sort_by_key(|s| unit(s.field));
| ^^^
diff --git a/src/tools/clippy/tests/ui/unknown_attribute.rs b/src/tools/clippy/tests/ui/unknown_attribute.rs
index e993e63f8..932f284d5 100644
--- a/src/tools/clippy/tests/ui/unknown_attribute.rs
+++ b/src/tools/clippy/tests/ui/unknown_attribute.rs
@@ -1,3 +1,4 @@
#[clippy::unknown]
+//~^ ERROR: usage of unknown attribute
#[clippy::cognitive_complexity = "1"]
fn main() {}
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
index debc7e152..cba32ce6b 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::pedantic)]
// Should suggest lowercase
#![allow(clippy::all)]
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.rs b/src/tools/clippy/tests/ui/unknown_clippy_lints.rs
index 16140fd10..c15d54197 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.rs
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::pedantic)]
// Should suggest lowercase
#![allow(clippy::All)]
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
index 880673eef..ee82db31c 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
@@ -1,49 +1,50 @@
error: unknown lint: `clippy::All`
- --> $DIR/unknown_clippy_lints.rs:5:10
+ --> $DIR/unknown_clippy_lints.rs:3:10
|
LL | #![allow(clippy::All)]
| ^^^^^^^^^^^ help: did you mean: `clippy::all`
|
= note: `-D unknown-lints` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(unknown_lints)]`
error: unknown lint: `clippy::CMP_OWNED`
- --> $DIR/unknown_clippy_lints.rs:6:9
+ --> $DIR/unknown_clippy_lints.rs:4:9
|
LL | #![warn(clippy::CMP_OWNED)]
| ^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::cmp_owned`
error: unknown lint: `clippy::if_not_els`
- --> $DIR/unknown_clippy_lints.rs:9:8
+ --> $DIR/unknown_clippy_lints.rs:7:8
|
LL | #[warn(clippy::if_not_els)]
| ^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::if_not_else`
error: unknown lint: `clippy::UNNecsaRy_cAst`
- --> $DIR/unknown_clippy_lints.rs:10:8
+ --> $DIR/unknown_clippy_lints.rs:8:8
|
LL | #[warn(clippy::UNNecsaRy_cAst)]
| ^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unnecessary_cast`
error: unknown lint: `clippy::useles_transute`
- --> $DIR/unknown_clippy_lints.rs:11:8
+ --> $DIR/unknown_clippy_lints.rs:9:8
|
LL | #[warn(clippy::useles_transute)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::useless_transmute`
error: unknown lint: `clippy::dead_cod`
- --> $DIR/unknown_clippy_lints.rs:13:8
+ --> $DIR/unknown_clippy_lints.rs:11:8
|
LL | #[warn(clippy::dead_cod)]
| ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op`
error: unknown lint: `clippy::unused_colle`
- --> $DIR/unknown_clippy_lints.rs:15:8
+ --> $DIR/unknown_clippy_lints.rs:13:8
|
LL | #[warn(clippy::unused_colle)]
| ^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unused_self`
error: unknown lint: `clippy::const_static_lifetim`
- --> $DIR/unknown_clippy_lints.rs:17:8
+ --> $DIR/unknown_clippy_lints.rs:15:8
|
LL | #[warn(clippy::const_static_lifetim)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes`
diff --git a/src/tools/clippy/tests/ui/unnecessary_box_returns.rs b/src/tools/clippy/tests/ui/unnecessary_box_returns.rs
index ce7cc2e97..bcdaca33b 100644
--- a/src/tools/clippy/tests/ui/unnecessary_box_returns.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_box_returns.rs
@@ -1,8 +1,9 @@
#![warn(clippy::unnecessary_box_returns)]
-
+//@no-rustfix
trait Bar {
// lint
fn baz(&self) -> Box<usize>;
+ //~^ ERROR: boxed return of the sized type `usize`
}
pub struct Foo {}
@@ -16,6 +17,7 @@ impl Bar for Foo {
impl Foo {
fn baz(&self) -> Box<usize> {
+ //~^ ERROR: boxed return of the sized type `usize`
// lint
Box::new(13)
}
@@ -23,11 +25,13 @@ impl Foo {
// lint
fn bxed_usize() -> Box<usize> {
+ //~^ ERROR: boxed return of the sized type `usize`
Box::new(5)
}
// lint
fn _bxed_foo() -> Box<Foo> {
+ //~^ ERROR: boxed return of the sized type `Foo`
Box::new(Foo {})
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_box_returns.stderr b/src/tools/clippy/tests/ui/unnecessary_box_returns.stderr
index b17512c10..944e911fa 100644
--- a/src/tools/clippy/tests/ui/unnecessary_box_returns.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_box_returns.stderr
@@ -6,9 +6,10 @@ LL | fn baz(&self) -> Box<usize>;
|
= help: changing this also requires a change to the return expressions in this function
= note: `-D clippy::unnecessary-box-returns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]`
error: boxed return of the sized type `usize`
- --> $DIR/unnecessary_box_returns.rs:18:22
+ --> $DIR/unnecessary_box_returns.rs:19:22
|
LL | fn baz(&self) -> Box<usize> {
| ^^^^^^^^^^ help: try: `usize`
@@ -16,7 +17,7 @@ LL | fn baz(&self) -> Box<usize> {
= help: changing this also requires a change to the return expressions in this function
error: boxed return of the sized type `usize`
- --> $DIR/unnecessary_box_returns.rs:25:20
+ --> $DIR/unnecessary_box_returns.rs:27:20
|
LL | fn bxed_usize() -> Box<usize> {
| ^^^^^^^^^^ help: try: `usize`
@@ -24,7 +25,7 @@ LL | fn bxed_usize() -> Box<usize> {
= help: changing this also requires a change to the return expressions in this function
error: boxed return of the sized type `Foo`
- --> $DIR/unnecessary_box_returns.rs:30:19
+ --> $DIR/unnecessary_box_returns.rs:33:19
|
LL | fn _bxed_foo() -> Box<Foo> {
| ^^^^^^^^ help: try: `Foo`
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.fixed b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
index 2bf02f134..18dd53bf2 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:extern_fake_libc.rs
#![warn(clippy::unnecessary_cast)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs
index 25b6b0f9b..fcdd4c60c 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:extern_fake_libc.rs
#![warn(clippy::unnecessary_cast)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.stderr b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
index 19411a01b..d4786f66e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
@@ -1,241 +1,242 @@
error: casting raw pointers to the same type and constness is unnecessary (`*const T` -> `*const T`)
- --> $DIR/unnecessary_cast.rs:19:5
+ --> $DIR/unnecessary_cast.rs:18:5
|
LL | ptr as *const T
| ^^^^^^^^^^^^^^^ help: try: `ptr`
|
= note: `-D clippy::unnecessary-cast` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:54:5
+ --> $DIR/unnecessary_cast.rs:53:5
|
LL | 1i32 as i32;
| ^^^^^^^^^^^ help: try: `1_i32`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:55:5
+ --> $DIR/unnecessary_cast.rs:54:5
|
LL | 1f32 as f32;
| ^^^^^^^^^^^ help: try: `1_f32`
error: casting to the same type is unnecessary (`bool` -> `bool`)
- --> $DIR/unnecessary_cast.rs:56:5
+ --> $DIR/unnecessary_cast.rs:55:5
|
LL | false as bool;
| ^^^^^^^^^^^^^ help: try: `false`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:59:5
+ --> $DIR/unnecessary_cast.rs:58:5
|
LL | -1_i32 as i32;
| ^^^^^^^^^^^^^ help: try: `-1_i32`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:60:5
+ --> $DIR/unnecessary_cast.rs:59:5
|
LL | - 1_i32 as i32;
| ^^^^^^^^^^^^^^ help: try: `- 1_i32`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:61:5
+ --> $DIR/unnecessary_cast.rs:60:5
|
LL | -1f32 as f32;
| ^^^^^^^^^^^^ help: try: `-1_f32`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:62:5
+ --> $DIR/unnecessary_cast.rs:61:5
|
LL | 1_i32 as i32;
| ^^^^^^^^^^^^ help: try: `1_i32`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:63:5
+ --> $DIR/unnecessary_cast.rs:62:5
|
LL | 1_f32 as f32;
| ^^^^^^^^^^^^ help: try: `1_f32`
error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`)
- --> $DIR/unnecessary_cast.rs:65:22
+ --> $DIR/unnecessary_cast.rs:64:22
|
LL | let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()`
error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`)
- --> $DIR/unnecessary_cast.rs:67:5
+ --> $DIR/unnecessary_cast.rs:66:5
|
LL | [1u8, 2].as_ptr() as *const u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()`
error: casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`)
- --> $DIR/unnecessary_cast.rs:69:5
+ --> $DIR/unnecessary_cast.rs:68:5
|
LL | [1u8, 2].as_mut_ptr() as *mut u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_mut_ptr()`
error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`)
- --> $DIR/unnecessary_cast.rs:80:5
+ --> $DIR/unnecessary_cast.rs:79:5
|
LL | owo::<u32>([1u32].as_ptr()) as *const u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `owo::<u32>([1u32].as_ptr())`
error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`)
- --> $DIR/unnecessary_cast.rs:81:5
+ --> $DIR/unnecessary_cast.rs:80:5
|
LL | uwu::<u32, u8>([1u32].as_ptr()) as *const u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::<u32, u8>([1u32].as_ptr())`
error: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`)
- --> $DIR/unnecessary_cast.rs:83:5
+ --> $DIR/unnecessary_cast.rs:82:5
|
LL | uwu::<u32, u32>([1u32].as_ptr()) as *const u32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::<u32, u32>([1u32].as_ptr())`
error: casting to the same type is unnecessary (`u32` -> `u32`)
- --> $DIR/unnecessary_cast.rs:118:5
+ --> $DIR/unnecessary_cast.rs:117:5
|
LL | aaa() as u32;
| ^^^^^^^^^^^^ help: try: `aaa()`
error: casting to the same type is unnecessary (`u32` -> `u32`)
- --> $DIR/unnecessary_cast.rs:120:5
+ --> $DIR/unnecessary_cast.rs:119:5
|
LL | aaa() as u32;
| ^^^^^^^^^^^^ help: try: `aaa()`
error: casting integer literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:156:9
+ --> $DIR/unnecessary_cast.rs:155:9
|
LL | 100 as f32;
| ^^^^^^^^^^ help: try: `100_f32`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:157:9
+ --> $DIR/unnecessary_cast.rs:156:9
|
LL | 100 as f64;
| ^^^^^^^^^^ help: try: `100_f64`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:158:9
+ --> $DIR/unnecessary_cast.rs:157:9
|
LL | 100_i32 as f64;
| ^^^^^^^^^^^^^^ help: try: `100_f64`
error: casting integer literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:159:17
+ --> $DIR/unnecessary_cast.rs:158:17
|
LL | let _ = -100 as f32;
| ^^^^^^^^^^^ help: try: `-100_f32`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:160:17
+ --> $DIR/unnecessary_cast.rs:159:17
|
LL | let _ = -100 as f64;
| ^^^^^^^^^^^ help: try: `-100_f64`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:161:17
+ --> $DIR/unnecessary_cast.rs:160:17
|
LL | let _ = -100_i32 as f64;
| ^^^^^^^^^^^^^^^ help: try: `-100_f64`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:162:9
+ --> $DIR/unnecessary_cast.rs:161:9
|
LL | 100. as f32;
| ^^^^^^^^^^^ help: try: `100_f32`
error: casting float literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:163:9
+ --> $DIR/unnecessary_cast.rs:162:9
|
LL | 100. as f64;
| ^^^^^^^^^^^ help: try: `100_f64`
error: casting integer literal to `u32` is unnecessary
- --> $DIR/unnecessary_cast.rs:175:9
+ --> $DIR/unnecessary_cast.rs:174:9
|
LL | 1 as u32;
| ^^^^^^^^ help: try: `1_u32`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:176:9
+ --> $DIR/unnecessary_cast.rs:175:9
|
LL | 0x10 as i32;
| ^^^^^^^^^^^ help: try: `0x10_i32`
error: casting integer literal to `usize` is unnecessary
- --> $DIR/unnecessary_cast.rs:177:9
+ --> $DIR/unnecessary_cast.rs:176:9
|
LL | 0b10 as usize;
| ^^^^^^^^^^^^^ help: try: `0b10_usize`
error: casting integer literal to `u16` is unnecessary
- --> $DIR/unnecessary_cast.rs:178:9
+ --> $DIR/unnecessary_cast.rs:177:9
|
LL | 0o73 as u16;
| ^^^^^^^^^^^ help: try: `0o73_u16`
error: casting integer literal to `u32` is unnecessary
- --> $DIR/unnecessary_cast.rs:179:9
+ --> $DIR/unnecessary_cast.rs:178:9
|
LL | 1_000_000_000 as u32;
| ^^^^^^^^^^^^^^^^^^^^ help: try: `1_000_000_000_u32`
error: casting float literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:181:9
+ --> $DIR/unnecessary_cast.rs:180:9
|
LL | 1.0 as f64;
| ^^^^^^^^^^ help: try: `1.0_f64`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:182:9
+ --> $DIR/unnecessary_cast.rs:181:9
|
LL | 0.5 as f32;
| ^^^^^^^^^^ help: try: `0.5_f32`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:186:17
+ --> $DIR/unnecessary_cast.rs:185:17
|
LL | let _ = -1 as i32;
| ^^^^^^^^^ help: try: `-1_i32`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:187:17
+ --> $DIR/unnecessary_cast.rs:186:17
|
LL | let _ = -1.0 as f32;
| ^^^^^^^^^^^ help: try: `-1.0_f32`
error: casting to the same type is unnecessary (`i32` -> `i32`)
- --> $DIR/unnecessary_cast.rs:193:18
+ --> $DIR/unnecessary_cast.rs:192:18
|
LL | let _ = &(x as i32);
| ^^^^^^^^^^ help: try: `{ x }`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:199:22
+ --> $DIR/unnecessary_cast.rs:198:22
|
LL | let _: i32 = -(1) as i32;
| ^^^^^^^^^^^ help: try: `-1_i32`
error: casting integer literal to `i64` is unnecessary
- --> $DIR/unnecessary_cast.rs:201:22
+ --> $DIR/unnecessary_cast.rs:200:22
|
LL | let _: i64 = -(1) as i64;
| ^^^^^^^^^^^ help: try: `-1_i64`
error: casting float literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:208:22
+ --> $DIR/unnecessary_cast.rs:207:22
|
LL | let _: f64 = (-8.0 as f64).exp();
| ^^^^^^^^^^^^^ help: try: `(-8.0_f64)`
error: casting float literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:210:23
+ --> $DIR/unnecessary_cast.rs:209:23
|
LL | let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
| ^^^^^^^^^^^^ help: try: `8.0_f64`
error: casting to the same type is unnecessary (`f32` -> `f32`)
- --> $DIR/unnecessary_cast.rs:218:20
+ --> $DIR/unnecessary_cast.rs:217:20
|
LL | let _num = foo() as f32;
| ^^^^^^^^^^^^ help: try: `foo()`
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.rs
index 0e027f604..36adf19c9 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.rs
@@ -1,7 +1,9 @@
#![warn(clippy::unnecessary_cast)]
-
+//@no-rustfix
fn main() {
let _ = std::ptr::null() as *const u8;
+ //~^ ERROR: casting raw pointers to the same type and constness is unnecessary (`*cons
+ //~| NOTE: `-D clippy::unnecessary-cast` implied by `-D warnings`
}
mod issue11113 {
@@ -17,6 +19,7 @@ mod issue11113 {
impl TearOff {
unsafe fn query(&self) {
((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)()
+ //~^ ERROR: casting raw pointers to the same type and constness is unnecessary
}
}
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.stderr
index eecf24568..2d38a2a77 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_unfixable.stderr
@@ -5,9 +5,10 @@ LL | let _ = std::ptr::null() as *const u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::null()`
|
= note: `-D clippy::unnecessary-cast` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`
error: casting raw pointers to the same type and constness is unnecessary (`*mut issue11113::Vtbl` -> `*mut issue11113::Vtbl`)
- --> $DIR/unnecessary_cast_unfixable.rs:19:16
+ --> $DIR/unnecessary_cast_unfixable.rs:21:16
|
LL | ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*(self.object as *mut *mut _)`
diff --git a/src/tools/clippy/tests/ui/unnecessary_clone.rs b/src/tools/clippy/tests/ui/unnecessary_clone.rs
index 7ceed3c75..12ac96aa6 100644
--- a/src/tools/clippy/tests/ui/unnecessary_clone.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_clone.rs
@@ -2,7 +2,7 @@
#![warn(clippy::clone_on_ref_ptr)]
#![allow(unused)]
#![allow(clippy::redundant_clone, clippy::uninlined_format_args, clippy::unnecessary_wraps)]
-
+//@no-rustfix
use std::cell::RefCell;
use std::rc::{self, Rc};
use std::sync::{self, Arc};
@@ -21,25 +21,34 @@ fn clone_on_ref_ptr() {
let arc_weak = Arc::downgrade(&arc);
rc.clone();
+ //~^ ERROR: using `.clone()` on a ref-counted pointer
+ //~| NOTE: `-D clippy::clone-on-ref-ptr` implied by `-D warnings`
Rc::clone(&rc);
arc.clone();
+ //~^ ERROR: using `.clone()` on a ref-counted pointer
Arc::clone(&arc);
rcweak.clone();
+ //~^ ERROR: using `.clone()` on a ref-counted pointer
rc::Weak::clone(&rcweak);
arc_weak.clone();
+ //~^ ERROR: using `.clone()` on a ref-counted pointer
sync::Weak::clone(&arc_weak);
let x = Arc::new(SomeImpl);
let _: Arc<dyn SomeTrait> = x.clone();
+ //~^ ERROR: using `.clone()` on a ref-counted pointer
}
fn clone_on_copy_generic<T: Copy>(t: T) {
t.clone();
+ //~^ ERROR: using `clone` on type `T` which implements the `Copy` trait
+ //~| NOTE: `-D clippy::clone-on-copy` implied by `-D warnings`
Some(t).clone();
+ //~^ ERROR: using `clone` on type `Option<T>` which implements the `Copy` trait
}
mod many_derefs {
@@ -74,6 +83,7 @@ mod many_derefs {
fn go1() {
let a = A;
let _: E = a.clone();
+ //~^ ERROR: using `clone` on type `E` which implements the `Copy` trait
let _: E = *****a;
}
}
@@ -93,5 +103,6 @@ mod issue2076 {
fn func() -> Option<Rc<u8>> {
let rc = Rc::new(42);
Some(try_opt!(Some(rc)).clone())
+ //~^ ERROR: using `.clone()` on a ref-counted pointer
}
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_clone.stderr b/src/tools/clippy/tests/ui/unnecessary_clone.stderr
index 23639f6d4..eab5f0423 100644
--- a/src/tools/clippy/tests/ui/unnecessary_clone.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_clone.stderr
@@ -5,53 +5,55 @@ LL | rc.clone();
| ^^^^^^^^^^ help: try: `Rc::<bool>::clone(&rc)`
|
= note: `-D clippy::clone-on-ref-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::clone_on_ref_ptr)]`
error: using `.clone()` on a ref-counted pointer
- --> $DIR/unnecessary_clone.rs:26:5
+ --> $DIR/unnecessary_clone.rs:28:5
|
LL | arc.clone();
| ^^^^^^^^^^^ help: try: `Arc::<bool>::clone(&arc)`
error: using `.clone()` on a ref-counted pointer
- --> $DIR/unnecessary_clone.rs:29:5
+ --> $DIR/unnecessary_clone.rs:32:5
|
LL | rcweak.clone();
| ^^^^^^^^^^^^^^ help: try: `Weak::<bool>::clone(&rcweak)`
error: using `.clone()` on a ref-counted pointer
- --> $DIR/unnecessary_clone.rs:32:5
+ --> $DIR/unnecessary_clone.rs:36:5
|
LL | arc_weak.clone();
| ^^^^^^^^^^^^^^^^ help: try: `Weak::<bool>::clone(&arc_weak)`
error: using `.clone()` on a ref-counted pointer
- --> $DIR/unnecessary_clone.rs:36:33
+ --> $DIR/unnecessary_clone.rs:41:33
|
LL | let _: Arc<dyn SomeTrait> = x.clone();
| ^^^^^^^^^ help: try: `Arc::<SomeImpl>::clone(&x)`
error: using `clone` on type `T` which implements the `Copy` trait
- --> $DIR/unnecessary_clone.rs:40:5
+ --> $DIR/unnecessary_clone.rs:46:5
|
LL | t.clone();
| ^^^^^^^^^ help: try removing the `clone` call: `t`
|
= note: `-D clippy::clone-on-copy` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::clone_on_copy)]`
error: using `clone` on type `Option<T>` which implements the `Copy` trait
- --> $DIR/unnecessary_clone.rs:42:5
+ --> $DIR/unnecessary_clone.rs:50:5
|
LL | Some(t).clone();
| ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)`
error: using `clone` on type `E` which implements the `Copy` trait
- --> $DIR/unnecessary_clone.rs:76:20
+ --> $DIR/unnecessary_clone.rs:85:20
|
LL | let _: E = a.clone();
| ^^^^^^^^^ help: try dereferencing it: `*****a`
error: using `.clone()` on a ref-counted pointer
- --> $DIR/unnecessary_clone.rs:95:14
+ --> $DIR/unnecessary_clone.rs:105:14
|
LL | Some(try_opt!(Some(rc)).clone())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Rc::<u8>::clone(&try_opt!(Some(rc)))`
diff --git a/src/tools/clippy/tests/ui/unnecessary_filter_map.rs b/src/tools/clippy/tests/ui/unnecessary_filter_map.rs
index 3c8c6ec94..1e0d7d129 100644
--- a/src/tools/clippy/tests/ui/unnecessary_filter_map.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_filter_map.rs
@@ -2,18 +2,23 @@
fn main() {
let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });
+ //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
+ //~| NOTE: `-D clippy::unnecessary-filter-map` implied by `-D warnings`
let _ = (0..4).filter_map(|x| {
+ //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
if x > 1 {
return Some(x);
};
None
});
let _ = (0..4).filter_map(|x| match x {
+ //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
0 | 1 => None,
_ => Some(x),
});
let _ = (0..4).filter_map(|x| Some(x + 1));
+ //~^ ERROR: this `.filter_map` can be written more simply using `.map`
let _ = (0..4).filter_map(i32::checked_abs);
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr b/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr
index 2d5403ce3..0dd65f652 100644
--- a/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr
@@ -5,12 +5,14 @@ LL | let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unnecessary-filter-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]`
error: this `.filter_map` can be written more simply using `.filter`
- --> $DIR/unnecessary_filter_map.rs:5:13
+ --> $DIR/unnecessary_filter_map.rs:7:13
|
LL | let _ = (0..4).filter_map(|x| {
| _____________^
+LL | |
LL | | if x > 1 {
LL | | return Some(x);
LL | | };
@@ -19,23 +21,24 @@ LL | | });
| |______^
error: this `.filter_map` can be written more simply using `.filter`
- --> $DIR/unnecessary_filter_map.rs:11:13
+ --> $DIR/unnecessary_filter_map.rs:14:13
|
LL | let _ = (0..4).filter_map(|x| match x {
| _____________^
+LL | |
LL | | 0 | 1 => None,
LL | | _ => Some(x),
LL | | });
| |______^
error: this `.filter_map` can be written more simply using `.map`
- --> $DIR/unnecessary_filter_map.rs:16:13
+ --> $DIR/unnecessary_filter_map.rs:20:13
|
LL | let _ = (0..4).filter_map(|x| Some(x + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `.filter_map` can be written more simply using `.filter`
- --> $DIR/unnecessary_filter_map.rs:155:14
+ --> $DIR/unnecessary_filter_map.rs:160:14
|
LL | let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_find_map.rs b/src/tools/clippy/tests/ui/unnecessary_find_map.rs
index 2c228fbbc..9972b6809 100644
--- a/src/tools/clippy/tests/ui/unnecessary_find_map.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_find_map.rs
@@ -2,18 +2,23 @@
fn main() {
let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });
+ //~^ ERROR: this `.find_map` can be written more simply using `.find`
+ //~| NOTE: `-D clippy::unnecessary-find-map` implied by `-D warnings`
let _ = (0..4).find_map(|x| {
+ //~^ ERROR: this `.find_map` can be written more simply using `.find`
if x > 1 {
return Some(x);
};
None
});
let _ = (0..4).find_map(|x| match x {
+ //~^ ERROR: this `.find_map` can be written more simply using `.find`
0 | 1 => None,
_ => Some(x),
});
let _ = (0..4).find_map(|x| Some(x + 1));
+ //~^ ERROR: this `.find_map` can be written more simply using `.map(..).next()`
let _ = (0..4).find_map(i32::checked_abs);
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_find_map.stderr b/src/tools/clippy/tests/ui/unnecessary_find_map.stderr
index 3a995b41b..662623fb6 100644
--- a/src/tools/clippy/tests/ui/unnecessary_find_map.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_find_map.stderr
@@ -5,12 +5,14 @@ LL | let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unnecessary-find-map` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]`
error: this `.find_map` can be written more simply using `.find`
- --> $DIR/unnecessary_find_map.rs:5:13
+ --> $DIR/unnecessary_find_map.rs:7:13
|
LL | let _ = (0..4).find_map(|x| {
| _____________^
+LL | |
LL | | if x > 1 {
LL | | return Some(x);
LL | | };
@@ -19,23 +21,24 @@ LL | | });
| |______^
error: this `.find_map` can be written more simply using `.find`
- --> $DIR/unnecessary_find_map.rs:11:13
+ --> $DIR/unnecessary_find_map.rs:14:13
|
LL | let _ = (0..4).find_map(|x| match x {
| _____________^
+LL | |
LL | | 0 | 1 => None,
LL | | _ => Some(x),
LL | | });
| |______^
error: this `.find_map` can be written more simply using `.map(..).next()`
- --> $DIR/unnecessary_find_map.rs:16:13
+ --> $DIR/unnecessary_find_map.rs:20:13
|
LL | let _ = (0..4).find_map(|x| Some(x + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `.find_map` can be written more simply using `.find`
- --> $DIR/unnecessary_find_map.rs:27:14
+ --> $DIR/unnecessary_find_map.rs:32:14
|
LL | let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.fixed b/src/tools/clippy/tests/ui/unnecessary_fold.fixed
index bd1d4a152..c884d26eb 100644
--- a/src/tools/clippy/tests/ui/unnecessary_fold.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_fold.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
/// Calls which should trigger the `UNNECESSARY_FOLD` lint
diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.rs b/src/tools/clippy/tests/ui/unnecessary_fold.rs
index d27cc460c..2e6d6ba52 100644
--- a/src/tools/clippy/tests/ui/unnecessary_fold.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_fold.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
/// Calls which should trigger the `UNNECESSARY_FOLD` lint
diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.stderr b/src/tools/clippy/tests/ui/unnecessary_fold.stderr
index 98979f747..f0d039638 100644
--- a/src/tools/clippy/tests/ui/unnecessary_fold.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_fold.stderr
@@ -1,91 +1,92 @@
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:8:20
+ --> $DIR/unnecessary_fold.rs:6:20
|
LL | let _ = (0..3).fold(false, |acc, x| acc || x > 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`
|
= note: `-D clippy::unnecessary-fold` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:10:20
+ --> $DIR/unnecessary_fold.rs:8:20
|
LL | let _ = (0..3).fold(true, |acc, x| acc && x > 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:12:25
+ --> $DIR/unnecessary_fold.rs:10:25
|
LL | let _: i32 = (0..3).fold(0, |acc, x| acc + x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:14:25
+ --> $DIR/unnecessary_fold.rs:12:25
|
LL | let _: i32 = (0..3).fold(1, |acc, x| acc * x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:19:41
+ --> $DIR/unnecessary_fold.rs:17:41
|
LL | let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:49:10
+ --> $DIR/unnecessary_fold.rs:47:10
|
LL | .fold(false, |acc, x| acc || x > 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:60:33
+ --> $DIR/unnecessary_fold.rs:58:33
|
LL | assert_eq!(map.values().fold(0, |x, y| x + y), 0);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:63:30
+ --> $DIR/unnecessary_fold.rs:61:30
|
LL | let _ = map.values().fold(0, |x, y| x + y);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:64:30
+ --> $DIR/unnecessary_fold.rs:62:30
|
LL | let _ = map.values().fold(1, |x, y| x * y);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:65:35
+ --> $DIR/unnecessary_fold.rs:63:35
|
LL | let _: i32 = map.values().fold(0, |x, y| x + y);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:66:35
+ --> $DIR/unnecessary_fold.rs:64:35
|
LL | let _: i32 = map.values().fold(1, |x, y| x * y);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:67:31
+ --> $DIR/unnecessary_fold.rs:65:31
|
LL | anything(map.values().fold(0, |x, y| x + y));
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:68:31
+ --> $DIR/unnecessary_fold.rs:66:31
|
LL | anything(map.values().fold(1, |x, y| x * y));
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:69:26
+ --> $DIR/unnecessary_fold.rs:67:26
|
LL | num(map.values().fold(0, |x, y| x + y));
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`
error: this `.fold` can be written more succinctly using another method
- --> $DIR/unnecessary_fold.rs:70:26
+ --> $DIR/unnecessary_fold.rs:68:26
|
LL | num(map.values().fold(1, |x, y| x * y));
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`
diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed
index a0f8dd1a2..ad0e5fab0 100644
--- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_assignments)]
#![warn(clippy::unnecessary_to_owned)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs
index 98f2dfe75..d3d59c4c7 100644
--- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_assignments)]
#![warn(clippy::unnecessary_to_owned)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr
index 8f151e620..ba40c6c14 100644
--- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.stderr
@@ -1,10 +1,11 @@
error: unnecessary use of `copied`
- --> $DIR/unnecessary_iter_cloned.rs:31:22
+ --> $DIR/unnecessary_iter_cloned.rs:29:22
|
LL | for (t, path) in files.iter().copied() {
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
help: use
|
LL | for (t, path) in files {
@@ -16,7 +17,7 @@ LL + let other = match get_file_path(t) {
|
error: unnecessary use of `copied`
- --> $DIR/unnecessary_iter_cloned.rs:46:22
+ --> $DIR/unnecessary_iter_cloned.rs:44:22
|
LL | for (t, path) in files.iter().copied() {
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_join.fixed b/src/tools/clippy/tests/ui/unnecessary_join.fixed
index f13a5275e..dab09be7e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_join.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_join.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unnecessary_join)]
#![allow(clippy::uninlined_format_args, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_join.rs b/src/tools/clippy/tests/ui/unnecessary_join.rs
index 6014d723a..d042d9e5c 100644
--- a/src/tools/clippy/tests/ui/unnecessary_join.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_join.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unnecessary_join)]
#![allow(clippy::uninlined_format_args, clippy::useless_vec)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_join.stderr b/src/tools/clippy/tests/ui/unnecessary_join.stderr
index e919a6d1d..8bf2ac5fd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_join.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_join.stderr
@@ -1,5 +1,5 @@
error: called `.collect::<Vec<String>>().join("")` on an iterator
- --> $DIR/unnecessary_join.rs:11:10
+ --> $DIR/unnecessary_join.rs:10:10
|
LL | .collect::<Vec<String>>()
| __________^
@@ -7,9 +7,10 @@ LL | | .join("");
| |_________________^ help: try using: `collect::<String>()`
|
= note: `-D clippy::unnecessary-join` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_join)]`
error: called `.collect::<Vec<String>>().join("")` on an iterator
- --> $DIR/unnecessary_join.rs:20:10
+ --> $DIR/unnecessary_join.rs:19:10
|
LL | .collect::<Vec<_>>()
| __________^
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
index dca380341..304e7b7fd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![warn(clippy::unnecessary_lazy_evaluations)]
#![allow(clippy::redundant_closure)]
#![allow(clippy::bind_instead_of_map)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
index 7fda719ed..ddfa6bb3e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build: proc_macros.rs:proc-macro
+//@aux-build: proc_macros.rs
#![warn(clippy::unnecessary_lazy_evaluations)]
#![allow(clippy::redundant_closure)]
#![allow(clippy::bind_instead_of_map)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
index 458eed1f3..4f1ca3748 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
@@ -1,5 +1,5 @@
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:69:13
+ --> $DIR/unnecessary_lazy_eval.rs:68:13
|
LL | let _ = opt.unwrap_or_else(|| 2);
| ^^^^--------------------
@@ -7,9 +7,10 @@ LL | let _ = opt.unwrap_or_else(|| 2);
| help: use `unwrap_or(..)` instead: `unwrap_or(2)`
|
= note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:70:13
+ --> $DIR/unnecessary_lazy_eval.rs:69:13
|
LL | let _ = opt.unwrap_or_else(|| astronomers_pi);
| ^^^^---------------------------------
@@ -17,7 +18,7 @@ LL | let _ = opt.unwrap_or_else(|| astronomers_pi);
| help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:71:13
+ --> $DIR/unnecessary_lazy_eval.rs:70:13
|
LL | let _ = opt.unwrap_or_else(|| ext_str.some_field);
| ^^^^-------------------------------------
@@ -25,7 +26,7 @@ LL | let _ = opt.unwrap_or_else(|| ext_str.some_field);
| help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:73:13
+ --> $DIR/unnecessary_lazy_eval.rs:72:13
|
LL | let _ = opt.and_then(|_| ext_opt);
| ^^^^---------------------
@@ -33,7 +34,7 @@ LL | let _ = opt.and_then(|_| ext_opt);
| help: use `and(..)` instead: `and(ext_opt)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:74:13
+ --> $DIR/unnecessary_lazy_eval.rs:73:13
|
LL | let _ = opt.or_else(|| ext_opt);
| ^^^^-------------------
@@ -41,7 +42,7 @@ LL | let _ = opt.or_else(|| ext_opt);
| help: use `or(..)` instead: `or(ext_opt)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:75:13
+ --> $DIR/unnecessary_lazy_eval.rs:74:13
|
LL | let _ = opt.or_else(|| None);
| ^^^^----------------
@@ -49,7 +50,7 @@ LL | let _ = opt.or_else(|| None);
| help: use `or(..)` instead: `or(None)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:76:13
+ --> $DIR/unnecessary_lazy_eval.rs:75:13
|
LL | let _ = opt.get_or_insert_with(|| 2);
| ^^^^------------------------
@@ -57,7 +58,7 @@ LL | let _ = opt.get_or_insert_with(|| 2);
| help: use `get_or_insert(..)` instead: `get_or_insert(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:77:13
+ --> $DIR/unnecessary_lazy_eval.rs:76:13
|
LL | let _ = opt.ok_or_else(|| 2);
| ^^^^----------------
@@ -65,7 +66,7 @@ LL | let _ = opt.ok_or_else(|| 2);
| help: use `ok_or(..)` instead: `ok_or(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:78:13
+ --> $DIR/unnecessary_lazy_eval.rs:77:13
|
LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
| ^^^^^^^^^^^^^^^^^-------------------------------
@@ -73,7 +74,7 @@ LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
| help: use `unwrap_or(..)` instead: `unwrap_or(Some((1, 2)))`
error: unnecessary closure used with `bool::then`
- --> $DIR/unnecessary_lazy_eval.rs:79:13
+ --> $DIR/unnecessary_lazy_eval.rs:78:13
|
LL | let _ = cond.then(|| astronomers_pi);
| ^^^^^-----------------------
@@ -81,7 +82,7 @@ LL | let _ = cond.then(|| astronomers_pi);
| help: use `then_some(..)` instead: `then_some(astronomers_pi)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:83:13
+ --> $DIR/unnecessary_lazy_eval.rs:82:13
|
LL | let _ = Some(1).unwrap_or_else(|| *r);
| ^^^^^^^^---------------------
@@ -89,7 +90,7 @@ LL | let _ = Some(1).unwrap_or_else(|| *r);
| help: use `unwrap_or(..)` instead: `unwrap_or(*r)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:85:13
+ --> $DIR/unnecessary_lazy_eval.rs:84:13
|
LL | let _ = Some(1).unwrap_or_else(|| *b);
| ^^^^^^^^---------------------
@@ -97,7 +98,7 @@ LL | let _ = Some(1).unwrap_or_else(|| *b);
| help: use `unwrap_or(..)` instead: `unwrap_or(*b)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:87:13
+ --> $DIR/unnecessary_lazy_eval.rs:86:13
|
LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r);
| ^^^^^^^^^^^^^^^^^---------------------
@@ -105,7 +106,7 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &r);
| help: use `unwrap_or(..)` instead: `unwrap_or(&r)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:88:13
+ --> $DIR/unnecessary_lazy_eval.rs:87:13
|
LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b);
| ^^^^^^^^^^^^^^^^^---------------------
@@ -113,7 +114,7 @@ LL | let _ = Some(1).as_ref().unwrap_or_else(|| &b);
| help: use `unwrap_or(..)` instead: `unwrap_or(&b)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:91:13
+ --> $DIR/unnecessary_lazy_eval.rs:90:13
|
LL | let _ = Some(10).unwrap_or_else(|| 2);
| ^^^^^^^^^--------------------
@@ -121,7 +122,7 @@ LL | let _ = Some(10).unwrap_or_else(|| 2);
| help: use `unwrap_or(..)` instead: `unwrap_or(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:92:13
+ --> $DIR/unnecessary_lazy_eval.rs:91:13
|
LL | let _ = Some(10).and_then(|_| ext_opt);
| ^^^^^^^^^---------------------
@@ -129,7 +130,7 @@ LL | let _ = Some(10).and_then(|_| ext_opt);
| help: use `and(..)` instead: `and(ext_opt)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:93:28
+ --> $DIR/unnecessary_lazy_eval.rs:92:28
|
LL | let _: Option<usize> = None.or_else(|| ext_opt);
| ^^^^^-------------------
@@ -137,7 +138,7 @@ LL | let _: Option<usize> = None.or_else(|| ext_opt);
| help: use `or(..)` instead: `or(ext_opt)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:94:13
+ --> $DIR/unnecessary_lazy_eval.rs:93:13
|
LL | let _ = None.get_or_insert_with(|| 2);
| ^^^^^------------------------
@@ -145,7 +146,7 @@ LL | let _ = None.get_or_insert_with(|| 2);
| help: use `get_or_insert(..)` instead: `get_or_insert(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:95:35
+ --> $DIR/unnecessary_lazy_eval.rs:94:35
|
LL | let _: Result<usize, usize> = None.ok_or_else(|| 2);
| ^^^^^----------------
@@ -153,7 +154,7 @@ LL | let _: Result<usize, usize> = None.ok_or_else(|| 2);
| help: use `ok_or(..)` instead: `ok_or(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:96:28
+ --> $DIR/unnecessary_lazy_eval.rs:95:28
|
LL | let _: Option<usize> = None.or_else(|| None);
| ^^^^^----------------
@@ -161,7 +162,7 @@ LL | let _: Option<usize> = None.or_else(|| None);
| help: use `or(..)` instead: `or(None)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:99:13
+ --> $DIR/unnecessary_lazy_eval.rs:98:13
|
LL | let _ = deep.0.unwrap_or_else(|| 2);
| ^^^^^^^--------------------
@@ -169,7 +170,7 @@ LL | let _ = deep.0.unwrap_or_else(|| 2);
| help: use `unwrap_or(..)` instead: `unwrap_or(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:100:13
+ --> $DIR/unnecessary_lazy_eval.rs:99:13
|
LL | let _ = deep.0.and_then(|_| ext_opt);
| ^^^^^^^---------------------
@@ -177,7 +178,7 @@ LL | let _ = deep.0.and_then(|_| ext_opt);
| help: use `and(..)` instead: `and(ext_opt)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:101:13
+ --> $DIR/unnecessary_lazy_eval.rs:100:13
|
LL | let _ = deep.0.or_else(|| None);
| ^^^^^^^----------------
@@ -185,7 +186,7 @@ LL | let _ = deep.0.or_else(|| None);
| help: use `or(..)` instead: `or(None)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:102:13
+ --> $DIR/unnecessary_lazy_eval.rs:101:13
|
LL | let _ = deep.0.get_or_insert_with(|| 2);
| ^^^^^^^------------------------
@@ -193,7 +194,7 @@ LL | let _ = deep.0.get_or_insert_with(|| 2);
| help: use `get_or_insert(..)` instead: `get_or_insert(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:103:13
+ --> $DIR/unnecessary_lazy_eval.rs:102:13
|
LL | let _ = deep.0.ok_or_else(|| 2);
| ^^^^^^^----------------
@@ -201,7 +202,7 @@ LL | let _ = deep.0.ok_or_else(|| 2);
| help: use `ok_or(..)` instead: `ok_or(2)`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:133:28
+ --> $DIR/unnecessary_lazy_eval.rs:132:28
|
LL | let _: Option<usize> = None.or_else(|| Some(3));
| ^^^^^-------------------
@@ -209,7 +210,7 @@ LL | let _: Option<usize> = None.or_else(|| Some(3));
| help: use `or(..)` instead: `or(Some(3))`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:134:13
+ --> $DIR/unnecessary_lazy_eval.rs:133:13
|
LL | let _ = deep.0.or_else(|| Some(3));
| ^^^^^^^-------------------
@@ -217,7 +218,7 @@ LL | let _ = deep.0.or_else(|| Some(3));
| help: use `or(..)` instead: `or(Some(3))`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:135:13
+ --> $DIR/unnecessary_lazy_eval.rs:134:13
|
LL | let _ = opt.or_else(|| Some(3));
| ^^^^-------------------
@@ -225,7 +226,7 @@ LL | let _ = opt.or_else(|| Some(3));
| help: use `or(..)` instead: `or(Some(3))`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:141:13
+ --> $DIR/unnecessary_lazy_eval.rs:140:13
|
LL | let _ = res2.unwrap_or_else(|_| 2);
| ^^^^^---------------------
@@ -233,7 +234,7 @@ LL | let _ = res2.unwrap_or_else(|_| 2);
| help: use `unwrap_or(..)` instead: `unwrap_or(2)`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:142:13
+ --> $DIR/unnecessary_lazy_eval.rs:141:13
|
LL | let _ = res2.unwrap_or_else(|_| astronomers_pi);
| ^^^^^----------------------------------
@@ -241,7 +242,7 @@ LL | let _ = res2.unwrap_or_else(|_| astronomers_pi);
| help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:143:13
+ --> $DIR/unnecessary_lazy_eval.rs:142:13
|
LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field);
| ^^^^^--------------------------------------
@@ -249,7 +250,7 @@ LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field);
| help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:165:35
+ --> $DIR/unnecessary_lazy_eval.rs:164:35
|
LL | let _: Result<usize, usize> = res.and_then(|_| Err(2));
| ^^^^--------------------
@@ -257,7 +258,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(2));
| help: use `and(..)` instead: `and(Err(2))`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:166:35
+ --> $DIR/unnecessary_lazy_eval.rs:165:35
|
LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
| ^^^^---------------------------------
@@ -265,7 +266,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
| help: use `and(..)` instead: `and(Err(astronomers_pi))`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:167:35
+ --> $DIR/unnecessary_lazy_eval.rs:166:35
|
LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
| ^^^^-------------------------------------
@@ -273,7 +274,7 @@ LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field))
| help: use `and(..)` instead: `and(Err(ext_str.some_field))`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:169:35
+ --> $DIR/unnecessary_lazy_eval.rs:168:35
|
LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2));
| ^^^^------------------
@@ -281,7 +282,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2));
| help: use `or(..)` instead: `or(Ok(2))`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:170:35
+ --> $DIR/unnecessary_lazy_eval.rs:169:35
|
LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
| ^^^^-------------------------------
@@ -289,7 +290,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
| help: use `or(..)` instead: `or(Ok(astronomers_pi))`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:171:35
+ --> $DIR/unnecessary_lazy_eval.rs:170:35
|
LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
| ^^^^-----------------------------------
@@ -297,7 +298,7 @@ LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
| help: use `or(..)` instead: `or(Ok(ext_str.some_field))`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval.rs:172:35
+ --> $DIR/unnecessary_lazy_eval.rs:171:35
|
LL | let _: Result<usize, usize> = res.
| ___________________________________^
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs
index b4a1f8167..33685bfb7 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs
@@ -1,6 +1,6 @@
#![warn(clippy::unnecessary_lazy_evaluations)]
#![allow(clippy::unnecessary_literal_unwrap)]
-
+//@no-rustfix
struct Deep(Option<usize>);
#[derive(Copy, Clone)]
@@ -11,11 +11,15 @@ struct SomeStruct {
fn main() {
// fix will break type inference
let _ = Ok(1).unwrap_or_else(|()| 2);
+ //~^ ERROR: unnecessary closure used to substitute value for `Result::Err`
+ //~| NOTE: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
mod e {
pub struct E;
}
let _ = Ok(1).unwrap_or_else(|e::E| 2);
+ //~^ ERROR: unnecessary closure used to substitute value for `Result::Err`
let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);
+ //~^ ERROR: unnecessary closure used to substitute value for `Result::Err`
// Fix #6343
let arr = [(Some(1),)];
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
index 7f353ba06..27fa560d4 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
@@ -7,9 +7,10 @@ LL | let _ = Ok(1).unwrap_or_else(|()| 2);
| help: use `unwrap_or(..)` instead: `unwrap_or(2)`
|
= note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval_unfixable.rs:17:13
+ --> $DIR/unnecessary_lazy_eval_unfixable.rs:19:13
|
LL | let _ = Ok(1).unwrap_or_else(|e::E| 2);
| ^^^^^^------------------------
@@ -17,7 +18,7 @@ LL | let _ = Ok(1).unwrap_or_else(|e::E| 2);
| help: use `unwrap_or(..)` instead: `unwrap_or(2)`
error: unnecessary closure used to substitute value for `Result::Err`
- --> $DIR/unnecessary_lazy_eval_unfixable.rs:18:13
+ --> $DIR/unnecessary_lazy_eval_unfixable.rs:21:13
|
LL | let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);
| ^^^^^^-------------------------------------
diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed
index 72d52c623..87df1f8cb 100644
--- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unnecessary_literal_unwrap)]
#![allow(unreachable_code)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs
index 7d713ea20..7bd8deea4 100644
--- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unnecessary_literal_unwrap)]
#![allow(unreachable_code)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr
index 7f603d6ef..013907f59 100644
--- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr
@@ -1,10 +1,11 @@
error: used `unwrap()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:12:16
+ --> $DIR/unnecessary_literal_unwrap.rs:11:16
|
LL | let _val = Some(1).unwrap();
| ^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_literal_unwrap)]`
help: remove the `Some` and `unwrap()`
|
LL - let _val = Some(1).unwrap();
@@ -12,7 +13,7 @@ LL + let _val = 1;
|
error: used `expect()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:13:16
+ --> $DIR/unnecessary_literal_unwrap.rs:12:16
|
LL | let _val = Some(1).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL + let _val = 1;
|
error: used `unwrap()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:15:5
+ --> $DIR/unnecessary_literal_unwrap.rs:14:5
|
LL | Some(1).unwrap();
| ^^^^^^^^^^^^^^^^
@@ -36,7 +37,7 @@ LL + 1;
|
error: used `expect()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:16:5
+ --> $DIR/unnecessary_literal_unwrap.rs:15:5
|
LL | Some(1).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,13 +49,13 @@ LL + 1;
|
error: used `unwrap()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:21:16
+ --> $DIR/unnecessary_literal_unwrap.rs:20:16
|
LL | let _val = None::<()>.unwrap();
| ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()`
error: used `expect()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:22:16
+ --> $DIR/unnecessary_literal_unwrap.rs:21:16
|
LL | let _val = None::<()>.expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -65,13 +66,13 @@ LL | let _val = panic!("this always happens");
| ~~~~~~~ ~
error: used `unwrap_or_default()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:23:24
+ --> $DIR/unnecessary_literal_unwrap.rs:22:24
|
LL | let _val: String = None.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `String::default()`
error: used `unwrap_or()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:24:21
+ --> $DIR/unnecessary_literal_unwrap.rs:23:21
|
LL | let _val: u16 = None.unwrap_or(234);
| ^^^^^^^^^^^^^^^^^^^
@@ -83,7 +84,7 @@ LL + let _val: u16 = 234;
|
error: used `unwrap_or_else()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:25:21
+ --> $DIR/unnecessary_literal_unwrap.rs:24:21
|
LL | let _val: u16 = None.unwrap_or_else(|| 234);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -95,7 +96,7 @@ LL + let _val: u16 = 234;
|
error: used `unwrap_or_else()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:26:21
+ --> $DIR/unnecessary_literal_unwrap.rs:25:21
|
LL | let _val: u16 = None.unwrap_or_else(|| { 234 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -107,7 +108,7 @@ LL + let _val: u16 = { 234 };
|
error: used `unwrap_or_else()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:27:21
+ --> $DIR/unnecessary_literal_unwrap.rs:26:21
|
LL | let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -119,13 +120,13 @@ LL + let _val: u16 = { 234 };
|
error: used `unwrap()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:29:5
+ --> $DIR/unnecessary_literal_unwrap.rs:28:5
|
LL | None::<()>.unwrap();
| ^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap()`: `panic!()`
error: used `expect()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:30:5
+ --> $DIR/unnecessary_literal_unwrap.rs:29:5
|
LL | None::<()>.expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -136,13 +137,13 @@ LL | panic!("this always happens");
| ~~~~~~~ ~
error: used `unwrap_or_default()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:31:5
+ --> $DIR/unnecessary_literal_unwrap.rs:30:5
|
LL | None::<String>.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `String::default()`
error: used `unwrap_or()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:32:5
+ --> $DIR/unnecessary_literal_unwrap.rs:31:5
|
LL | None::<u16>.unwrap_or(234);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,7 +155,7 @@ LL + 234;
|
error: used `unwrap_or_else()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:33:5
+ --> $DIR/unnecessary_literal_unwrap.rs:32:5
|
LL | None::<u16>.unwrap_or_else(|| 234);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -166,7 +167,7 @@ LL + 234;
|
error: used `unwrap_or_else()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:34:5
+ --> $DIR/unnecessary_literal_unwrap.rs:33:5
|
LL | None::<u16>.unwrap_or_else(|| { 234 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -178,7 +179,7 @@ LL + { 234 };
|
error: used `unwrap_or_else()` on `None` value
- --> $DIR/unnecessary_literal_unwrap.rs:35:5
+ --> $DIR/unnecessary_literal_unwrap.rs:34:5
|
LL | None::<u16>.unwrap_or_else(|| -> u16 { 234 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -190,7 +191,7 @@ LL + { 234 };
|
error: used `unwrap()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:39:16
+ --> $DIR/unnecessary_literal_unwrap.rs:38:16
|
LL | let _val = Ok::<_, ()>(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -202,7 +203,7 @@ LL + let _val = 1;
|
error: used `expect()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:40:16
+ --> $DIR/unnecessary_literal_unwrap.rs:39:16
|
LL | let _val = Ok::<_, ()>(1).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -214,7 +215,7 @@ LL + let _val = 1;
|
error: used `unwrap_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:41:16
+ --> $DIR/unnecessary_literal_unwrap.rs:40:16
|
LL | let _val = Ok::<_, ()>(1).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -225,7 +226,7 @@ LL | let _val = panic!("{:?}", 1);
| ~~~~~~~~~~~~~~ ~
error: used `expect_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:42:16
+ --> $DIR/unnecessary_literal_unwrap.rs:41:16
|
LL | let _val = Ok::<_, ()>(1).expect_err("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -236,7 +237,7 @@ LL | let _val = panic!("{1}: {:?}", 1, "this always happens");
| ~~~~~~~~~~~~~~~~~~~ ~
error: used `unwrap()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:44:5
+ --> $DIR/unnecessary_literal_unwrap.rs:43:5
|
LL | Ok::<_, ()>(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -248,7 +249,7 @@ LL + 1;
|
error: used `expect()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:45:5
+ --> $DIR/unnecessary_literal_unwrap.rs:44:5
|
LL | Ok::<_, ()>(1).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -260,7 +261,7 @@ LL + 1;
|
error: used `unwrap_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:46:5
+ --> $DIR/unnecessary_literal_unwrap.rs:45:5
|
LL | Ok::<_, ()>(1).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -271,7 +272,7 @@ LL | panic!("{:?}", 1);
| ~~~~~~~~~~~~~~ ~
error: used `expect_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:47:5
+ --> $DIR/unnecessary_literal_unwrap.rs:46:5
|
LL | Ok::<_, ()>(1).expect_err("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -282,7 +283,7 @@ LL | panic!("{1}: {:?}", 1, "this always happens");
| ~~~~~~~~~~~~~~~~~~~ ~
error: used `unwrap_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:51:16
+ --> $DIR/unnecessary_literal_unwrap.rs:50:16
|
LL | let _val = Err::<(), _>(1).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -294,7 +295,7 @@ LL + let _val = 1;
|
error: used `expect_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:52:16
+ --> $DIR/unnecessary_literal_unwrap.rs:51:16
|
LL | let _val = Err::<(), _>(1).expect_err("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -306,7 +307,7 @@ LL + let _val = 1;
|
error: used `unwrap()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:53:16
+ --> $DIR/unnecessary_literal_unwrap.rs:52:16
|
LL | let _val = Err::<(), _>(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -317,7 +318,7 @@ LL | let _val = panic!("{:?}", 1);
| ~~~~~~~~~~~~~~ ~
error: used `expect()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:54:16
+ --> $DIR/unnecessary_literal_unwrap.rs:53:16
|
LL | let _val = Err::<(), _>(1).expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -328,7 +329,7 @@ LL | let _val = panic!("{1}: {:?}", 1, "this always happens");
| ~~~~~~~~~~~~~~~~~~~ ~
error: used `unwrap_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:56:5
+ --> $DIR/unnecessary_literal_unwrap.rs:55:5
|
LL | Err::<(), _>(1).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -340,7 +341,7 @@ LL + 1;
|
error: used `expect_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:57:5
+ --> $DIR/unnecessary_literal_unwrap.rs:56:5
|
LL | Err::<(), _>(1).expect_err("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -352,7 +353,7 @@ LL + 1;
|
error: used `unwrap()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:58:5
+ --> $DIR/unnecessary_literal_unwrap.rs:57:5
|
LL | Err::<(), _>(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -363,7 +364,7 @@ LL | panic!("{:?}", 1);
| ~~~~~~~~~~~~~~ ~
error: used `expect()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:59:5
+ --> $DIR/unnecessary_literal_unwrap.rs:58:5
|
LL | Err::<(), _>(1).expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -374,7 +375,7 @@ LL | panic!("{1}: {:?}", 1, "this always happens");
| ~~~~~~~~~~~~~~~~~~~ ~
error: used `unwrap_or()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:63:16
+ --> $DIR/unnecessary_literal_unwrap.rs:62:16
|
LL | let _val = Some(1).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^
@@ -386,7 +387,7 @@ LL + let _val = 1;
|
error: used `unwrap_or_default()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:64:16
+ --> $DIR/unnecessary_literal_unwrap.rs:63:16
|
LL | let _val = Some(1).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -398,7 +399,7 @@ LL + let _val = 1;
|
error: used `unwrap_or_else()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:65:16
+ --> $DIR/unnecessary_literal_unwrap.rs:64:16
|
LL | let _val = Some(1).unwrap_or_else(|| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -410,7 +411,7 @@ LL + let _val = 1;
|
error: used `unwrap_or()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:67:5
+ --> $DIR/unnecessary_literal_unwrap.rs:66:5
|
LL | Some(1).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^
@@ -422,7 +423,7 @@ LL + 1;
|
error: used `unwrap_or_default()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:68:5
+ --> $DIR/unnecessary_literal_unwrap.rs:67:5
|
LL | Some(1).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -434,7 +435,7 @@ LL + 1;
|
error: used `unwrap_or_else()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:69:5
+ --> $DIR/unnecessary_literal_unwrap.rs:68:5
|
LL | Some(1).unwrap_or_else(|| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -446,7 +447,7 @@ LL + 1;
|
error: used `unwrap_or()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:73:16
+ --> $DIR/unnecessary_literal_unwrap.rs:72:16
|
LL | let _val = Ok::<_, ()>(1).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -458,7 +459,7 @@ LL + let _val = 1;
|
error: used `unwrap_or_default()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:74:16
+ --> $DIR/unnecessary_literal_unwrap.rs:73:16
|
LL | let _val = Ok::<_, ()>(1).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -470,7 +471,7 @@ LL + let _val = 1;
|
error: used `unwrap_or_else()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:75:16
+ --> $DIR/unnecessary_literal_unwrap.rs:74:16
|
LL | let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -482,7 +483,7 @@ LL + let _val = 1;
|
error: used `unwrap_or()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:77:5
+ --> $DIR/unnecessary_literal_unwrap.rs:76:5
|
LL | Ok::<_, ()>(1).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -494,7 +495,7 @@ LL + 1;
|
error: used `unwrap_or_default()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:78:5
+ --> $DIR/unnecessary_literal_unwrap.rs:77:5
|
LL | Ok::<_, ()>(1).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -506,7 +507,7 @@ LL + 1;
|
error: used `unwrap_or_else()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:79:5
+ --> $DIR/unnecessary_literal_unwrap.rs:78:5
|
LL | Ok::<_, ()>(1).unwrap_or_else(|_| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -518,7 +519,7 @@ LL + 1;
|
error: used `unwrap_unchecked()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:93:22
+ --> $DIR/unnecessary_literal_unwrap.rs:92:22
|
LL | let _ = unsafe { Some(1).unwrap_unchecked() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -530,7 +531,7 @@ LL + let _ = 1;
|
error: used `unwrap_unchecked()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:94:22
+ --> $DIR/unnecessary_literal_unwrap.rs:93:22
|
LL | let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -542,7 +543,7 @@ LL + let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe
|
error: used `unwrap_unchecked()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap.rs:95:22
+ --> $DIR/unnecessary_literal_unwrap.rs:94:22
|
LL | let _ = unsafe { Some(1).unwrap_unchecked() } + 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -554,7 +555,7 @@ LL + let _ = 1 + 1;
|
error: used `unwrap_unchecked()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:96:22
+ --> $DIR/unnecessary_literal_unwrap.rs:95:22
|
LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -566,7 +567,7 @@ LL + let _ = 1;
|
error: used `unwrap_unchecked()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:97:22
+ --> $DIR/unnecessary_literal_unwrap.rs:96:22
|
LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -578,7 +579,7 @@ LL + let _ = unsafe { 1 + *(&1 as *const i32) };
|
error: used `unwrap_unchecked()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap.rs:98:22
+ --> $DIR/unnecessary_literal_unwrap.rs:97:22
|
LL | let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -590,7 +591,7 @@ LL + let _ = 1 + 1;
|
error: used `unwrap_err_unchecked()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap.rs:99:22
+ --> $DIR/unnecessary_literal_unwrap.rs:98:22
|
LL | let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs
index 41300aceb..61058b798 100644
--- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.rs
@@ -1,106 +1,158 @@
#![warn(clippy::unnecessary_literal_unwrap)]
#![allow(unreachable_code)]
#![allow(clippy::unnecessary_lazy_evaluations, clippy::let_unit_value)]
-
+//@no-rustfix
fn unwrap_option_some() {
let val = Some(1);
let _val2 = val.unwrap();
+ //~^ ERROR: used `unwrap()` on `Some` value
let _val2 = val.expect("this never happens");
+ //~^ ERROR: used `expect()` on `Some` value
}
fn unwrap_option_some_context() {
let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap();
+ //~^ ERROR: used `unwrap()` on `Some` value
let _val = Some::<usize>([1, 2, 3].iter().sum()).expect("this never happens");
+ //~^ ERROR: used `expect()` on `Some` value
let val = Some::<usize>([1, 2, 3].iter().sum());
let _val2 = val.unwrap();
+ //~^ ERROR: used `unwrap()` on `Some` value
let _val2 = val.expect("this never happens");
+ //~^ ERROR: used `expect()` on `Some` value
}
fn unwrap_option_none() {
let val = None::<()>;
let _val2 = val.unwrap();
+ //~^ ERROR: used `unwrap()` on `None` value
let _val2 = val.expect("this always happens");
+ //~^ ERROR: used `expect()` on `None` value
let _val3: u8 = None.unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `None` value
None::<()>.unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `None` value
}
fn unwrap_result_ok() {
let val = Ok::<_, ()>(1);
let _val2 = val.unwrap();
+ //~^ ERROR: used `unwrap()` on `Ok` value
let _val2 = val.expect("this never happens");
+ //~^ ERROR: used `expect()` on `Ok` value
let _val2 = val.unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on `Ok` value
let _val2 = val.expect_err("this always happens");
+ //~^ ERROR: used `expect_err()` on `Ok` value
}
fn unwrap_result_ok_context() {
let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap();
+ //~^ ERROR: used `unwrap()` on `Ok` value
let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect("this never happens");
+ //~^ ERROR: used `expect()` on `Ok` value
let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on `Ok` value
let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect_err("this always happens");
+ //~^ ERROR: used `expect_err()` on `Ok` value
let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
let _val2 = val.unwrap();
+ //~^ ERROR: used `unwrap()` on `Ok` value
let _val2 = val.expect("this never happens");
+ //~^ ERROR: used `expect()` on `Ok` value
let _val2 = val.unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on `Ok` value
let _val2 = val.expect_err("this always happens");
+ //~^ ERROR: used `expect_err()` on `Ok` value
}
fn unwrap_result_err() {
let val = Err::<(), _>(1);
let _val2 = val.unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on `Err` value
let _val2 = val.expect_err("this never happens");
+ //~^ ERROR: used `expect_err()` on `Err` value
let _val2 = val.unwrap();
+ //~^ ERROR: used `unwrap()` on `Err` value
let _val2 = val.expect("this always happens");
+ //~^ ERROR: used `expect()` on `Err` value
}
fn unwrap_result_err_context() {
let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on `Err` value
let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens");
+ //~^ ERROR: used `expect_err()` on `Err` value
let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap();
+ //~^ ERROR: used `unwrap()` on `Err` value
let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens");
+ //~^ ERROR: used `expect()` on `Err` value
let val = Err::<(), usize>([1, 2, 3].iter().sum());
let _val2 = val.unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on `Err` value
let _val2 = val.expect_err("this never happens");
+ //~^ ERROR: used `expect_err()` on `Err` value
let _val2 = val.unwrap();
+ //~^ ERROR: used `unwrap()` on `Err` value
let _val2 = val.expect("this always happens");
+ //~^ ERROR: used `expect()` on `Err` value
}
fn unwrap_methods_option() {
let val = Some(1);
let _val2 = val.unwrap_or(2);
+ //~^ ERROR: used `unwrap_or()` on `Some` value
let _val2 = val.unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `Some` value
let _val2 = val.unwrap_or_else(|| 2);
+ //~^ ERROR: used `unwrap_or_else()` on `Some` value
}
fn unwrap_methods_option_context() {
let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or(2);
+ //~^ ERROR: used `unwrap_or()` on `Some` value
let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `Some` value
let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_else(|| 2);
+ //~^ ERROR: used `unwrap_or_else()` on `Some` value
let val = Some::<usize>([1, 2, 3].iter().sum());
let _val2 = val.unwrap_or(2);
+ //~^ ERROR: used `unwrap_or()` on `Some` value
let _val2 = val.unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `Some` value
let _val2 = val.unwrap_or_else(|| 2);
+ //~^ ERROR: used `unwrap_or_else()` on `Some` value
}
fn unwrap_methods_result() {
let val = Ok::<_, ()>(1);
let _val2 = val.unwrap_or(2);
+ //~^ ERROR: used `unwrap_or()` on `Ok` value
let _val2 = val.unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `Ok` value
let _val2 = val.unwrap_or_else(|_| 2);
+ //~^ ERROR: used `unwrap_or_else()` on `Ok` value
}
fn unwrap_methods_result_context() {
let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or(2);
+ //~^ ERROR: used `unwrap_or()` on `Ok` value
let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `Ok` value
let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2);
+ //~^ ERROR: used `unwrap_or_else()` on `Ok` value
let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
let _val2 = val.unwrap_or(2);
+ //~^ ERROR: used `unwrap_or()` on `Ok` value
let _val2 = val.unwrap_or_default();
+ //~^ ERROR: used `unwrap_or_default()` on `Ok` value
let _val2 = val.unwrap_or_else(|_| 2);
+ //~^ ERROR: used `unwrap_or_else()` on `Ok` value
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr
index 2d1270d47..c6ecd6de6 100644
--- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap_unfixable.stderr
@@ -10,9 +10,10 @@ help: remove the `Some` and `unwrap()`
LL | let val = Some(1);
| ^^^^^^^
= note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_literal_unwrap)]`
error: used `expect()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:8:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:9:17
|
LL | let _val2 = val.expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,589 +25,589 @@ LL | let val = Some(1);
| ^^^^^^^
error: used `unwrap()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:12:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:14:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:12:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:14:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:13:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:16:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:13:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:16:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:16:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:20:17
|
LL | let _val2 = val.unwrap();
| ^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:15:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:19:15
|
LL | let val = Some::<usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:17:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:22:17
|
LL | let _val2 = val.expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:15:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:19:15
|
LL | let val = Some::<usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap()` on `None` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:22:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:28:17
|
LL | let _val2 = val.unwrap();
| ^^^^^^^^^^^^
|
help: remove the `None` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:21:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15
|
LL | let val = None::<()>;
| ^^^^^^^^^^
error: used `expect()` on `None` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:23:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:30:17
|
LL | let _val2 = val.expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `None` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:21:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:27:15
|
LL | let val = None::<()>;
| ^^^^^^^^^^
error: used `unwrap_or_default()` on `None` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:24:21
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:32:21
|
LL | let _val3: u8 = None.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()`
error: used `unwrap_or_default()` on `None` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:25:5
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:34:5
|
LL | None::<()>.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the `None` and `unwrap_or_default()`: `Default::default()`
error: used `unwrap()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:30:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:17
|
LL | let _val2 = val.unwrap();
| ^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:15
|
LL | let val = Ok::<_, ()>(1);
| ^^^^^^^^^^^^^^
error: used `expect()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:31:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:17
|
LL | let _val2 = val.expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:15
|
LL | let val = Ok::<_, ()>(1);
| ^^^^^^^^^^^^^^
error: used `unwrap_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:32:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:44:17
|
LL | let _val2 = val.unwrap_err();
| ^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:15
|
LL | let val = Ok::<_, ()>(1);
| ^^^^^^^^^^^^^^
error: used `expect_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:33:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:46:17
|
LL | let _val2 = val.expect_err("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `expect_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:29:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:15
|
LL | let val = Ok::<_, ()>(1);
| ^^^^^^^^^^^^^^
error: used `unwrap()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:51:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:37:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:51:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:53:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:38:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:53:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:55:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:39:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:55:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect_err("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `expect_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:40:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:57:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect_err("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:43:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:17
|
LL | let _val2 = val.unwrap();
| ^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:15
|
LL | let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:44:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:17
|
LL | let _val2 = val.expect("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:15
|
LL | let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:45:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:65:17
|
LL | let _val2 = val.unwrap_err();
| ^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:15
|
LL | let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect_err()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:46:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:67:17
|
LL | let _val2 = val.expect_err("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `expect_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:42:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:15
|
LL | let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:51:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:73:17
|
LL | let _val2 = val.unwrap_err();
| ^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `unwrap_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:15
|
LL | let val = Err::<(), _>(1);
| ^^^^^^^^^^^^^^^
error: used `expect_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:52:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:75:17
|
LL | let _val2 = val.expect_err("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `expect_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:15
|
LL | let val = Err::<(), _>(1);
| ^^^^^^^^^^^^^^^
error: used `unwrap()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:53:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:77:17
|
LL | let _val2 = val.unwrap();
| ^^^^^^^^^^^^
|
help: remove the `Err` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:15
|
LL | let val = Err::<(), _>(1);
| ^^^^^^^^^^^^^^^
error: used `expect()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:54:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:79:17
|
LL | let _val2 = val.expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:50:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:15
|
LL | let val = Err::<(), _>(1);
| ^^^^^^^^^^^^^^^
error: used `unwrap_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:84:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `unwrap_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:58:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:84:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:86:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `expect_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:59:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:86:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:88:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:60:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:88:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:90:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:61:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:90:16
|
LL | let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:64:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:94:17
|
LL | let _val2 = val.unwrap_err();
| ^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `unwrap_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:93:15
|
LL | let val = Err::<(), usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect_err()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:65:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:17
|
LL | let _val2 = val.expect_err("this never happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `expect_err()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:93:15
|
LL | let val = Err::<(), usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:66:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:17
|
LL | let _val2 = val.unwrap();
| ^^^^^^^^^^^^
|
help: remove the `Err` and `unwrap()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:93:15
|
LL | let val = Err::<(), usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `expect()` on `Err` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:67:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:17
|
LL | let _val2 = val.expect("this always happens");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Err` and `expect()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:63:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:93:15
|
LL | let val = Err::<(), usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:72:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:106:17
|
LL | let _val2 = val.unwrap_or(2);
| ^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:105:15
|
LL | let val = Some(1);
| ^^^^^^^
error: used `unwrap_or_default()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:73:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:108:17
|
LL | let _val2 = val.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or_default()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:105:15
|
LL | let val = Some(1);
| ^^^^^^^
error: used `unwrap_or_else()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:74:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:110:17
|
LL | let _val2 = val.unwrap_or_else(|| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or_else()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:71:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:105:15
|
LL | let val = Some(1);
| ^^^^^^^
error: used `unwrap_or()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:115:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:78:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:115:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_default()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:79:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:117:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or_default()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:79:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:117:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_else()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:119:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_else(|| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or_else()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:80:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:119:16
|
LL | let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_else(|| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:83:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:123:17
|
LL | let _val2 = val.unwrap_or(2);
| ^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:122:15
|
LL | let val = Some::<usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_default()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:84:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:125:17
|
LL | let _val2 = val.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or_default()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:122:15
|
LL | let val = Some::<usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_else()` on `Some` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:85:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:127:17
|
LL | let _val2 = val.unwrap_or_else(|| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Some` and `unwrap_or_else()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:82:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:122:15
|
LL | let val = Some::<usize>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:90:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:133:17
|
LL | let _val2 = val.unwrap_or(2);
| ^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:132:15
|
LL | let val = Ok::<_, ()>(1);
| ^^^^^^^^^^^^^^
error: used `unwrap_or_default()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:91:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:135:17
|
LL | let _val2 = val.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or_default()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:132:15
|
LL | let val = Ok::<_, ()>(1);
| ^^^^^^^^^^^^^^
error: used `unwrap_or_else()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:92:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:137:17
|
LL | let _val2 = val.unwrap_or_else(|_| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or_else()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:89:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:132:15
|
LL | let val = Ok::<_, ()>(1);
| ^^^^^^^^^^^^^^
error: used `unwrap_or()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:142:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:96:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:142:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_default()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:97:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:144:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or_default()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:97:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:144:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_else()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:146:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or_else()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:98:16
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:146:16
|
LL | let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:101:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:150:17
|
LL | let _val2 = val.unwrap_or(2);
| ^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:149:15
|
LL | let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_default()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:102:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:152:17
|
LL | let _val2 = val.unwrap_or_default();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or_default()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:149:15
|
LL | let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used `unwrap_or_else()` on `Ok` value
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:103:17
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:154:17
|
LL | let _val2 = val.unwrap_or_else(|_| 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the `Ok` and `unwrap_or_else()`
- --> $DIR/unnecessary_literal_unwrap_unfixable.rs:100:15
+ --> $DIR/unnecessary_literal_unwrap_unfixable.rs:149:15
|
LL | let val = Ok::<usize, ()>([1, 2, 3].iter().sum());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed
new file mode 100644
index 000000000..d0ba7ed74
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed
@@ -0,0 +1,56 @@
+#![allow(unused)]
+#![warn(clippy::unnecessary_map_on_constructor)]
+
+use std::ffi::OsStr;
+
+fn fun(t: i32) -> i32 {
+ t
+}
+
+fn notfun(e: SimpleError) -> SimpleError {
+ e
+}
+macro_rules! expands_to_fun {
+ () => {
+ fun
+ };
+}
+
+#[derive(Copy, Clone)]
+struct SimpleError {}
+
+type SimpleResult = std::result::Result<i32, SimpleError>;
+
+fn main() {
+ let x: i32 = 4;
+
+ let err = SimpleError {};
+ let a = Some(x);
+ let b: SimpleResult = Ok(x);
+ let c: SimpleResult = Err(err);
+
+ let a = Some(fun(x));
+ let b: SimpleResult = Ok(fun(x));
+ let c: SimpleResult = Err(notfun(err));
+
+ let a = Option::Some(fun(x));
+ let b: SimpleResult = SimpleResult::Ok(fun(x));
+ let c: SimpleResult = SimpleResult::Err(notfun(err));
+ let b: std::result::Result<i32, SimpleError> = Ok(fun(x));
+ let c: std::result::Result<i32, SimpleError> = Err(notfun(err));
+
+ let a = Some(fun(x));
+ let b: SimpleResult = Ok(fun(x));
+ let c: SimpleResult = Err(notfun(err));
+
+ // Should not trigger warning
+ a.map(fun);
+ b.map(fun);
+ c.map_err(notfun);
+
+ b.map_err(notfun); // Ok(_).map_err
+ c.map(fun); // Err(_).map()
+
+ option_env!("PATH").map(OsStr::new);
+ Some(x).map(expands_to_fun!());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs
new file mode 100644
index 000000000..e89e7aad4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs
@@ -0,0 +1,56 @@
+#![allow(unused)]
+#![warn(clippy::unnecessary_map_on_constructor)]
+
+use std::ffi::OsStr;
+
+fn fun(t: i32) -> i32 {
+ t
+}
+
+fn notfun(e: SimpleError) -> SimpleError {
+ e
+}
+macro_rules! expands_to_fun {
+ () => {
+ fun
+ };
+}
+
+#[derive(Copy, Clone)]
+struct SimpleError {}
+
+type SimpleResult = std::result::Result<i32, SimpleError>;
+
+fn main() {
+ let x: i32 = 4;
+
+ let err = SimpleError {};
+ let a = Some(x);
+ let b: SimpleResult = Ok(x);
+ let c: SimpleResult = Err(err);
+
+ let a = Some(x).map(fun);
+ let b: SimpleResult = Ok(x).map(fun);
+ let c: SimpleResult = Err(err).map_err(notfun);
+
+ let a = Option::Some(x).map(fun);
+ let b: SimpleResult = SimpleResult::Ok(x).map(fun);
+ let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);
+ let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);
+ let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);
+
+ let a = Some(fun(x));
+ let b: SimpleResult = Ok(fun(x));
+ let c: SimpleResult = Err(notfun(err));
+
+ // Should not trigger warning
+ a.map(fun);
+ b.map(fun);
+ c.map_err(notfun);
+
+ b.map_err(notfun); // Ok(_).map_err
+ c.map(fun); // Err(_).map()
+
+ option_env!("PATH").map(OsStr::new);
+ Some(x).map(expands_to_fun!());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr
new file mode 100644
index 000000000..d522b68d8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr
@@ -0,0 +1,53 @@
+error: unnecessary map on constructor Some(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:32:13
+ |
+LL | let a = Some(x).map(fun);
+ | ^^^^^^^^^^^^^^^^ help: try: `Some(fun(x))`
+ |
+ = note: `-D clippy::unnecessary-map-on-constructor` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_on_constructor)]`
+
+error: unnecessary map on constructor Ok(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:33:27
+ |
+LL | let b: SimpleResult = Ok(x).map(fun);
+ | ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`
+
+error: unnecessary map_err on constructor Err(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:34:27
+ |
+LL | let c: SimpleResult = Err(err).map_err(notfun);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`
+
+error: unnecessary map on constructor Option::Some(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:36:13
+ |
+LL | let a = Option::Some(x).map(fun);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option::Some(fun(x))`
+
+error: unnecessary map on constructor SimpleResult::Ok(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:37:27
+ |
+LL | let b: SimpleResult = SimpleResult::Ok(x).map(fun);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Ok(fun(x))`
+
+error: unnecessary map_err on constructor SimpleResult::Err(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:38:27
+ |
+LL | let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Err(notfun(err))`
+
+error: unnecessary map on constructor Ok(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:39:52
+ |
+LL | let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);
+ | ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`
+
+error: unnecessary map_err on constructor Err(_)
+ --> $DIR/unnecessary_map_on_constructor.rs:40:52
+ |
+LL | let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
index fbd2d3459..d0c0298ef 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
clippy::deref_addrof,
dead_code,
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs
index b45298a6d..e8e3a2d56 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(
clippy::deref_addrof,
dead_code,
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.stderr b/src/tools/clippy/tests/ui/unnecessary_operation.stderr
index a1d0d9399..fbe495f51 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.stderr
@@ -1,109 +1,110 @@
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:56:5
+ --> $DIR/unnecessary_operation.rs:54:5
|
LL | Tuple(get_number());
| ^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
|
= note: `-D clippy::unnecessary-operation` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_operation)]`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:57:5
+ --> $DIR/unnecessary_operation.rs:55:5
|
LL | Struct { field: get_number() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:58:5
+ --> $DIR/unnecessary_operation.rs:56:5
|
LL | Struct { ..get_struct() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:59:5
+ --> $DIR/unnecessary_operation.rs:57:5
|
LL | Enum::Tuple(get_number());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:60:5
+ --> $DIR/unnecessary_operation.rs:58:5
|
LL | Enum::Struct { field: get_number() };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:61:5
+ --> $DIR/unnecessary_operation.rs:59:5
|
LL | 5 + get_number();
| ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:62:5
+ --> $DIR/unnecessary_operation.rs:60:5
|
LL | *&get_number();
| ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:63:5
+ --> $DIR/unnecessary_operation.rs:61:5
|
LL | &get_number();
| ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:64:5
+ --> $DIR/unnecessary_operation.rs:62:5
|
LL | (5, 6, get_number());
| ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;6;get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:65:5
+ --> $DIR/unnecessary_operation.rs:63:5
|
LL | get_number()..;
| ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:66:5
+ --> $DIR/unnecessary_operation.rs:64:5
|
LL | ..get_number();
| ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:67:5
+ --> $DIR/unnecessary_operation.rs:65:5
|
LL | 5..get_number();
| ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:68:5
+ --> $DIR/unnecessary_operation.rs:66:5
|
LL | [42, get_number()];
| ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:69:5
+ --> $DIR/unnecessary_operation.rs:67:5
|
LL | [42, 55][get_usize()];
| ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:70:5
+ --> $DIR/unnecessary_operation.rs:68:5
|
LL | (42, get_number()).1;
| ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:71:5
+ --> $DIR/unnecessary_operation.rs:69:5
|
LL | [get_number(); 55];
| ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:72:5
+ --> $DIR/unnecessary_operation.rs:70:5
|
LL | [42; 55][get_usize()];
| ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:73:5
+ --> $DIR/unnecessary_operation.rs:71:5
|
LL | / {
LL | | get_number()
@@ -111,7 +112,7 @@ LL | | };
| |______^ help: statement can be reduced to: `get_number();`
error: unnecessary operation
- --> $DIR/unnecessary_operation.rs:76:5
+ --> $DIR/unnecessary_operation.rs:74:5
|
LL | / FooString {
LL | | s: String::from("blah"),
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
index af12fd1d6..75cd63db8 100644
--- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::unnecessary_owned_empty_strings)]
fn ref_str_argument(_value: &str) {}
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
index a460b21af..2edc0bd86 100644
--- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::unnecessary_owned_empty_strings)]
fn ref_str_argument(_value: &str) {}
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
index 1eb198a86..58d925b10 100644
--- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
@@ -1,13 +1,14 @@
error: usage of `&String::new()` for a function expecting a `&str` argument
- --> $DIR/unnecessary_owned_empty_strings.rs:12:22
+ --> $DIR/unnecessary_owned_empty_strings.rs:10:22
|
LL | ref_str_argument(&String::new());
| ^^^^^^^^^^^^^^ help: try: `""`
|
= note: `-D clippy::unnecessary-owned-empty-strings` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_owned_empty_strings)]`
error: usage of `&String::from("")` for a function expecting a `&str` argument
- --> $DIR/unnecessary_owned_empty_strings.rs:16:22
+ --> $DIR/unnecessary_owned_empty_strings.rs:14:22
|
LL | ref_str_argument(&String::from(""));
| ^^^^^^^^^^^^^^^^^ help: try: `""`
diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs b/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs
index d858701ae..d9a7ad8e5 100644
--- a/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs
@@ -4,14 +4,19 @@
mod unsafe_items_invalid_comment {
// SAFETY:
const CONST: u32 = 0;
+ //~^ ERROR: constant item has unnecessary safety comment
// SAFETY:
static STATIC: u32 = 0;
+ //~^ ERROR: static item has unnecessary safety comment
// SAFETY:
struct Struct;
+ //~^ ERROR: struct has unnecessary safety comment
// SAFETY:
enum Enum {}
+ //~^ ERROR: enum has unnecessary safety comment
// SAFETY:
mod module {}
+ //~^ ERROR: module has unnecessary safety comment
}
mod unnecessary_from_macro {
@@ -40,12 +45,15 @@ mod unnecessary_from_macro {
fn unnecessary_on_stmt_and_expr() -> u32 {
// SAFETY: unnecessary
let num = 42;
+ //~^ ERROR: statement has unnecessary safety comment
// SAFETY: unnecessary
if num > 24 {}
+ //~^ ERROR: statement has unnecessary safety comment
// SAFETY: unnecessary
24
+ //~^ ERROR: expression has unnecessary safety comment
}
mod issue_10084 {
diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr
index 7b2af67d6..6d4ef6c30 100644
--- a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr
@@ -10,57 +10,58 @@ help: consider removing the safety comment
LL | // SAFETY:
| ^^^^^^^^^^
= note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
error: static item has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:8:5
+ --> $DIR/unnecessary_safety_comment.rs:9:5
|
LL | static STATIC: u32 = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:7:5
+ --> $DIR/unnecessary_safety_comment.rs:8:5
|
LL | // SAFETY:
| ^^^^^^^^^^
error: struct has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:10:5
+ --> $DIR/unnecessary_safety_comment.rs:12:5
|
LL | struct Struct;
| ^^^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:9:5
+ --> $DIR/unnecessary_safety_comment.rs:11:5
|
LL | // SAFETY:
| ^^^^^^^^^^
error: enum has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:12:5
+ --> $DIR/unnecessary_safety_comment.rs:15:5
|
LL | enum Enum {}
| ^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:11:5
+ --> $DIR/unnecessary_safety_comment.rs:14:5
|
LL | // SAFETY:
| ^^^^^^^^^^
error: module has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:14:5
+ --> $DIR/unnecessary_safety_comment.rs:18:5
|
LL | mod module {}
| ^^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:13:5
+ --> $DIR/unnecessary_safety_comment.rs:17:5
|
LL | // SAFETY:
| ^^^^^^^^^^
error: impl has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:33:13
+ --> $DIR/unnecessary_safety_comment.rs:38:13
|
LL | impl T for $t {}
| ^^^^^^^^^^^^^^^^
@@ -69,44 +70,44 @@ LL | with_safety_comment!(i32);
| ------------------------- in this macro invocation
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:32:13
+ --> $DIR/unnecessary_safety_comment.rs:37:13
|
LL | // Safety: unnecessary
| ^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `with_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
error: expression has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:48:5
+ --> $DIR/unnecessary_safety_comment.rs:55:5
|
LL | 24
| ^^
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:47:5
+ --> $DIR/unnecessary_safety_comment.rs:54:5
|
LL | // SAFETY: unnecessary
| ^^^^^^^^^^^^^^^^^^^^^^
error: statement has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:42:5
+ --> $DIR/unnecessary_safety_comment.rs:47:5
|
LL | let num = 42;
| ^^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:41:5
+ --> $DIR/unnecessary_safety_comment.rs:46:5
|
LL | // SAFETY: unnecessary
| ^^^^^^^^^^^^^^^^^^^^^^
error: statement has unnecessary safety comment
- --> $DIR/unnecessary_safety_comment.rs:45:5
+ --> $DIR/unnecessary_safety_comment.rs:51:5
|
LL | if num > 24 {}
| ^^^^^^^^^^^^^^
|
help: consider removing the safety comment
- --> $DIR/unnecessary_safety_comment.rs:44:5
+ --> $DIR/unnecessary_safety_comment.rs:50:5
|
LL | // SAFETY: unnecessary
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed b/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed
index 7fc978d3e..c265dcd24 100644
--- a/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unnecessary_self_imports)]
#![allow(unused_imports, dead_code)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_self_imports.rs b/src/tools/clippy/tests/ui/unnecessary_self_imports.rs
index 02424bc12..c3fcf7c95 100644
--- a/src/tools/clippy/tests/ui/unnecessary_self_imports.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_self_imports.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unnecessary_self_imports)]
#![allow(unused_imports, dead_code)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr b/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr
index db805eb36..4e50aaece 100644
--- a/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr
@@ -1,5 +1,5 @@
error: import ending with `::{self}`
- --> $DIR/unnecessary_self_imports.rs:6:1
+ --> $DIR/unnecessary_self_imports.rs:5:1
|
LL | use std::fs::{self as alias};
| ^^^^^^^^^--------------------
@@ -8,9 +8,10 @@ LL | use std::fs::{self as alias};
|
= note: this will slightly change semantics; any non-module items at the same path will also be imported
= note: `-D clippy::unnecessary-self-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_self_imports)]`
error: import ending with `::{self}`
- --> $DIR/unnecessary_self_imports.rs:8:1
+ --> $DIR/unnecessary_self_imports.rs:7:1
|
LL | use std::rc::{self};
| ^^^^^^^^^-----------
diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed b/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed
index 19380ad00..6b667e00c 100644
--- a/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::stable_sort_primitive, clippy::useless_vec)]
use std::cell::Ref;
diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.rs b/src/tools/clippy/tests/ui/unnecessary_sort_by.rs
index cea1b65b5..0ff20fb9e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_sort_by.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(clippy::stable_sort_primitive, clippy::useless_vec)]
use std::cell::Ref;
diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr b/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
index 89da5e7ea..9d54c8d50 100644
--- a/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
@@ -1,73 +1,74 @@
error: use Vec::sort here instead
- --> $DIR/unnecessary_sort_by.rs:14:5
+ --> $DIR/unnecessary_sort_by.rs:12:5
|
LL | vec.sort_by(|a, b| a.cmp(b));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort()`
|
= note: `-D clippy::unnecessary-sort-by` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]`
error: use Vec::sort here instead
- --> $DIR/unnecessary_sort_by.rs:15:5
+ --> $DIR/unnecessary_sort_by.rs:13:5
|
LL | vec.sort_unstable_by(|a, b| a.cmp(b));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable()`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:16:5
+ --> $DIR/unnecessary_sort_by.rs:14:5
|
LL | vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (a + 5).abs())`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:17:5
+ --> $DIR/unnecessary_sort_by.rs:15:5
|
LL | vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b)));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| id(-a))`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:20:5
+ --> $DIR/unnecessary_sort_by.rs:18:5
|
LL | vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()))`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:21:5
+ --> $DIR/unnecessary_sort_by.rs:19:5
|
LL | vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a)));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b)))`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:31:5
+ --> $DIR/unnecessary_sort_by.rs:29:5
|
LL | vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (***a).abs())`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:32:5
+ --> $DIR/unnecessary_sort_by.rs:30:5
|
LL | vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| (***a).abs())`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:91:9
+ --> $DIR/unnecessary_sort_by.rs:89:9
|
LL | args.sort_by(|a, b| a.name().cmp(&b.name()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|a| a.name())`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:92:9
+ --> $DIR/unnecessary_sort_by.rs:90:9
|
LL | args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|a| a.name())`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:94:9
+ --> $DIR/unnecessary_sort_by.rs:92:9
|
LL | args.sort_by(|a, b| b.name().cmp(&a.name()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|b| std::cmp::Reverse(b.name()))`
error: use Vec::sort_by_key here instead
- --> $DIR/unnecessary_sort_by.rs:95:9
+ --> $DIR/unnecessary_sort_by.rs:93:9
|
LL | args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name()))`
diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed
index eae1271d1..f3cf65da2 100644
--- a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed
@@ -1,6 +1,4 @@
-//@run-rustfix
-
-#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)]
+#![allow(clippy::non_canonical_clone_impl, unused)]
#![warn(clippy::unnecessary_struct_initialization)]
struct S {
diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs
index 4abd560f8..bd5302f9d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs
@@ -1,6 +1,4 @@
-//@run-rustfix
-
-#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)]
+#![allow(clippy::non_canonical_clone_impl, unused)]
#![warn(clippy::unnecessary_struct_initialization)]
struct S {
diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr
index ca4970577..d8e0ce6cc 100644
--- a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.stderr
@@ -1,31 +1,32 @@
error: unnecessary struct building
- --> $DIR/unnecessary_struct_initialization.rs:34:9
+ --> $DIR/unnecessary_struct_initialization.rs:32:9
|
LL | Self { ..*self }
| ^^^^^^^^^^^^^^^^ help: replace with: `*self`
|
= note: `-D clippy::unnecessary-struct-initialization` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_struct_initialization)]`
error: unnecessary struct building
- --> $DIR/unnecessary_struct_initialization.rs:41:17
+ --> $DIR/unnecessary_struct_initialization.rs:39:17
|
LL | let mut b = S { ..a };
| ^^^^^^^^^ help: replace with: `a`
error: unnecessary struct building
- --> $DIR/unnecessary_struct_initialization.rs:44:18
+ --> $DIR/unnecessary_struct_initialization.rs:42:18
|
LL | let c = &mut S { ..b };
| ^^^^^^^^^ help: replace with: `b`
error: unnecessary struct building
- --> $DIR/unnecessary_struct_initialization.rs:52:14
+ --> $DIR/unnecessary_struct_initialization.rs:50:14
|
LL | let g = &S { ..f };
| ^^^^^^^^^ help: replace with: `f`
error: unnecessary struct building
- --> $DIR/unnecessary_struct_initialization.rs:55:18
+ --> $DIR/unnecessary_struct_initialization.rs:53:18
|
LL | let h = &mut S {
| __________________^
@@ -34,7 +35,7 @@ LL | | };
| |_____^ help: replace with: `*Box::new(S { f: String::from("foo") })`
error: unnecessary struct building
- --> $DIR/unnecessary_struct_initialization.rs:74:18
+ --> $DIR/unnecessary_struct_initialization.rs:72:18
|
LL | let p = &mut T {
| __________________^
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index cb7562351..67faabc53 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -1,6 +1,4 @@
-//@run-rustfix
-
-#![allow(clippy::needless_borrow, clippy::ptr_arg)]
+#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index f82ddb2d2..99f913642 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -1,6 +1,4 @@
-//@run-rustfix
-
-#![allow(clippy::needless_borrow, clippy::ptr_arg)]
+#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index 4918fe355..d8971b51d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -1,482 +1,484 @@
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:150:64
+ --> $DIR/unnecessary_to_owned.rs:148:64
|
LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/unnecessary_to_owned.rs:150:20
+ --> $DIR/unnecessary_to_owned.rs:148:20
|
LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::redundant-clone` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:151:40
+ --> $DIR/unnecessary_to_owned.rs:149:40
|
LL | require_os_str(&OsString::from("x").to_os_string());
| ^^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/unnecessary_to_owned.rs:151:21
+ --> $DIR/unnecessary_to_owned.rs:149:21
|
LL | require_os_str(&OsString::from("x").to_os_string());
| ^^^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:152:48
+ --> $DIR/unnecessary_to_owned.rs:150:48
|
LL | require_path(&std::path::PathBuf::from("x").to_path_buf());
| ^^^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/unnecessary_to_owned.rs:152:19
+ --> $DIR/unnecessary_to_owned.rs:150:19
|
LL | require_path(&std::path::PathBuf::from("x").to_path_buf());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:153:35
+ --> $DIR/unnecessary_to_owned.rs:151:35
|
LL | require_str(&String::from("x").to_string());
| ^^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/unnecessary_to_owned.rs:153:18
+ --> $DIR/unnecessary_to_owned.rs:151:18
|
LL | require_str(&String::from("x").to_string());
| ^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:154:39
+ --> $DIR/unnecessary_to_owned.rs:152:39
|
LL | require_slice(&[String::from("x")].to_owned());
| ^^^^^^^^^^^ help: remove this
|
note: this value is dropped without further use
- --> $DIR/unnecessary_to_owned.rs:154:20
+ --> $DIR/unnecessary_to_owned.rs:152:20
|
LL | require_slice(&[String::from("x")].to_owned());
| ^^^^^^^^^^^^^^^^^^^
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:59:36
+ --> $DIR/unnecessary_to_owned.rs:57:36
|
LL | require_c_str(&Cow::from(c_str).into_owned());
| ^^^^^^^^^^^^^ help: remove this
|
= note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:60:19
+ --> $DIR/unnecessary_to_owned.rs:58:19
|
LL | require_c_str(&c_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_os_string`
- --> $DIR/unnecessary_to_owned.rs:62:20
+ --> $DIR/unnecessary_to_owned.rs:60:20
|
LL | require_os_str(&os_str.to_os_string());
| ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:63:38
+ --> $DIR/unnecessary_to_owned.rs:61:38
|
LL | require_os_str(&Cow::from(os_str).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:64:20
+ --> $DIR/unnecessary_to_owned.rs:62:20
|
LL | require_os_str(&os_str.to_owned());
| ^^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_path_buf`
- --> $DIR/unnecessary_to_owned.rs:66:18
+ --> $DIR/unnecessary_to_owned.rs:64:18
|
LL | require_path(&path.to_path_buf());
| ^^^^^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:67:34
+ --> $DIR/unnecessary_to_owned.rs:65:34
|
LL | require_path(&Cow::from(path).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:68:18
+ --> $DIR/unnecessary_to_owned.rs:66:18
|
LL | require_path(&path.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:70:17
+ --> $DIR/unnecessary_to_owned.rs:68:17
|
LL | require_str(&s.to_string());
| ^^^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:71:30
+ --> $DIR/unnecessary_to_owned.rs:69:30
|
LL | require_str(&Cow::from(s).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:72:17
+ --> $DIR/unnecessary_to_owned.rs:70:17
|
LL | require_str(&s.to_owned());
| ^^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:73:17
+ --> $DIR/unnecessary_to_owned.rs:71:17
|
LL | require_str(&x_ref.to_string());
| ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:75:19
+ --> $DIR/unnecessary_to_owned.rs:73:19
|
LL | require_slice(&slice.to_vec());
| ^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:76:36
+ --> $DIR/unnecessary_to_owned.rs:74:36
|
LL | require_slice(&Cow::from(slice).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:77:19
+ --> $DIR/unnecessary_to_owned.rs:75:19
|
LL | require_slice(&array.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:78:19
+ --> $DIR/unnecessary_to_owned.rs:76:19
|
LL | require_slice(&array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:79:19
+ --> $DIR/unnecessary_to_owned.rs:77:19
|
LL | require_slice(&slice.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:82:42
+ --> $DIR/unnecessary_to_owned.rs:80:42
|
LL | require_x(&Cow::<X>::Owned(x.clone()).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:85:25
+ --> $DIR/unnecessary_to_owned.rs:83:25
|
LL | require_deref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:86:26
+ --> $DIR/unnecessary_to_owned.rs:84:26
|
LL | require_deref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:87:24
+ --> $DIR/unnecessary_to_owned.rs:85:24
|
LL | require_deref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:88:23
+ --> $DIR/unnecessary_to_owned.rs:86:23
|
LL | require_deref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:89:25
+ --> $DIR/unnecessary_to_owned.rs:87:25
|
LL | require_deref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:91:30
+ --> $DIR/unnecessary_to_owned.rs:89:30
|
LL | require_impl_deref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:92:31
+ --> $DIR/unnecessary_to_owned.rs:90:31
|
LL | require_impl_deref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:93:29
+ --> $DIR/unnecessary_to_owned.rs:91:29
|
LL | require_impl_deref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:94:28
+ --> $DIR/unnecessary_to_owned.rs:92:28
|
LL | require_impl_deref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:95:30
+ --> $DIR/unnecessary_to_owned.rs:93:30
|
LL | require_impl_deref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:97:29
+ --> $DIR/unnecessary_to_owned.rs:95:29
|
LL | require_deref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:97:43
+ --> $DIR/unnecessary_to_owned.rs:95:43
|
LL | require_deref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:98:29
+ --> $DIR/unnecessary_to_owned.rs:96:29
|
LL | require_deref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:98:47
+ --> $DIR/unnecessary_to_owned.rs:96:47
|
LL | require_deref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:100:26
+ --> $DIR/unnecessary_to_owned.rs:98:26
|
LL | require_as_ref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:101:27
+ --> $DIR/unnecessary_to_owned.rs:99:27
|
LL | require_as_ref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:102:25
+ --> $DIR/unnecessary_to_owned.rs:100:25
|
LL | require_as_ref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:103:24
+ --> $DIR/unnecessary_to_owned.rs:101:24
|
LL | require_as_ref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:104:24
+ --> $DIR/unnecessary_to_owned.rs:102:24
|
LL | require_as_ref_str(x.to_owned());
| ^^^^^^^^^^^^ help: use: `&x`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:105:26
+ --> $DIR/unnecessary_to_owned.rs:103:26
|
LL | require_as_ref_slice(array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:106:26
+ --> $DIR/unnecessary_to_owned.rs:104:26
|
LL | require_as_ref_slice(array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:107:26
+ --> $DIR/unnecessary_to_owned.rs:105:26
|
LL | require_as_ref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:109:31
+ --> $DIR/unnecessary_to_owned.rs:107:31
|
LL | require_impl_as_ref_c_str(c_str.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `c_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:110:32
+ --> $DIR/unnecessary_to_owned.rs:108:32
|
LL | require_impl_as_ref_os_str(os_str.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `os_str`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:111:30
+ --> $DIR/unnecessary_to_owned.rs:109:30
|
LL | require_impl_as_ref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:112:29
+ --> $DIR/unnecessary_to_owned.rs:110:29
|
LL | require_impl_as_ref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:113:29
+ --> $DIR/unnecessary_to_owned.rs:111:29
|
LL | require_impl_as_ref_str(x.to_owned());
| ^^^^^^^^^^^^ help: use: `&x`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:114:31
+ --> $DIR/unnecessary_to_owned.rs:112:31
|
LL | require_impl_as_ref_slice(array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:115:31
+ --> $DIR/unnecessary_to_owned.rs:113:31
|
LL | require_impl_as_ref_slice(array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:116:31
+ --> $DIR/unnecessary_to_owned.rs:114:31
|
LL | require_impl_as_ref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:118:30
+ --> $DIR/unnecessary_to_owned.rs:116:30
|
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:118:44
+ --> $DIR/unnecessary_to_owned.rs:116:44
|
LL | require_as_ref_str_slice(s.to_owned(), array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:119:30
+ --> $DIR/unnecessary_to_owned.rs:117:30
|
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:119:44
+ --> $DIR/unnecessary_to_owned.rs:117:44
|
LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:120:30
+ --> $DIR/unnecessary_to_owned.rs:118:30
|
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:120:44
+ --> $DIR/unnecessary_to_owned.rs:118:44
|
LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:121:30
+ --> $DIR/unnecessary_to_owned.rs:119:30
|
LL | require_as_ref_slice_str(array.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:121:48
+ --> $DIR/unnecessary_to_owned.rs:119:48
|
LL | require_as_ref_slice_str(array.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:122:30
+ --> $DIR/unnecessary_to_owned.rs:120:30
|
LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:122:52
+ --> $DIR/unnecessary_to_owned.rs:120:52
|
LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:123:30
+ --> $DIR/unnecessary_to_owned.rs:121:30
|
LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:123:48
+ --> $DIR/unnecessary_to_owned.rs:121:48
|
LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:125:20
+ --> $DIR/unnecessary_to_owned.rs:123:20
|
LL | let _ = x.join(&x_ref.to_string());
| ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:127:13
+ --> $DIR/unnecessary_to_owned.rs:125:13
|
LL | let _ = slice.to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:128:13
+ --> $DIR/unnecessary_to_owned.rs:126:13
|
LL | let _ = slice.to_owned().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:129:13
+ --> $DIR/unnecessary_to_owned.rs:127:13
|
LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:130:13
+ --> $DIR/unnecessary_to_owned.rs:128:13
|
LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:132:13
+ --> $DIR/unnecessary_to_owned.rs:130:13
|
LL | let _ = IntoIterator::into_iter(slice.to_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:133:13
+ --> $DIR/unnecessary_to_owned.rs:131:13
|
LL | let _ = IntoIterator::into_iter(slice.to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:134:13
+ --> $DIR/unnecessary_to_owned.rs:132:13
|
LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:135:13
+ --> $DIR/unnecessary_to_owned.rs:133:13
|
LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:197:14
+ --> $DIR/unnecessary_to_owned.rs:195:14
|
LL | for t in file_types.to_vec() {
| ^^^^^^^^^^^^^^^^^^^
@@ -492,25 +494,25 @@ LL + let path = match get_file_path(t) {
|
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:220:14
+ --> $DIR/unnecessary_to_owned.rs:218:14
|
LL | let _ = &["x"][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:225:14
+ --> $DIR/unnecessary_to_owned.rs:223:14
|
LL | let _ = &["x"][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:272:24
+ --> $DIR/unnecessary_to_owned.rs:270:24
|
LL | Box::new(build(y.to_string()))
| ^^^^^^^^^^^^^ help: use: `y`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:380:12
+ --> $DIR/unnecessary_to_owned.rs:378:12
|
LL | id("abc".to_string())
| ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs
index 2d55dc664..373b18470 100644
--- a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![allow(clippy::let_unit_value)]
#![warn(clippy::unnecessary_safety_doc)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr
index b0f20fdac..817eb3e26 100644
--- a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr
@@ -5,6 +5,7 @@ LL | pub fn apocalypse(universe: &mut ()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unnecessary-safety-doc` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_doc)]`
error: safe function's docs have unnecessary `# Safety` section
--> $DIR/unnecessary_unsafety_doc.rs:45:5
diff --git a/src/tools/clippy/tests/ui/unnecessary_wraps.rs b/src/tools/clippy/tests/ui/unnecessary_wraps.rs
index 63648ef58..200aefff1 100644
--- a/src/tools/clippy/tests/ui/unnecessary_wraps.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_wraps.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![warn(clippy::unnecessary_wraps)]
#![allow(clippy::no_effect)]
#![allow(clippy::needless_return)]
@@ -6,6 +7,8 @@
// should be linted
fn func1(a: bool, b: bool) -> Option<i32> {
+ //~^ ERROR: this function's return value is unnecessarily wrapped by `Option`
+ //~| NOTE: `-D clippy::unnecessary-wraps` implied by `-D warnings`
if a && b {
return Some(42);
}
@@ -19,6 +22,7 @@ fn func1(a: bool, b: bool) -> Option<i32> {
// should be linted
fn func2(a: bool, b: bool) -> Option<i32> {
+ //~^ ERROR: this function's return value is unnecessarily wrapped by `Option`
if a && b {
return Some(10);
}
@@ -37,6 +41,7 @@ fn func4(a: bool) -> Option<i32> {
// should be linted
fn func5() -> Option<i32> {
+ //~^ ERROR: this function's return value is unnecessarily wrapped by `Option`
Some(1)
}
@@ -47,6 +52,7 @@ fn func6() -> Option<i32> {
// should be linted
fn func7() -> Result<i32, ()> {
+ //~^ ERROR: this function's return value is unnecessarily wrapped by `Result`
Ok(1)
}
@@ -75,6 +81,7 @@ impl A {
// should be linted
fn func12() -> Option<i32> {
+ //~^ ERROR: this function's return value is unnecessarily wrapped by `Option`
Some(1)
}
}
@@ -102,6 +109,7 @@ fn issue_6384(s: &str) -> Option<&str> {
// should be linted
fn issue_6640_1(a: bool, b: bool) -> Option<()> {
+ //~^ ERROR: this function's return value is unnecessary
if a && b {
return Some(());
}
@@ -115,6 +123,7 @@ fn issue_6640_1(a: bool, b: bool) -> Option<()> {
// should be linted
fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {
+ //~^ ERROR: this function's return value is unnecessary
if a && b {
return Ok(());
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
index a6a0b22cf..20d3e070e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
@@ -1,16 +1,17 @@
error: this function's return value is unnecessarily wrapped by `Option`
- --> $DIR/unnecessary_wraps.rs:8:1
+ --> $DIR/unnecessary_wraps.rs:9:1
|
LL | / fn func1(a: bool, b: bool) -> Option<i32> {
+LL | |
+LL | |
LL | | if a && b {
-LL | | return Some(42);
-LL | | }
... |
LL | | }
LL | | }
| |_^
|
= note: `-D clippy::unnecessary-wraps` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnecessary_wraps)]`
help: remove `Option` from the return type...
|
LL | fn func1(a: bool, b: bool) -> i32 {
@@ -27,9 +28,10 @@ LL ~ return 1337;
|
error: this function's return value is unnecessarily wrapped by `Option`
- --> $DIR/unnecessary_wraps.rs:21:1
+ --> $DIR/unnecessary_wraps.rs:24:1
|
LL | / fn func2(a: bool, b: bool) -> Option<i32> {
+LL | |
LL | | if a && b {
LL | | return Some(10);
LL | | }
@@ -49,9 +51,10 @@ LL ~ if a { 20 } else { 30 }
|
error: this function's return value is unnecessarily wrapped by `Option`
- --> $DIR/unnecessary_wraps.rs:39:1
+ --> $DIR/unnecessary_wraps.rs:43:1
|
LL | / fn func5() -> Option<i32> {
+LL | |
LL | | Some(1)
LL | | }
| |_^
@@ -66,9 +69,10 @@ LL | 1
|
error: this function's return value is unnecessarily wrapped by `Result`
- --> $DIR/unnecessary_wraps.rs:49:1
+ --> $DIR/unnecessary_wraps.rs:54:1
|
LL | / fn func7() -> Result<i32, ()> {
+LL | |
LL | | Ok(1)
LL | | }
| |_^
@@ -83,9 +87,10 @@ LL | 1
|
error: this function's return value is unnecessarily wrapped by `Option`
- --> $DIR/unnecessary_wraps.rs:77:5
+ --> $DIR/unnecessary_wraps.rs:83:5
|
LL | / fn func12() -> Option<i32> {
+LL | |
LL | | Some(1)
LL | | }
| |_____^
@@ -100,12 +105,12 @@ LL | 1
|
error: this function's return value is unnecessary
- --> $DIR/unnecessary_wraps.rs:104:1
+ --> $DIR/unnecessary_wraps.rs:111:1
|
LL | / fn issue_6640_1(a: bool, b: bool) -> Option<()> {
+LL | |
LL | | if a && b {
LL | | return Some(());
-LL | | }
... |
LL | | }
LL | | }
@@ -127,12 +132,12 @@ LL ~ return ;
|
error: this function's return value is unnecessary
- --> $DIR/unnecessary_wraps.rs:117:1
+ --> $DIR/unnecessary_wraps.rs:125:1
|
LL | / fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {
+LL | |
LL | | if a && b {
LL | | return Ok(());
-LL | | }
... |
LL | | }
LL | | }
diff --git a/src/tools/clippy/tests/ui/unneeded_field_pattern.rs b/src/tools/clippy/tests/ui/unneeded_field_pattern.rs
index 48ae1cf66..0dc21f4ce 100644
--- a/src/tools/clippy/tests/ui/unneeded_field_pattern.rs
+++ b/src/tools/clippy/tests/ui/unneeded_field_pattern.rs
@@ -1,4 +1,4 @@
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![warn(clippy::unneeded_field_pattern)]
#![allow(dead_code, unused)]
diff --git a/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr b/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr
index 3f1568498..68b433df8 100644
--- a/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr
+++ b/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr
@@ -6,6 +6,7 @@ LL | Foo { a: _, b: 0, .. } => {},
|
= help: try with `Foo { b: 0, .. }`
= note: `-D clippy::unneeded-field-pattern` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unneeded_field_pattern)]`
error: all the struct fields are matched to a wildcard pattern, consider using `..`
--> $DIR/unneeded_field_pattern.rs:20:9
diff --git a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed
index 2eeba509e..cbf91ed49 100644
--- a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed
+++ b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(stmt_expr_attributes)]
#![deny(clippy::unneeded_wildcard_pattern)]
#![allow(clippy::needless_if)]
diff --git a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs
index 5416cfaa5..10df2b93d 100644
--- a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs
+++ b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macros.rs:proc-macro
+//@aux-build:proc_macros.rs
#![feature(stmt_expr_attributes)]
#![deny(clippy::unneeded_wildcard_pattern)]
#![allow(clippy::needless_if)]
diff --git a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.stderr b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.stderr
index ffbdc0495..f2880a8e6 100644
--- a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.stderr
+++ b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.stderr
@@ -1,89 +1,89 @@
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:13:18
+ --> $DIR/unneeded_wildcard_pattern.rs:12:18
|
LL | if let (0, .., _) = t {};
| ^^^ help: remove it
|
note: the lint level is defined here
- --> $DIR/unneeded_wildcard_pattern.rs:4:9
+ --> $DIR/unneeded_wildcard_pattern.rs:3:9
|
LL | #![deny(clippy::unneeded_wildcard_pattern)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:14:16
+ --> $DIR/unneeded_wildcard_pattern.rs:13:16
|
LL | if let (0, _, ..) = t {};
| ^^^ help: remove it
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:15:13
+ --> $DIR/unneeded_wildcard_pattern.rs:14:13
|
LL | if let (_, .., 0) = t {};
| ^^^ help: remove it
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:16:15
+ --> $DIR/unneeded_wildcard_pattern.rs:15:15
|
LL | if let (.., _, 0) = t {};
| ^^^ help: remove it
error: these patterns are unneeded as the `..` pattern can match those elements
- --> $DIR/unneeded_wildcard_pattern.rs:17:16
+ --> $DIR/unneeded_wildcard_pattern.rs:16:16
|
LL | if let (0, _, _, ..) = t {};
| ^^^^^^ help: remove them
error: these patterns are unneeded as the `..` pattern can match those elements
- --> $DIR/unneeded_wildcard_pattern.rs:18:18
+ --> $DIR/unneeded_wildcard_pattern.rs:17:18
|
LL | if let (0, .., _, _) = t {};
| ^^^^^^ help: remove them
error: these patterns are unneeded as the `..` pattern can match those elements
- --> $DIR/unneeded_wildcard_pattern.rs:27:22
+ --> $DIR/unneeded_wildcard_pattern.rs:26:22
|
LL | if let (0, .., _, _,) = t {};
| ^^^^^^ help: remove them
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:34:19
+ --> $DIR/unneeded_wildcard_pattern.rs:33:19
|
LL | if let S(0, .., _) = s {};
| ^^^ help: remove it
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:35:17
+ --> $DIR/unneeded_wildcard_pattern.rs:34:17
|
LL | if let S(0, _, ..) = s {};
| ^^^ help: remove it
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:36:14
+ --> $DIR/unneeded_wildcard_pattern.rs:35:14
|
LL | if let S(_, .., 0) = s {};
| ^^^ help: remove it
error: this pattern is unneeded as the `..` pattern can match that element
- --> $DIR/unneeded_wildcard_pattern.rs:37:16
+ --> $DIR/unneeded_wildcard_pattern.rs:36:16
|
LL | if let S(.., _, 0) = s {};
| ^^^ help: remove it
error: these patterns are unneeded as the `..` pattern can match those elements
- --> $DIR/unneeded_wildcard_pattern.rs:38:17
+ --> $DIR/unneeded_wildcard_pattern.rs:37:17
|
LL | if let S(0, _, _, ..) = s {};
| ^^^^^^ help: remove them
error: these patterns are unneeded as the `..` pattern can match those elements
- --> $DIR/unneeded_wildcard_pattern.rs:39:19
+ --> $DIR/unneeded_wildcard_pattern.rs:38:19
|
LL | if let S(0, .., _, _) = s {};
| ^^^^^^ help: remove them
error: these patterns are unneeded as the `..` pattern can match those elements
- --> $DIR/unneeded_wildcard_pattern.rs:48:23
+ --> $DIR/unneeded_wildcard_pattern.rs:47:23
|
LL | if let S(0, .., _, _,) = s {};
| ^^^^^^ help: remove them
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
index 738045595..53ec556d1 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(box_patterns)]
#![warn(clippy::unnested_or_patterns)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.rs b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
index 9e0e7b5de..e5e378e92 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.rs
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(box_patterns)]
#![warn(clippy::unnested_or_patterns)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
index b997e4ce8..98ca7e373 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
@@ -1,17 +1,18 @@
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:18:12
+ --> $DIR/unnested_or_patterns.rs:16:12
|
LL | if let box 0 | box 2 = Box::new(0) {}
| ^^^^^^^^^^^^^
|
= note: `-D clippy::unnested-or-patterns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]`
help: nest the patterns
|
LL | if let box (0 | 2) = Box::new(0) {}
| ~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:19:12
+ --> $DIR/unnested_or_patterns.rs:17:12
|
LL | if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
| ~~~~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:21:12
+ --> $DIR/unnested_or_patterns.rs:19:12
|
LL | if let Some(1) | C0 | Some(2) = None {}
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +34,7 @@ LL | if let Some(1 | 2) | C0 = None {}
| ~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:22:12
+ --> $DIR/unnested_or_patterns.rs:20:12
|
LL | if let &mut 0 | &mut 2 = &mut 0 {}
| ^^^^^^^^^^^^^^^
@@ -44,7 +45,7 @@ LL | if let &mut (0 | 2) = &mut 0 {}
| ~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:23:12
+ --> $DIR/unnested_or_patterns.rs:21:12
|
LL | if let x @ 0 | x @ 2 = 0 {}
| ^^^^^^^^^^^^^
@@ -55,7 +56,7 @@ LL | if let x @ (0 | 2) = 0 {}
| ~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:24:12
+ --> $DIR/unnested_or_patterns.rs:22:12
|
LL | if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -66,7 +67,7 @@ LL | if let (0, 1 | 2 | 3) = (0, 0) {}
| ~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:25:12
+ --> $DIR/unnested_or_patterns.rs:23:12
|
LL | if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -77,7 +78,7 @@ LL | if let (1 | 2 | 3, 0) = (0, 0) {}
| ~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:26:12
+ --> $DIR/unnested_or_patterns.rs:24:12
|
LL | if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +89,7 @@ LL | if let (x, ..) | (x, 1 | 2) = (0, 1) {}
| ~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:27:12
+ --> $DIR/unnested_or_patterns.rs:25:12
|
LL | if let [0] | [1] = [0] {}
| ^^^^^^^^^
@@ -99,7 +100,7 @@ LL | if let [0 | 1] = [0] {}
| ~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:28:12
+ --> $DIR/unnested_or_patterns.rs:26:12
|
LL | if let [x, 0] | [x, 1] = [0, 1] {}
| ^^^^^^^^^^^^^^^
@@ -110,7 +111,7 @@ LL | if let [x, 0 | 1] = [0, 1] {}
| ~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:29:12
+ --> $DIR/unnested_or_patterns.rs:27:12
|
LL | if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +122,7 @@ LL | if let [x, 0 | 1 | 2] = [0, 1] {}
| ~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:30:12
+ --> $DIR/unnested_or_patterns.rs:28:12
|
LL | if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,7 +133,7 @@ LL | if let [x, ..] | [x, 1 | 2] = [0, 1] {}
| ~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:32:12
+ --> $DIR/unnested_or_patterns.rs:30:12
|
LL | if let TS(0, x) | TS(1, x) = TS(0, 0) {}
| ^^^^^^^^^^^^^^^^^^^
@@ -143,7 +144,7 @@ LL | if let TS(0 | 1, x) = TS(0, 0) {}
| ~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:33:12
+ --> $DIR/unnested_or_patterns.rs:31:12
|
LL | if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,7 +155,7 @@ LL | if let TS(1 | 2 | 3, 0) = TS(0, 0) {}
| ~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:34:12
+ --> $DIR/unnested_or_patterns.rs:32:12
|
LL | if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +166,7 @@ LL | if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
| ~~~~~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:39:12
+ --> $DIR/unnested_or_patterns.rs:37:12
|
LL | if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -176,7 +177,7 @@ LL | if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
| ~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:50:12
+ --> $DIR/unnested_or_patterns.rs:48:12
|
LL | if let [1] | [53] = [0] {}
| ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed
index 11dc34378..b2a4e83da 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(box_patterns)]
#![warn(clippy::unnested_or_patterns)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.rs b/src/tools/clippy/tests/ui/unnested_or_patterns2.rs
index b25560827..58435f899 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns2.rs
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(box_patterns)]
#![warn(clippy::unnested_or_patterns)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr
index 76e890b3a..182ae00de 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr
@@ -1,17 +1,18 @@
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:14:12
+ --> $DIR/unnested_or_patterns2.rs:12:12
|
LL | if let Some(Some(0)) | Some(Some(1)) = None {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unnested-or-patterns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]`
help: nest the patterns
|
LL | if let Some(Some(0 | 1)) = None {}
| ~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:15:12
+ --> $DIR/unnested_or_patterns2.rs:13:12
|
LL | if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +23,7 @@ LL | if let Some(Some(0 | 1 | 2)) = None {}
| ~~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:16:12
+ --> $DIR/unnested_or_patterns2.rs:14:12
|
LL | if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +34,7 @@ LL | if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:17:12
+ --> $DIR/unnested_or_patterns2.rs:15:12
|
LL | if let Some(Some(0) | Some(1 | 2)) = None {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +45,7 @@ LL | if let Some(Some(0 | 1 | 2)) = None {}
| ~~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:18:12
+ --> $DIR/unnested_or_patterns2.rs:16:12
|
LL | if let ((0,),) | ((1,) | (2,),) = ((0,),) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +56,7 @@ LL | if let ((0 | 1 | 2,),) = ((0,),) {}
| ~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:19:12
+ --> $DIR/unnested_or_patterns2.rs:17:12
|
LL | if let 0 | (1 | 2) = 0 {}
| ^^^^^^^^^^^
@@ -66,7 +67,7 @@ LL | if let 0 | 1 | 2 = 0 {}
| ~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:20:12
+ --> $DIR/unnested_or_patterns2.rs:18:12
|
LL | if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -77,7 +78,7 @@ LL | if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
| ~~~~~~~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns2.rs:21:12
+ --> $DIR/unnested_or_patterns2.rs:19:12
|
LL | if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unreadable_literal.fixed b/src/tools/clippy/tests/ui/unreadable_literal.fixed
index f5e87648a..6d8c719ee 100644
--- a/src/tools/clippy/tests/ui/unreadable_literal.fixed
+++ b/src/tools/clippy/tests/ui/unreadable_literal.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::unreadable_literal)]
#![allow(unused_tuple_struct_fields)]
diff --git a/src/tools/clippy/tests/ui/unreadable_literal.rs b/src/tools/clippy/tests/ui/unreadable_literal.rs
index 426bdf7d7..42ca773c3 100644
--- a/src/tools/clippy/tests/ui/unreadable_literal.rs
+++ b/src/tools/clippy/tests/ui/unreadable_literal.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::unreadable_literal)]
#![allow(unused_tuple_struct_fields)]
diff --git a/src/tools/clippy/tests/ui/unreadable_literal.stderr b/src/tools/clippy/tests/ui/unreadable_literal.stderr
index 450121b1c..d7a3377ec 100644
--- a/src/tools/clippy/tests/ui/unreadable_literal.stderr
+++ b/src/tools/clippy/tests/ui/unreadable_literal.stderr
@@ -1,61 +1,62 @@
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:34:17
+ --> $DIR/unreadable_literal.rs:32:17
|
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
| ^^^^^^^^^^^^ help: consider: `0b11_0110_i64`
|
= note: `-D clippy::unreadable-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unreadable_literal)]`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:34:31
+ --> $DIR/unreadable_literal.rs:32:31
|
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
| ^^^^^^^^^^^^^^^^ help: consider: `0x1234_5678_usize`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:34:49
+ --> $DIR/unreadable_literal.rs:32:49
|
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
| ^^^^^^^^^^ help: consider: `123_456_f32`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:34:61
+ --> $DIR/unreadable_literal.rs:32:61
|
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
| ^^^^^^^^^^^^ help: consider: `1.234_567_f32`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:36:20
+ --> $DIR/unreadable_literal.rs:34:20
|
LL | let _bad_sci = 1.123456e1;
| ^^^^^^^^^^ help: consider: `1.123_456e1`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:38:18
+ --> $DIR/unreadable_literal.rs:36:18
|
LL | let _fail1 = 0xabcdef;
| ^^^^^^^^ help: consider: `0x00ab_cdef`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:39:23
+ --> $DIR/unreadable_literal.rs:37:23
|
LL | let _fail2: u32 = 0xBAFEBAFE;
| ^^^^^^^^^^ help: consider: `0xBAFE_BAFE`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:40:18
+ --> $DIR/unreadable_literal.rs:38:18
|
LL | let _fail3 = 0xabcdeff;
| ^^^^^^^^^ help: consider: `0x0abc_deff`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:41:24
+ --> $DIR/unreadable_literal.rs:39:24
|
LL | let _fail4: i128 = 0xabcabcabcabcabcabc;
| ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc`
error: long literal lacking separators
- --> $DIR/unreadable_literal.rs:42:18
+ --> $DIR/unreadable_literal.rs:40:18
|
LL | let _fail5 = 1.100300400;
| ^^^^^^^^^^^ help: consider: `1.100_300_400`
diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
index bafca9191..70dcaa3af 100644
--- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
+++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
@@ -6,6 +6,7 @@ extern crate serde;
use serde::Deserialize;
#[derive(Deserialize)]
+//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct A;
impl A {
pub unsafe fn new(_a: i32, _b: i32) -> Self {
@@ -14,12 +15,14 @@ impl A {
}
#[derive(Deserialize)]
+//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct B;
impl B {
pub unsafe fn unsafe_method(&self) {}
}
#[derive(Deserialize)]
+//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct C;
impl C {
pub fn unsafe_block(&self) {
@@ -28,6 +31,7 @@ impl C {
}
#[derive(Deserialize)]
+//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct D;
impl D {
pub fn inner_unsafe_fn(&self) {
diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
index 8aaae2d7f..d6fb82398 100644
--- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
+++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
@@ -6,10 +6,11 @@ LL | #[derive(Deserialize)]
|
= help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html
= note: `-D clippy::unsafe-derive-deserialize` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unsafe_derive_deserialize)]`
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
- --> $DIR/unsafe_derive_deserialize.rs:16:10
+ --> $DIR/unsafe_derive_deserialize.rs:17:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
@@ -18,7 +19,7 @@ LL | #[derive(Deserialize)]
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
- --> $DIR/unsafe_derive_deserialize.rs:22:10
+ --> $DIR/unsafe_derive_deserialize.rs:24:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
@@ -27,7 +28,7 @@ LL | #[derive(Deserialize)]
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
- --> $DIR/unsafe_derive_deserialize.rs:30:10
+ --> $DIR/unsafe_derive_deserialize.rs:33:10
|
LL | #[derive(Deserialize)]
| ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
index 04f6ef29a..e0e0ded14 100644
--- a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
@@ -3,8 +3,11 @@
#![warn(clippy::unsafe_removed_from_name)]
use std::cell::UnsafeCell as TotallySafeCell;
+//~^ ERROR: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCell`
+//~| NOTE: `-D clippy::unsafe-removed-from-name` implied by `-D warnings`
use std::cell::UnsafeCell as TotallySafeCellAgain;
+//~^ ERROR: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain
// Shouldn't error
use std::cell::RefCell as ProbablyNotUnsafe;
@@ -23,9 +26,12 @@ mod mod_with_some_unsafe_things {
}
use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety;
+//~^ ERROR: removed `unsafe` from the name of `Unsafe` in use as `LieAboutModSafety`
// merged imports
use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B};
+//~^ ERROR: removed `unsafe` from the name of `Unsafe` in use as `A`
+//~| ERROR: removed `unsafe` from the name of `Unsafe` in use as `B`
// Shouldn't error
use mod_with_some_unsafe_things::Safe as IPromiseItsSafeThisTime;
diff --git a/src/tools/clippy/tests/ui/unsafe_removed_from_name.stderr b/src/tools/clippy/tests/ui/unsafe_removed_from_name.stderr
index 090d917bd..261c7837a 100644
--- a/src/tools/clippy/tests/ui/unsafe_removed_from_name.stderr
+++ b/src/tools/clippy/tests/ui/unsafe_removed_from_name.stderr
@@ -5,27 +5,28 @@ LL | use std::cell::UnsafeCell as TotallySafeCell;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::unsafe-removed-from-name` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unsafe_removed_from_name)]`
error: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain`
- --> $DIR/unsafe_removed_from_name.rs:7:1
+ --> $DIR/unsafe_removed_from_name.rs:9:1
|
LL | use std::cell::UnsafeCell as TotallySafeCellAgain;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: removed `unsafe` from the name of `Unsafe` in use as `LieAboutModSafety`
- --> $DIR/unsafe_removed_from_name.rs:25:1
+ --> $DIR/unsafe_removed_from_name.rs:28:1
|
LL | use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: removed `unsafe` from the name of `Unsafe` in use as `A`
- --> $DIR/unsafe_removed_from_name.rs:28:1
+ --> $DIR/unsafe_removed_from_name.rs:32:1
|
LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: removed `unsafe` from the name of `Unsafe` in use as `B`
- --> $DIR/unsafe_removed_from_name.rs:28:1
+ --> $DIR/unsafe_removed_from_name.rs:32:1
|
LL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed b/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed
index 125120872..93f7f747b 100644
--- a/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed
+++ b/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![warn(clippy::unseparated_literal_suffix)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs b/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs
index 0a3ffc478..c960ff6b5 100644
--- a/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs
+++ b/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![warn(clippy::unseparated_literal_suffix)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/unseparated_prefix_literals.stderr b/src/tools/clippy/tests/ui/unseparated_prefix_literals.stderr
index ab2f75e0c..d74e72875 100644
--- a/src/tools/clippy/tests/ui/unseparated_prefix_literals.stderr
+++ b/src/tools/clippy/tests/ui/unseparated_prefix_literals.stderr
@@ -1,49 +1,50 @@
error: integer type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:24:18
+ --> $DIR/unseparated_prefix_literals.rs:23:18
|
LL | let _fail1 = 1234i32;
| ^^^^^^^ help: add an underscore: `1234_i32`
|
= note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]`
error: integer type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:25:18
+ --> $DIR/unseparated_prefix_literals.rs:24:18
|
LL | let _fail2 = 1234u32;
| ^^^^^^^ help: add an underscore: `1234_u32`
error: integer type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:26:18
+ --> $DIR/unseparated_prefix_literals.rs:25:18
|
LL | let _fail3 = 1234isize;
| ^^^^^^^^^ help: add an underscore: `1234_isize`
error: integer type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:27:18
+ --> $DIR/unseparated_prefix_literals.rs:26:18
|
LL | let _fail4 = 1234usize;
| ^^^^^^^^^ help: add an underscore: `1234_usize`
error: integer type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:28:18
+ --> $DIR/unseparated_prefix_literals.rs:27:18
|
LL | let _fail5 = 0x123isize;
| ^^^^^^^^^^ help: add an underscore: `0x123_isize`
error: float type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:32:19
+ --> $DIR/unseparated_prefix_literals.rs:31:19
|
LL | let _failf1 = 1.5f32;
| ^^^^^^ help: add an underscore: `1.5_f32`
error: float type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:33:19
+ --> $DIR/unseparated_prefix_literals.rs:32:19
|
LL | let _failf2 = 1f32;
| ^^^^ help: add an underscore: `1_f32`
error: integer type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:16:9
+ --> $DIR/unseparated_prefix_literals.rs:15:9
|
LL | 42usize
| ^^^^^^^ help: add an underscore: `42_usize`
@@ -54,7 +55,7 @@ LL | let _ = lit_from_macro!();
= note: this error originates in the macro `lit_from_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: integer type suffix should be separated by an underscore
- --> $DIR/unseparated_prefix_literals.rs:41:16
+ --> $DIR/unseparated_prefix_literals.rs:40:16
|
LL | assert_eq!(4897u32, 32223);
| ^^^^^^^ help: add an underscore: `4897_u32`
diff --git a/src/tools/clippy/tests/ui/unused_async.rs b/src/tools/clippy/tests/ui/unused_async.rs
index 1d188025e..71722e9af 100644
--- a/src/tools/clippy/tests/ui/unused_async.rs
+++ b/src/tools/clippy/tests/ui/unused_async.rs
@@ -11,6 +11,7 @@ mod issue10800 {
use std::future::ready;
async fn async_block_await() {
+ //~^ ERROR: unused `async` for function with no await statements
async {
ready(()).await;
};
@@ -43,6 +44,7 @@ mod issue9695 {
async fn f() {}
async fn f2() {}
async fn f3() {}
+ //~^ ERROR: unused `async` for function with no await statements
fn needs_async_fn<F: Future<Output = ()>>(_: fn() -> F) {}
@@ -55,6 +57,7 @@ mod issue9695 {
}
async fn foo() -> i32 {
+ //~^ ERROR: unused `async` for function with no await statements
4
}
@@ -66,6 +69,7 @@ struct S;
impl S {
async fn unused(&self) -> i32 {
+ //~^ ERROR: unused `async` for function with no await statements
1
}
diff --git a/src/tools/clippy/tests/ui/unused_async.stderr b/src/tools/clippy/tests/ui/unused_async.stderr
index 8d9b72c48..077e8cacc 100644
--- a/src/tools/clippy/tests/ui/unused_async.stderr
+++ b/src/tools/clippy/tests/ui/unused_async.stderr
@@ -2,6 +2,7 @@ error: unused `async` for function with no await statements
--> $DIR/unused_async.rs:13:5
|
LL | / async fn async_block_await() {
+LL | |
LL | | async {
LL | | ready(()).await;
LL | | };
@@ -10,14 +11,15 @@ LL | | }
|
= help: consider removing the `async` from this function
note: `await` used in an async block, which does not require the enclosing function to be `async`
- --> $DIR/unused_async.rs:15:23
+ --> $DIR/unused_async.rs:16:23
|
LL | ready(()).await;
| ^^^^^
= note: `-D clippy::unused-async` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unused_async)]`
error: unused `async` for function with no await statements
- --> $DIR/unused_async.rs:45:5
+ --> $DIR/unused_async.rs:46:5
|
LL | async fn f3() {}
| ^^^^^^^^^^^^^^^^
@@ -25,9 +27,10 @@ LL | async fn f3() {}
= help: consider removing the `async` from this function
error: unused `async` for function with no await statements
- --> $DIR/unused_async.rs:57:1
+ --> $DIR/unused_async.rs:59:1
|
LL | / async fn foo() -> i32 {
+LL | |
LL | | 4
LL | | }
| |_^
@@ -35,9 +38,10 @@ LL | | }
= help: consider removing the `async` from this function
error: unused `async` for function with no await statements
- --> $DIR/unused_async.rs:68:5
+ --> $DIR/unused_async.rs:71:5
|
LL | / async fn unused(&self) -> i32 {
+LL | |
LL | | 1
LL | | }
| |_____^
diff --git a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs b/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs
index 78601a348..be9919353 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs
+++ b/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs
@@ -1,6 +1,6 @@
#![warn(clippy::unused_format_specs)]
#![allow(unused)]
-
+//@no-rustfix
macro_rules! format_args_from_macro {
() => {
format_args!("from macro")
@@ -10,13 +10,18 @@ macro_rules! format_args_from_macro {
fn main() {
// prints `.`, not ` .`
println!("{:5}.", format_args!(""));
+ //~^ ERROR: format specifiers have no effect on `format_args!()`
+ //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings`
//prints `abcde`, not `abc`
println!("{:.3}", format_args!("abcde"));
+ //~^ ERROR: format specifiers have no effect on `format_args!()`
println!("{:5}.", format_args_from_macro!());
+ //~^ ERROR: format specifiers have no effect on `format_args!()`
let args = format_args!("");
println!("{args:5}");
+ //~^ ERROR: format specifiers have no effect on `format_args!()`
}
fn should_not_lint() {
diff --git a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr b/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr
index cb7156b6b..183e80c85 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr
@@ -5,6 +5,7 @@ LL | println!("{:5}.", format_args!(""));
| ^^^^
|
= note: `-D clippy::unused-format-specs` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unused_format_specs)]`
help: for the width to apply consider using `format!()`
|
LL | println!("{:5}.", format!(""));
@@ -16,7 +17,7 @@ LL + println!("{}.", format_args!(""));
|
error: format specifiers have no effect on `format_args!()`
- --> $DIR/unused_format_specs_unfixable.rs:14:15
+ --> $DIR/unused_format_specs_unfixable.rs:16:15
|
LL | println!("{:.3}", format_args!("abcde"));
| ^^^^^
@@ -32,7 +33,7 @@ LL + println!("{}", format_args!("abcde"));
|
error: format specifiers have no effect on `format_args!()`
- --> $DIR/unused_format_specs_unfixable.rs:16:15
+ --> $DIR/unused_format_specs_unfixable.rs:19:15
|
LL | println!("{:5}.", format_args_from_macro!());
| ^^^^
@@ -45,7 +46,7 @@ LL + println!("{}.", format_args_from_macro!());
|
error: format specifiers have no effect on `format_args!()`
- --> $DIR/unused_format_specs_unfixable.rs:19:15
+ --> $DIR/unused_format_specs_unfixable.rs:23:15
|
LL | println!("{args:5}");
| ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unused_io_amount.rs b/src/tools/clippy/tests/ui/unused_io_amount.rs
index e9d1eeb31..62aec6e9e 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.rs
+++ b/src/tools/clippy/tests/ui/unused_io_amount.rs
@@ -7,20 +7,26 @@ use std::io::{self, Read};
fn question_mark<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {
s.write(b"test")?;
+ //~^ ERROR: written amount is not handled
let mut buf = [0u8; 4];
s.read(&mut buf)?;
+ //~^ ERROR: read amount is not handled
Ok(())
}
fn unwrap<T: io::Read + io::Write>(s: &mut T) {
s.write(b"test").unwrap();
+ //~^ ERROR: written amount is not handled
let mut buf = [0u8; 4];
s.read(&mut buf).unwrap();
+ //~^ ERROR: read amount is not handled
}
fn vectored<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {
s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;
+ //~^ ERROR: read amount is not handled
s.write_vectored(&[io::IoSlice::new(&[])])?;
+ //~^ ERROR: written amount is not handled
Ok(())
}
@@ -28,6 +34,7 @@ fn ok(file: &str) -> Option<()> {
let mut reader = std::fs::File::open(file).ok()?;
let mut result = [0u8; 0];
reader.read(&mut result).ok()?;
+ //~^ ERROR: read amount is not handled
Some(())
}
@@ -37,6 +44,7 @@ fn or_else(file: &str) -> io::Result<()> {
let mut reader = std::fs::File::open(file)?;
let mut result = [0u8; 0];
reader.read(&mut result).or_else(|err| Err(err))?;
+ //~^ ERROR: read amount is not handled
Ok(())
}
@@ -49,6 +57,7 @@ fn or(file: &str) -> Result<(), Error> {
let mut reader = std::fs::File::open(file).unwrap();
let mut result = [0u8; 0];
reader.read(&mut result).or(Err(Error::Kind))?;
+ //~^ ERROR: read amount is not handled
Ok(())
}
@@ -56,6 +65,7 @@ fn combine_or(file: &str) -> Result<(), Error> {
let mut reader = std::fs::File::open(file).unwrap();
let mut result = [0u8; 0];
reader
+ //~^ ERROR: read amount is not handled
.read(&mut result)
.or(Err(Error::Kind))
.or(Err(Error::Kind))
@@ -65,19 +75,25 @@ fn combine_or(file: &str) -> Result<(), Error> {
fn is_ok_err<T: io::Read + io::Write>(s: &mut T) {
s.write(b"ok").is_ok();
+ //~^ ERROR: written amount is not handled
s.write(b"err").is_err();
+ //~^ ERROR: written amount is not handled
let mut buf = [0u8; 0];
s.read(&mut buf).is_ok();
+ //~^ ERROR: read amount is not handled
s.read(&mut buf).is_err();
+ //~^ ERROR: read amount is not handled
}
async fn bad_async_write<W: AsyncWrite + Unpin>(w: &mut W) {
w.write(b"hello world").await.unwrap();
+ //~^ ERROR: written amount is not handled
}
async fn bad_async_read<R: AsyncRead + Unpin>(r: &mut R) {
let mut buf = [0u8; 0];
r.read(&mut buf[..]).await.unwrap();
+ //~^ ERROR: read amount is not handled
}
async fn io_not_ignored_async_write<W: AsyncWrite + Unpin>(mut w: W) {
@@ -91,6 +107,7 @@ fn bad_async_write_closure<W: AsyncWrite + Unpin + 'static>(w: W) -> impl future
let mut w = w;
async move {
w.write(b"hello world").await?;
+ //~^ ERROR: written amount is not handled
Ok(())
}
}
@@ -99,6 +116,7 @@ async fn async_read_nested_or<R: AsyncRead + Unpin>(r: &mut R, do_it: bool) -> R
let mut buf = [0u8; 1];
if do_it {
r.read(&mut buf[..]).await.or(Err(Error::Kind))?;
+ //~^ ERROR: read amount is not handled
}
Ok(buf)
}
@@ -107,11 +125,13 @@ use tokio::io::{AsyncRead as TokioAsyncRead, AsyncReadExt as _, AsyncWrite as To
async fn bad_async_write_tokio<W: TokioAsyncWrite + Unpin>(w: &mut W) {
w.write(b"hello world").await.unwrap();
+ //~^ ERROR: written amount is not handled
}
async fn bad_async_read_tokio<R: TokioAsyncRead + Unpin>(r: &mut R) {
let mut buf = [0u8; 0];
r.read(&mut buf[..]).await.unwrap();
+ //~^ ERROR: read amount is not handled
}
async fn undetected_bad_async_write<W: AsyncWrite + Unpin>(w: &mut W) {
diff --git a/src/tools/clippy/tests/ui/unused_io_amount.stderr b/src/tools/clippy/tests/ui/unused_io_amount.stderr
index 0865c5213..f9aef596a 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.stderr
+++ b/src/tools/clippy/tests/ui/unused_io_amount.stderr
@@ -6,9 +6,10 @@ LL | s.write(b"test")?;
|
= help: use `Write::write_all` instead, or handle partial writes
= note: `-D clippy::unused-io-amount` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unused_io_amount)]`
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:11:5
+ --> $DIR/unused_io_amount.rs:12:5
|
LL | s.read(&mut buf)?;
| ^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | s.read(&mut buf)?;
= help: use `Read::read_exact` instead, or handle partial reads
error: written amount is not handled
- --> $DIR/unused_io_amount.rs:16:5
+ --> $DIR/unused_io_amount.rs:18:5
|
LL | s.write(b"test").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | s.write(b"test").unwrap();
= help: use `Write::write_all` instead, or handle partial writes
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:18:5
+ --> $DIR/unused_io_amount.rs:21:5
|
LL | s.read(&mut buf).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,19 +33,19 @@ LL | s.read(&mut buf).unwrap();
= help: use `Read::read_exact` instead, or handle partial reads
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:22:5
+ --> $DIR/unused_io_amount.rs:26:5
|
LL | s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: written amount is not handled
- --> $DIR/unused_io_amount.rs:23:5
+ --> $DIR/unused_io_amount.rs:28:5
|
LL | s.write_vectored(&[io::IoSlice::new(&[])])?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:30:5
+ --> $DIR/unused_io_amount.rs:36:5
|
LL | reader.read(&mut result).ok()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,7 +53,7 @@ LL | reader.read(&mut result).ok()?;
= help: use `Read::read_exact` instead, or handle partial reads
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:39:5
+ --> $DIR/unused_io_amount.rs:46:5
|
LL | reader.read(&mut result).or_else(|err| Err(err))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +61,7 @@ LL | reader.read(&mut result).or_else(|err| Err(err))?;
= help: use `Read::read_exact` instead, or handle partial reads
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:51:5
+ --> $DIR/unused_io_amount.rs:59:5
|
LL | reader.read(&mut result).or(Err(Error::Kind))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -68,9 +69,10 @@ LL | reader.read(&mut result).or(Err(Error::Kind))?;
= help: use `Read::read_exact` instead, or handle partial reads
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:58:5
+ --> $DIR/unused_io_amount.rs:67:5
|
LL | / reader
+LL | |
LL | | .read(&mut result)
LL | | .or(Err(Error::Kind))
LL | | .or(Err(Error::Kind))
@@ -80,7 +82,7 @@ LL | | .expect("error");
= help: use `Read::read_exact` instead, or handle partial reads
error: written amount is not handled
- --> $DIR/unused_io_amount.rs:67:5
+ --> $DIR/unused_io_amount.rs:77:5
|
LL | s.write(b"ok").is_ok();
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +90,7 @@ LL | s.write(b"ok").is_ok();
= help: use `Write::write_all` instead, or handle partial writes
error: written amount is not handled
- --> $DIR/unused_io_amount.rs:68:5
+ --> $DIR/unused_io_amount.rs:79:5
|
LL | s.write(b"err").is_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +98,7 @@ LL | s.write(b"err").is_err();
= help: use `Write::write_all` instead, or handle partial writes
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:70:5
+ --> $DIR/unused_io_amount.rs:82:5
|
LL | s.read(&mut buf).is_ok();
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +106,7 @@ LL | s.read(&mut buf).is_ok();
= help: use `Read::read_exact` instead, or handle partial reads
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:71:5
+ --> $DIR/unused_io_amount.rs:84:5
|
LL | s.read(&mut buf).is_err();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +114,7 @@ LL | s.read(&mut buf).is_err();
= help: use `Read::read_exact` instead, or handle partial reads
error: written amount is not handled
- --> $DIR/unused_io_amount.rs:75:5
+ --> $DIR/unused_io_amount.rs:89:5
|
LL | w.write(b"hello world").await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,7 +122,7 @@ LL | w.write(b"hello world").await.unwrap();
= help: use `AsyncWriteExt::write_all` instead, or handle partial writes
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:80:5
+ --> $DIR/unused_io_amount.rs:95:5
|
LL | r.read(&mut buf[..]).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -128,7 +130,7 @@ LL | r.read(&mut buf[..]).await.unwrap();
= help: use `AsyncReadExt::read_exact` instead, or handle partial reads
error: written amount is not handled
- --> $DIR/unused_io_amount.rs:93:9
+ --> $DIR/unused_io_amount.rs:109:9
|
LL | w.write(b"hello world").await?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -136,7 +138,7 @@ LL | w.write(b"hello world").await?;
= help: use `AsyncWriteExt::write_all` instead, or handle partial writes
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:101:9
+ --> $DIR/unused_io_amount.rs:118:9
|
LL | r.read(&mut buf[..]).await.or(Err(Error::Kind))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +146,7 @@ LL | r.read(&mut buf[..]).await.or(Err(Error::Kind))?;
= help: use `AsyncReadExt::read_exact` instead, or handle partial reads
error: written amount is not handled
- --> $DIR/unused_io_amount.rs:109:5
+ --> $DIR/unused_io_amount.rs:127:5
|
LL | w.write(b"hello world").await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -152,7 +154,7 @@ LL | w.write(b"hello world").await.unwrap();
= help: use `AsyncWriteExt::write_all` instead, or handle partial writes
error: read amount is not handled
- --> $DIR/unused_io_amount.rs:114:5
+ --> $DIR/unused_io_amount.rs:133:5
|
LL | r.read(&mut buf[..]).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unused_peekable.rs b/src/tools/clippy/tests/ui/unused_peekable.rs
index b227f8660..131b51e01 100644
--- a/src/tools/clippy/tests/ui/unused_peekable.rs
+++ b/src/tools/clippy/tests/ui/unused_peekable.rs
@@ -11,14 +11,17 @@ fn main() {
#[allow(clippy::unused_unit)]
fn invalid() {
let peekable = std::iter::empty::<u32>().peekable();
+ //~^ ERROR: `peek` never called on `Peekable` iterator
// Only lint `new_local`
let old_local = std::iter::empty::<u32>().peekable();
let new_local = old_local;
+ //~^ ERROR: `peek` never called on `Peekable` iterator
// Behind mut ref
let mut by_mut_ref_test = std::iter::empty::<u32>().peekable();
let by_mut_ref = &mut by_mut_ref_test;
+ //~^ ERROR: `peek` never called on `Peekable` iterator
// Explicitly returns `Peekable`
fn returns_peekable() -> Peekable<Empty<u32>> {
@@ -26,21 +29,26 @@ fn invalid() {
}
let peekable_from_fn = returns_peekable();
+ //~^ ERROR: `peek` never called on `Peekable` iterator
// Using a method not exclusive to `Peekable`
let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable();
+ //~^ ERROR: `peek` never called on `Peekable` iterator
peekable_using_iterator_method.next();
// Passed by ref to another function
fn takes_ref(_peek: &Peekable<Empty<u32>>) {}
let passed_along_ref = std::iter::empty::<u32>().peekable();
+ //~^ ERROR: `peek` never called on `Peekable` iterator
takes_ref(&passed_along_ref);
// `by_ref` without `peek`
let mut by_ref_test = std::iter::empty::<u32>().peekable();
let _by_ref = by_ref_test.by_ref();
+ //~^ ERROR: `peek` never called on `Peekable` iterator
let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable();
+ //~^ ERROR: `peek` never called on `Peekable` iterator
for x in peekable_in_for_loop {}
}
diff --git a/src/tools/clippy/tests/ui/unused_peekable.stderr b/src/tools/clippy/tests/ui/unused_peekable.stderr
index d969232fd..157d6fc15 100644
--- a/src/tools/clippy/tests/ui/unused_peekable.stderr
+++ b/src/tools/clippy/tests/ui/unused_peekable.stderr
@@ -6,9 +6,10 @@ LL | let peekable = std::iter::empty::<u32>().peekable();
|
= help: consider removing the call to `peekable`
= note: `-D clippy::unused-peekable` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unused_peekable)]`
error: `peek` never called on `Peekable` iterator
- --> $DIR/unused_peekable.rs:17:9
+ --> $DIR/unused_peekable.rs:18:9
|
LL | let new_local = old_local;
| ^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let new_local = old_local;
= help: consider removing the call to `peekable`
error: `peek` never called on `Peekable` iterator
- --> $DIR/unused_peekable.rs:21:9
+ --> $DIR/unused_peekable.rs:23:9
|
LL | let by_mut_ref = &mut by_mut_ref_test;
| ^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let by_mut_ref = &mut by_mut_ref_test;
= help: consider removing the call to `peekable`
error: `peek` never called on `Peekable` iterator
- --> $DIR/unused_peekable.rs:28:9
+ --> $DIR/unused_peekable.rs:31:9
|
LL | let peekable_from_fn = returns_peekable();
| ^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | let peekable_from_fn = returns_peekable();
= help: consider removing the call to `peekable`
error: `peek` never called on `Peekable` iterator
- --> $DIR/unused_peekable.rs:31:13
+ --> $DIR/unused_peekable.rs:35:13
|
LL | let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | let mut peekable_using_iterator_method = std::iter::empty::<u32>().peek
= help: consider removing the call to `peekable`
error: `peek` never called on `Peekable` iterator
- --> $DIR/unused_peekable.rs:36:9
+ --> $DIR/unused_peekable.rs:41:9
|
LL | let passed_along_ref = std::iter::empty::<u32>().peekable();
| ^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | let passed_along_ref = std::iter::empty::<u32>().peekable();
= help: consider removing the call to `peekable`
error: `peek` never called on `Peekable` iterator
- --> $DIR/unused_peekable.rs:41:9
+ --> $DIR/unused_peekable.rs:47:9
|
LL | let _by_ref = by_ref_test.by_ref();
| ^^^^^^^
@@ -56,7 +57,7 @@ LL | let _by_ref = by_ref_test.by_ref();
= help: consider removing the call to `peekable`
error: `peek` never called on `Peekable` iterator
- --> $DIR/unused_peekable.rs:43:13
+ --> $DIR/unused_peekable.rs:50:13
|
LL | let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable();
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unused_rounding.fixed b/src/tools/clippy/tests/ui/unused_rounding.fixed
index f02b55502..02f970f42 100644
--- a/src/tools/clippy/tests/ui/unused_rounding.fixed
+++ b/src/tools/clippy/tests/ui/unused_rounding.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unused_rounding)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/unused_rounding.rs b/src/tools/clippy/tests/ui/unused_rounding.rs
index c7bd4906d..fd14c466f 100644
--- a/src/tools/clippy/tests/ui/unused_rounding.rs
+++ b/src/tools/clippy/tests/ui/unused_rounding.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::unused_rounding)]
fn main() {
diff --git a/src/tools/clippy/tests/ui/unused_rounding.stderr b/src/tools/clippy/tests/ui/unused_rounding.stderr
index b867996fe..d6ce27351 100644
--- a/src/tools/clippy/tests/ui/unused_rounding.stderr
+++ b/src/tools/clippy/tests/ui/unused_rounding.stderr
@@ -1,31 +1,32 @@
error: used the `ceil` method with a whole number float
- --> $DIR/unused_rounding.rs:5:13
+ --> $DIR/unused_rounding.rs:4:13
|
LL | let _ = 1f32.ceil();
| ^^^^^^^^^^^ help: remove the `ceil` method call: `1f32`
|
= note: `-D clippy::unused-rounding` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unused_rounding)]`
error: used the `floor` method with a whole number float
- --> $DIR/unused_rounding.rs:6:13
+ --> $DIR/unused_rounding.rs:5:13
|
LL | let _ = 1.0f64.floor();
| ^^^^^^^^^^^^^^ help: remove the `floor` method call: `1.0f64`
error: used the `round` method with a whole number float
- --> $DIR/unused_rounding.rs:7:13
+ --> $DIR/unused_rounding.rs:6:13
|
LL | let _ = 1.00f32.round();
| ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32`
error: used the `round` method with a whole number float
- --> $DIR/unused_rounding.rs:13:13
+ --> $DIR/unused_rounding.rs:12:13
|
LL | let _ = 3.0_f32.round();
| ^^^^^^^^^^^^^^^ help: remove the `round` method call: `3.0_f32`
error: used the `round` method with a whole number float
- --> $DIR/unused_rounding.rs:15:13
+ --> $DIR/unused_rounding.rs:14:13
|
LL | let _ = 3_3.0_0_f32.round();
| ^^^^^^^^^^^^^^^^^^^ help: remove the `round` method call: `3_3.0_0_f32`
diff --git a/src/tools/clippy/tests/ui/unused_self.rs b/src/tools/clippy/tests/ui/unused_self.rs
index 55bd56071..d3d06037c 100644
--- a/src/tools/clippy/tests/ui/unused_self.rs
+++ b/src/tools/clippy/tests/ui/unused_self.rs
@@ -9,16 +9,25 @@ mod unused_self {
impl A {
fn unused_self_move(self) {}
+ //~^ ERROR: unused `self` argument
fn unused_self_ref(&self) {}
+ //~^ ERROR: unused `self` argument
fn unused_self_mut_ref(&mut self) {}
+ //~^ ERROR: unused `self` argument
fn unused_self_pin_ref(self: Pin<&Self>) {}
+ //~^ ERROR: unused `self` argument
fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {}
+ //~^ ERROR: unused `self` argument
fn unused_self_pin_nested(self: Pin<Arc<Self>>) {}
+ //~^ ERROR: unused `self` argument
fn unused_self_box(self: Box<Self>) {}
+ //~^ ERROR: unused `self` argument
fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 {
+ //~^ ERROR: unused `self` argument
x + y
}
fn unused_self_class_method(&self) {
+ //~^ ERROR: unused `self` argument
Self::static_method();
}
diff --git a/src/tools/clippy/tests/ui/unused_self.stderr b/src/tools/clippy/tests/ui/unused_self.stderr
index 919f9b6ef..3865095bb 100644
--- a/src/tools/clippy/tests/ui/unused_self.stderr
+++ b/src/tools/clippy/tests/ui/unused_self.stderr
@@ -6,9 +6,10 @@ LL | fn unused_self_move(self) {}
|
= help: consider refactoring to an associated function
= note: `-D clippy::unused-self` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unused_self)]`
error: unused `self` argument
- --> $DIR/unused_self.rs:12:28
+ --> $DIR/unused_self.rs:13:28
|
LL | fn unused_self_ref(&self) {}
| ^^^^^
@@ -16,7 +17,7 @@ LL | fn unused_self_ref(&self) {}
= help: consider refactoring to an associated function
error: unused `self` argument
- --> $DIR/unused_self.rs:13:32
+ --> $DIR/unused_self.rs:15:32
|
LL | fn unused_self_mut_ref(&mut self) {}
| ^^^^^^^^^
@@ -24,7 +25,7 @@ LL | fn unused_self_mut_ref(&mut self) {}
= help: consider refactoring to an associated function
error: unused `self` argument
- --> $DIR/unused_self.rs:14:32
+ --> $DIR/unused_self.rs:17:32
|
LL | fn unused_self_pin_ref(self: Pin<&Self>) {}
| ^^^^
@@ -32,7 +33,7 @@ LL | fn unused_self_pin_ref(self: Pin<&Self>) {}
= help: consider refactoring to an associated function
error: unused `self` argument
- --> $DIR/unused_self.rs:15:36
+ --> $DIR/unused_self.rs:19:36
|
LL | fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {}
| ^^^^
@@ -40,7 +41,7 @@ LL | fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {}
= help: consider refactoring to an associated function
error: unused `self` argument
- --> $DIR/unused_self.rs:16:35
+ --> $DIR/unused_self.rs:21:35
|
LL | fn unused_self_pin_nested(self: Pin<Arc<Self>>) {}
| ^^^^
@@ -48,7 +49,7 @@ LL | fn unused_self_pin_nested(self: Pin<Arc<Self>>) {}
= help: consider refactoring to an associated function
error: unused `self` argument
- --> $DIR/unused_self.rs:17:28
+ --> $DIR/unused_self.rs:23:28
|
LL | fn unused_self_box(self: Box<Self>) {}
| ^^^^
@@ -56,7 +57,7 @@ LL | fn unused_self_box(self: Box<Self>) {}
= help: consider refactoring to an associated function
error: unused `self` argument
- --> $DIR/unused_self.rs:18:40
+ --> $DIR/unused_self.rs:25:40
|
LL | fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 {
| ^^^^^
@@ -64,7 +65,7 @@ LL | fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 {
= help: consider refactoring to an associated function
error: unused `self` argument
- --> $DIR/unused_self.rs:21:37
+ --> $DIR/unused_self.rs:29:37
|
LL | fn unused_self_class_method(&self) {
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/unused_unit.fixed b/src/tools/clippy/tests/ui/unused_unit.fixed
index 7b8f7847d..16da9a25b 100644
--- a/src/tools/clippy/tests/ui/unused_unit.fixed
+++ b/src/tools/clippy/tests/ui/unused_unit.fixed
@@ -1,4 +1,4 @@
-//@run-rustfix
+
// The output for humans should just highlight the whole span without showing
// the suggested replacement, but we also want to test that suggested
diff --git a/src/tools/clippy/tests/ui/unused_unit.rs b/src/tools/clippy/tests/ui/unused_unit.rs
index fdde1ecad..e37403143 100644
--- a/src/tools/clippy/tests/ui/unused_unit.rs
+++ b/src/tools/clippy/tests/ui/unused_unit.rs
@@ -1,4 +1,4 @@
-//@run-rustfix
+
// The output for humans should just highlight the whole span without showing
// the suggested replacement, but we also want to test that suggested
diff --git a/src/tools/clippy/tests/ui/unwrap.rs b/src/tools/clippy/tests/ui/unwrap.rs
index 64d643783..8ad7e9850 100644
--- a/src/tools/clippy/tests/ui/unwrap.rs
+++ b/src/tools/clippy/tests/ui/unwrap.rs
@@ -4,12 +4,15 @@
fn unwrap_option() {
let opt = Some(0);
let _ = opt.unwrap();
+ //~^ ERROR: used `unwrap()` on an `Option` value
}
fn unwrap_result() {
let res: Result<u8, u8> = Ok(0);
let _ = res.unwrap();
+ //~^ ERROR: used `unwrap()` on a `Result` value
let _ = res.unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on a `Result` value
}
fn main() {
diff --git a/src/tools/clippy/tests/ui/unwrap.stderr b/src/tools/clippy/tests/ui/unwrap.stderr
index 41db819f6..25911ded2 100644
--- a/src/tools/clippy/tests/ui/unwrap.stderr
+++ b/src/tools/clippy/tests/ui/unwrap.stderr
@@ -7,9 +7,10 @@ LL | let _ = opt.unwrap();
= note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
= note: `-D clippy::unwrap-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`
error: used `unwrap()` on a `Result` value
- --> $DIR/unwrap.rs:11:13
+ --> $DIR/unwrap.rs:12:13
|
LL | let _ = res.unwrap();
| ^^^^^^^^^^^^
@@ -18,7 +19,7 @@ LL | let _ = res.unwrap();
= help: consider using `expect()` to provide a better panic message
error: used `unwrap_err()` on a `Result` value
- --> $DIR/unwrap.rs:12:13
+ --> $DIR/unwrap.rs:14:13
|
LL | let _ = res.unwrap_err();
| ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.rs b/src/tools/clippy/tests/ui/unwrap_expect_used.rs
index 26f92ccde..96368a070 100644
--- a/src/tools/clippy/tests/ui/unwrap_expect_used.rs
+++ b/src/tools/clippy/tests/ui/unwrap_expect_used.rs
@@ -25,7 +25,9 @@ impl<T> OptionExt for Option<T> {
fn main() {
Some(3).unwrap();
+ //~^ ERROR: used `unwrap()` on an `Option` value
Some(3).expect("Hello world!");
+ //~^ ERROR: used `expect()` on an `Option` value
// Don't trigger on unwrap_err on an option
Some(3).unwrap_err();
@@ -41,7 +43,11 @@ fn main() {
let a: Result<i32, i32> = Ok(3);
a.unwrap();
+ //~^ ERROR: used `unwrap()` on a `Result` value
a.expect("Hello world!");
+ //~^ ERROR: used `expect()` on a `Result` value
a.unwrap_err();
+ //~^ ERROR: used `unwrap_err()` on a `Result` value
a.expect_err("Hello error!");
+ //~^ ERROR: used `expect_err()` on a `Result` value
}
diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
index f66e47612..cbe6ea22e 100644
--- a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
@@ -6,18 +6,20 @@ LL | Some(3).unwrap();
|
= note: if this value is `None`, it will panic
= note: `-D clippy::unwrap-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`
error: used `expect()` on an `Option` value
- --> $DIR/unwrap_expect_used.rs:28:5
+ --> $DIR/unwrap_expect_used.rs:29:5
|
LL | Some(3).expect("Hello world!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::expect_used)]`
error: used `unwrap()` on a `Result` value
- --> $DIR/unwrap_expect_used.rs:43:5
+ --> $DIR/unwrap_expect_used.rs:45:5
|
LL | a.unwrap();
| ^^^^^^^^^^
@@ -25,7 +27,7 @@ LL | a.unwrap();
= note: if this value is an `Err`, it will panic
error: used `expect()` on a `Result` value
- --> $DIR/unwrap_expect_used.rs:44:5
+ --> $DIR/unwrap_expect_used.rs:47:5
|
LL | a.expect("Hello world!");
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +35,7 @@ LL | a.expect("Hello world!");
= note: if this value is an `Err`, it will panic
error: used `unwrap_err()` on a `Result` value
- --> $DIR/unwrap_expect_used.rs:45:5
+ --> $DIR/unwrap_expect_used.rs:49:5
|
LL | a.unwrap_err();
| ^^^^^^^^^^^^^^
@@ -41,7 +43,7 @@ LL | a.unwrap_err();
= note: if this value is an `Ok`, it will panic
error: used `expect_err()` on a `Result` value
- --> $DIR/unwrap_expect_used.rs:46:5
+ --> $DIR/unwrap_expect_used.rs:51:5
|
LL | a.expect_err("Hello error!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unwrap_in_result.rs b/src/tools/clippy/tests/ui/unwrap_in_result.rs
index 2aa842adc..a19db46c6 100644
--- a/src/tools/clippy/tests/ui/unwrap_in_result.rs
+++ b/src/tools/clippy/tests/ui/unwrap_in_result.rs
@@ -20,6 +20,7 @@ impl A {
// should be detected
fn bad_divisible_by_3(i_str: String) -> Result<bool, String> {
+ //~^ ERROR: used unwrap or expect in a function that returns result or option
// checks whether a string represents a number divisible by 3
let i = i_str.parse::<i32>().unwrap();
if i % 3 == 0 {
@@ -30,6 +31,7 @@ impl A {
}
fn example_option_expect(i_str: String) -> Option<bool> {
+ //~^ ERROR: used unwrap or expect in a function that returns result or option
let i = i_str.parse::<i32>().expect("not a number");
if i % 3 == 0 {
return Some(true);
diff --git a/src/tools/clippy/tests/ui/unwrap_in_result.stderr b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
index 40e6bfe08..9a0a32d47 100644
--- a/src/tools/clippy/tests/ui/unwrap_in_result.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
@@ -2,9 +2,9 @@ error: used unwrap or expect in a function that returns result or option
--> $DIR/unwrap_in_result.rs:22:5
|
LL | / fn bad_divisible_by_3(i_str: String) -> Result<bool, String> {
+LL | |
LL | | // checks whether a string represents a number divisible by 3
LL | | let i = i_str.parse::<i32>().unwrap();
-LL | | if i % 3 == 0 {
... |
LL | | }
LL | | }
@@ -12,27 +12,28 @@ LL | | }
|
= help: unwrap and expect should not be used in a function that returns result or option
note: potential non-recoverable error(s)
- --> $DIR/unwrap_in_result.rs:24:17
+ --> $DIR/unwrap_in_result.rs:25:17
|
LL | let i = i_str.parse::<i32>().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::unwrap-in-result` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unwrap_in_result)]`
error: used unwrap or expect in a function that returns result or option
- --> $DIR/unwrap_in_result.rs:32:5
+ --> $DIR/unwrap_in_result.rs:33:5
|
LL | / fn example_option_expect(i_str: String) -> Option<bool> {
+LL | |
LL | | let i = i_str.parse::<i32>().expect("not a number");
LL | | if i % 3 == 0 {
-LL | | return Some(true);
-LL | | }
+... |
LL | | None
LL | | }
| |_____^
|
= help: unwrap and expect should not be used in a function that returns result or option
note: potential non-recoverable error(s)
- --> $DIR/unwrap_in_result.rs:33:17
+ --> $DIR/unwrap_in_result.rs:35:17
|
LL | let i = i_str.parse::<i32>().expect("not a number");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unwrap_or.fixed b/src/tools/clippy/tests/ui/unwrap_or.fixed
new file mode 100644
index 000000000..e1a47fc7b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unwrap_or.fixed
@@ -0,0 +1,13 @@
+#![warn(clippy::all, clippy::or_fun_call)]
+#![allow(clippy::unnecessary_literal_unwrap)]
+
+fn main() {
+ let s = Some(String::from("test string")).unwrap_or_else(|| "Fail".to_string()).len();
+ //~^ ERROR: use of `unwrap_or` followed by a function call
+ //~| NOTE: `-D clippy::or-fun-call` implied by `-D warnings`
+}
+
+fn new_lines() {
+ let s = Some(String::from("test string")).unwrap_or_else(|| "Fail".to_string()).len();
+ //~^ ERROR: use of `unwrap_or` followed by a function call
+}
diff --git a/src/tools/clippy/tests/ui/unwrap_or.rs b/src/tools/clippy/tests/ui/unwrap_or.rs
index 5bea85e66..914bfb939 100644
--- a/src/tools/clippy/tests/ui/unwrap_or.rs
+++ b/src/tools/clippy/tests/ui/unwrap_or.rs
@@ -3,8 +3,11 @@
fn main() {
let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len();
+ //~^ ERROR: use of `unwrap_or` followed by a function call
+ //~| NOTE: `-D clippy::or-fun-call` implied by `-D warnings`
}
fn new_lines() {
let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len();
+ //~^ ERROR: use of `unwrap_or` followed by a function call
}
diff --git a/src/tools/clippy/tests/ui/unwrap_or.stderr b/src/tools/clippy/tests/ui/unwrap_or.stderr
index e384bbbb0..3a32092f7 100644
--- a/src/tools/clippy/tests/ui/unwrap_or.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_or.stderr
@@ -5,9 +5,10 @@ LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| "Fail".to_string())`
|
= note: `-D clippy::or-fun-call` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]`
error: use of `unwrap_or` followed by a function call
- --> $DIR/unwrap_or.rs:9:47
+ --> $DIR/unwrap_or.rs:11:47
|
LL | let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| "Fail".to_string())`
diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed
index acdb96942..8d5d34175 100644
--- a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed
+++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::unwrap_or_default)]
#![allow(dead_code)]
#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]
@@ -132,4 +130,34 @@ fn method_call_with_deref() {
let _ = inner_map.entry(0).or_default();
}
+fn missing_suggested_method() {
+ #[derive(Copy, Clone)]
+ struct S<T>(T);
+
+ impl<T> S<T> {
+ fn or_insert_with(&mut self, default: impl FnOnce() -> T) -> &mut T {
+ &mut self.0
+ }
+
+ fn or_insert(&mut self, default: T) -> &mut T {
+ &mut self.0
+ }
+
+ fn unwrap_or_else(self, default: impl FnOnce() -> T) -> T {
+ self.0
+ }
+
+ fn unwrap_or(self, default: T) -> T {
+ self.0
+ }
+ }
+
+ // Don't lint when or_default/unwrap_or_default do not exist on the type
+ let mut s = S(1);
+ s.or_insert_with(Default::default);
+ s.or_insert(Default::default());
+ s.unwrap_or_else(Default::default);
+ s.unwrap_or(Default::default());
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs
index 55ccd00e1..adbcb4b44 100644
--- a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs
+++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::unwrap_or_default)]
#![allow(dead_code)]
#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]
@@ -132,4 +130,34 @@ fn method_call_with_deref() {
let _ = inner_map.entry(0).or_insert_with(Default::default);
}
+fn missing_suggested_method() {
+ #[derive(Copy, Clone)]
+ struct S<T>(T);
+
+ impl<T> S<T> {
+ fn or_insert_with(&mut self, default: impl FnOnce() -> T) -> &mut T {
+ &mut self.0
+ }
+
+ fn or_insert(&mut self, default: T) -> &mut T {
+ &mut self.0
+ }
+
+ fn unwrap_or_else(self, default: impl FnOnce() -> T) -> T {
+ self.0
+ }
+
+ fn unwrap_or(self, default: T) -> T {
+ self.0
+ }
+ }
+
+ // Don't lint when or_default/unwrap_or_default do not exist on the type
+ let mut s = S(1);
+ s.or_insert_with(Default::default);
+ s.or_insert(Default::default());
+ s.unwrap_or_else(Default::default);
+ s.unwrap_or(Default::default());
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr b/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr
index af662c6de..3119aba19 100644
--- a/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.stderr
@@ -1,97 +1,98 @@
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:48:14
+ --> $DIR/unwrap_or_else_default.rs:46:14
|
LL | with_new.unwrap_or_else(Vec::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
|
= note: `-D clippy::unwrap-or-default` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:62:23
+ --> $DIR/unwrap_or_else_default.rs:60:23
|
LL | with_real_default.unwrap_or_else(<HasDefaultAndDuplicate as Default>::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:65:24
+ --> $DIR/unwrap_or_else_default.rs:63:24
|
LL | with_default_trait.unwrap_or_else(Default::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:68:23
+ --> $DIR/unwrap_or_else_default.rs:66:23
|
LL | with_default_type.unwrap_or_else(u64::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:71:23
+ --> $DIR/unwrap_or_else_default.rs:69:23
|
LL | with_default_type.unwrap_or_else(Vec::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:74:18
+ --> $DIR/unwrap_or_else_default.rs:72:18
|
LL | empty_string.unwrap_or_else(|| "".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:78:12
+ --> $DIR/unwrap_or_else_default.rs:76:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:81:12
+ --> $DIR/unwrap_or_else_default.rs:79:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:84:12
+ --> $DIR/unwrap_or_else_default.rs:82:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:87:12
+ --> $DIR/unwrap_or_else_default.rs:85:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:90:12
+ --> $DIR/unwrap_or_else_default.rs:88:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:93:12
+ --> $DIR/unwrap_or_else_default.rs:91:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:96:12
+ --> $DIR/unwrap_or_else_default.rs:94:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:99:12
+ --> $DIR/unwrap_or_else_default.rs:97:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> $DIR/unwrap_or_else_default.rs:115:12
+ --> $DIR/unwrap_or_else_default.rs:113:12
|
LL | option.unwrap_or_else(Vec::new).push(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `or_insert_with` to construct default value
- --> $DIR/unwrap_or_else_default.rs:132:32
+ --> $DIR/unwrap_or_else_default.rs:130:32
|
LL | let _ = inner_map.entry(0).or_insert_with(Default::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
diff --git a/src/tools/clippy/tests/ui/upper_case_acronyms.fixed b/src/tools/clippy/tests/ui/upper_case_acronyms.fixed
new file mode 100644
index 000000000..460567b09
--- /dev/null
+++ b/src/tools/clippy/tests/ui/upper_case_acronyms.fixed
@@ -0,0 +1,62 @@
+#![warn(clippy::upper_case_acronyms)]
+
+struct HTTPResponse; // not linted by default, but with cfg option
+
+struct CString; // not linted
+
+enum Flags {
+ NS, // not linted
+ Cwr,
+ //~^ ERROR: name `CWR` contains a capitalized acronym
+ //~| NOTE: `-D clippy::upper-case-acronyms` implied by `-D warnings`
+ Ece,
+ //~^ ERROR: name `ECE` contains a capitalized acronym
+ Urg,
+ //~^ ERROR: name `URG` contains a capitalized acronym
+ Ack,
+ //~^ ERROR: name `ACK` contains a capitalized acronym
+ Psh,
+ //~^ ERROR: name `PSH` contains a capitalized acronym
+ Rst,
+ //~^ ERROR: name `RST` contains a capitalized acronym
+ Syn,
+ //~^ ERROR: name `SYN` contains a capitalized acronym
+ Fin,
+ //~^ ERROR: name `FIN` contains a capitalized acronym
+}
+
+// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of
+// `GccLlvmSomething`
+struct GCCLLVMSomething;
+
+// public items must not be linted
+pub struct NOWARNINGHERE;
+pub struct ALSONoWarningHERE;
+
+// enum variants should not be linted if the num is pub
+pub enum ParseError<T> {
+ YDB(u8),
+ Utf8(std::string::FromUtf8Error),
+ Parse(T, String),
+}
+
+// private, do lint here
+enum ParseErrorPrivate<T> {
+ Wasd(u8),
+ //~^ ERROR: name `WASD` contains a capitalized acronym
+ Utf8(std::string::FromUtf8Error),
+ Parse(T, String),
+}
+
+// do lint here
+struct Json;
+//~^ ERROR: name `JSON` contains a capitalized acronym
+
+// do lint here
+enum Yaml {
+ //~^ ERROR: name `YAML` contains a capitalized acronym
+ Num(u32),
+ Str(String),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/upper_case_acronyms.rs b/src/tools/clippy/tests/ui/upper_case_acronyms.rs
index 9b7c2f28e..6a20aee62 100644
--- a/src/tools/clippy/tests/ui/upper_case_acronyms.rs
+++ b/src/tools/clippy/tests/ui/upper_case_acronyms.rs
@@ -7,13 +7,22 @@ struct CString; // not linted
enum Flags {
NS, // not linted
CWR,
+ //~^ ERROR: name `CWR` contains a capitalized acronym
+ //~| NOTE: `-D clippy::upper-case-acronyms` implied by `-D warnings`
ECE,
+ //~^ ERROR: name `ECE` contains a capitalized acronym
URG,
+ //~^ ERROR: name `URG` contains a capitalized acronym
ACK,
+ //~^ ERROR: name `ACK` contains a capitalized acronym
PSH,
+ //~^ ERROR: name `PSH` contains a capitalized acronym
RST,
+ //~^ ERROR: name `RST` contains a capitalized acronym
SYN,
+ //~^ ERROR: name `SYN` contains a capitalized acronym
FIN,
+ //~^ ERROR: name `FIN` contains a capitalized acronym
}
// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of
@@ -34,15 +43,18 @@ pub enum ParseError<T> {
// private, do lint here
enum ParseErrorPrivate<T> {
WASD(u8),
+ //~^ ERROR: name `WASD` contains a capitalized acronym
Utf8(std::string::FromUtf8Error),
Parse(T, String),
}
// do lint here
struct JSON;
+//~^ ERROR: name `JSON` contains a capitalized acronym
// do lint here
enum YAML {
+ //~^ ERROR: name `YAML` contains a capitalized acronym
Num(u32),
Str(String),
}
diff --git a/src/tools/clippy/tests/ui/upper_case_acronyms.stderr b/src/tools/clippy/tests/ui/upper_case_acronyms.stderr
index 74082ec16..c57b325e9 100644
--- a/src/tools/clippy/tests/ui/upper_case_acronyms.stderr
+++ b/src/tools/clippy/tests/ui/upper_case_acronyms.stderr
@@ -5,63 +5,64 @@ LL | CWR,
| ^^^ help: consider making the acronym lowercase, except the initial letter: `Cwr`
|
= note: `-D clippy::upper-case-acronyms` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::upper_case_acronyms)]`
error: name `ECE` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:10:5
+ --> $DIR/upper_case_acronyms.rs:12:5
|
LL | ECE,
| ^^^ help: consider making the acronym lowercase, except the initial letter: `Ece`
error: name `URG` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:11:5
+ --> $DIR/upper_case_acronyms.rs:14:5
|
LL | URG,
| ^^^ help: consider making the acronym lowercase, except the initial letter: `Urg`
error: name `ACK` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:12:5
+ --> $DIR/upper_case_acronyms.rs:16:5
|
LL | ACK,
| ^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ack`
error: name `PSH` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:13:5
+ --> $DIR/upper_case_acronyms.rs:18:5
|
LL | PSH,
| ^^^ help: consider making the acronym lowercase, except the initial letter: `Psh`
error: name `RST` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:14:5
+ --> $DIR/upper_case_acronyms.rs:20:5
|
LL | RST,
| ^^^ help: consider making the acronym lowercase, except the initial letter: `Rst`
error: name `SYN` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:15:5
+ --> $DIR/upper_case_acronyms.rs:22:5
|
LL | SYN,
| ^^^ help: consider making the acronym lowercase, except the initial letter: `Syn`
error: name `FIN` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:16:5
+ --> $DIR/upper_case_acronyms.rs:24:5
|
LL | FIN,
| ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin`
error: name `WASD` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:36:5
+ --> $DIR/upper_case_acronyms.rs:45:5
|
LL | WASD(u8),
| ^^^^ help: consider making the acronym lowercase, except the initial letter: `Wasd`
error: name `JSON` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:42:8
+ --> $DIR/upper_case_acronyms.rs:52:8
|
LL | struct JSON;
| ^^^^ help: consider making the acronym lowercase, except the initial letter: `Json`
error: name `YAML` contains a capitalized acronym
- --> $DIR/upper_case_acronyms.rs:45:6
+ --> $DIR/upper_case_acronyms.rs:56:6
|
LL | enum YAML {
| ^^^^ help: consider making the acronym lowercase, except the initial letter: `Yaml`
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index 4179f21c5..787dd3ec7 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![warn(clippy::use_self)]
#![allow(dead_code, unreachable_code)]
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index 01a36def9..39e182fae 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![warn(clippy::use_self)]
#![allow(dead_code, unreachable_code)]
diff --git a/src/tools/clippy/tests/ui/use_self.stderr b/src/tools/clippy/tests/ui/use_self.stderr
index 48364c40c..a1d4eac5d 100644
--- a/src/tools/clippy/tests/ui/use_self.stderr
+++ b/src/tools/clippy/tests/ui/use_self.stderr
@@ -1,253 +1,254 @@
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:22:21
+ --> $DIR/use_self.rs:21:21
|
LL | fn new() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
|
= note: `-D clippy::use-self` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::use_self)]`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:23:13
+ --> $DIR/use_self.rs:22:13
|
LL | Foo {}
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:25:22
+ --> $DIR/use_self.rs:24:22
|
LL | fn test() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:26:13
+ --> $DIR/use_self.rs:25:13
|
LL | Foo::new()
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:31:25
+ --> $DIR/use_self.rs:30:25
|
LL | fn default() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:32:13
+ --> $DIR/use_self.rs:31:13
|
LL | Foo::new()
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:97:24
+ --> $DIR/use_self.rs:96:24
|
LL | fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:97:55
+ --> $DIR/use_self.rs:96:55
|
LL | fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:112:13
+ --> $DIR/use_self.rs:111:13
|
LL | TS(0)
| ^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:147:29
+ --> $DIR/use_self.rs:146:29
|
LL | fn bar() -> Bar {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:148:21
+ --> $DIR/use_self.rs:147:21
|
LL | Bar { foo: Foo {} }
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:159:21
+ --> $DIR/use_self.rs:158:21
|
LL | fn baz() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:160:13
+ --> $DIR/use_self.rs:159:13
|
LL | Foo {}
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:177:21
+ --> $DIR/use_self.rs:176:21
|
LL | let _ = Enum::B(42);
| ^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:178:21
+ --> $DIR/use_self.rs:177:21
|
LL | let _ = Enum::C { field: true };
| ^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:179:21
+ --> $DIR/use_self.rs:178:21
|
LL | let _ = Enum::A;
| ^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:221:13
+ --> $DIR/use_self.rs:220:13
|
LL | nested::A::fun_1();
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:222:13
+ --> $DIR/use_self.rs:221:13
|
LL | nested::A::A;
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:224:13
+ --> $DIR/use_self.rs:223:13
|
LL | nested::A {};
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:243:13
+ --> $DIR/use_self.rs:242:13
|
LL | TestStruct::from_something()
| ^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:257:25
+ --> $DIR/use_self.rs:256:25
|
LL | async fn g() -> S {
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:258:13
+ --> $DIR/use_self.rs:257:13
|
LL | S {}
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:262:16
+ --> $DIR/use_self.rs:261:16
|
LL | &p[S::A..S::B]
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:262:22
+ --> $DIR/use_self.rs:261:22
|
LL | &p[S::A..S::B]
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:285:29
+ --> $DIR/use_self.rs:284:29
|
LL | fn foo(value: T) -> Foo<T> {
| ^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:286:13
+ --> $DIR/use_self.rs:285:13
|
LL | Foo::<T> { value }
| ^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:458:13
+ --> $DIR/use_self.rs:457:13
|
LL | A::new::<submod::B>(submod::B {})
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:495:13
+ --> $DIR/use_self.rs:494:13
|
LL | S2::new()
| ^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:532:17
+ --> $DIR/use_self.rs:531:17
|
LL | Foo::Bar => unimplemented!(),
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:533:17
+ --> $DIR/use_self.rs:532:17
|
LL | Foo::Baz => unimplemented!(),
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:539:20
+ --> $DIR/use_self.rs:538:20
|
LL | if let Foo::Bar = self {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:563:17
+ --> $DIR/use_self.rs:562:17
|
LL | Something::Num(n) => *n,
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:564:17
+ --> $DIR/use_self.rs:563:17
|
LL | Something::TupleNums(n, _m) => *n,
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:565:17
+ --> $DIR/use_self.rs:564:17
|
LL | Something::StructNums { one, two: _ } => *one,
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:571:17
+ --> $DIR/use_self.rs:570:17
|
LL | crate::issue8845::Something::Num(n) => *n,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:572:17
+ --> $DIR/use_self.rs:571:17
|
LL | crate::issue8845::Something::TupleNums(n, _m) => *n,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:573:17
+ --> $DIR/use_self.rs:572:17
|
LL | crate::issue8845::Something::StructNums { one, two: _ } => *one,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:589:17
+ --> $DIR/use_self.rs:588:17
|
LL | let Foo(x) = self;
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:594:17
+ --> $DIR/use_self.rs:593:17
|
LL | let crate::issue8845::Foo(x) = self;
| ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:601:17
+ --> $DIR/use_self.rs:600:17
|
LL | let Bar { x, .. } = self;
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:606:17
+ --> $DIR/use_self.rs:605:17
|
LL | let crate::issue8845::Bar { x, .. } = self;
| ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:645:17
+ --> $DIR/use_self.rs:644:17
|
LL | E::A => {},
| ^ help: use the applicable keyword: `Self`
diff --git a/src/tools/clippy/tests/ui/use_self_trait.fixed b/src/tools/clippy/tests/ui/use_self_trait.fixed
index 20138a29f..2758ec7ac 100644
--- a/src/tools/clippy/tests/ui/use_self_trait.fixed
+++ b/src/tools/clippy/tests/ui/use_self_trait.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::use_self)]
#![allow(dead_code)]
#![allow(clippy::should_implement_trait, clippy::boxed_local)]
diff --git a/src/tools/clippy/tests/ui/use_self_trait.rs b/src/tools/clippy/tests/ui/use_self_trait.rs
index bf697b01a..31031e8f5 100644
--- a/src/tools/clippy/tests/ui/use_self_trait.rs
+++ b/src/tools/clippy/tests/ui/use_self_trait.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![warn(clippy::use_self)]
#![allow(dead_code)]
#![allow(clippy::should_implement_trait, clippy::boxed_local)]
diff --git a/src/tools/clippy/tests/ui/use_self_trait.stderr b/src/tools/clippy/tests/ui/use_self_trait.stderr
index 6257f802d..71a227174 100644
--- a/src/tools/clippy/tests/ui/use_self_trait.stderr
+++ b/src/tools/clippy/tests/ui/use_self_trait.stderr
@@ -1,97 +1,98 @@
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:21:18
+ --> $DIR/use_self_trait.rs:19:18
|
LL | fn refs(p1: &Bad) -> &Bad {
| ^^^ help: use the applicable keyword: `Self`
|
= note: `-D clippy::use-self` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::use_self)]`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:21:27
+ --> $DIR/use_self_trait.rs:19:27
|
LL | fn refs(p1: &Bad) -> &Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:25:33
+ --> $DIR/use_self_trait.rs:23:33
|
LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:25:49
+ --> $DIR/use_self_trait.rs:23:49
|
LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:29:26
+ --> $DIR/use_self_trait.rs:27:26
|
LL | fn mut_refs(p1: &mut Bad) -> &mut Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:29:39
+ --> $DIR/use_self_trait.rs:27:39
|
LL | fn mut_refs(p1: &mut Bad) -> &mut Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:33:24
+ --> $DIR/use_self_trait.rs:31:24
|
LL | fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:33:42
+ --> $DIR/use_self_trait.rs:31:42
|
LL | fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:35:16
+ --> $DIR/use_self_trait.rs:33:16
|
LL | fn vals(_: Bad) -> Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:35:24
+ --> $DIR/use_self_trait.rs:33:24
|
LL | fn vals(_: Bad) -> Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:36:9
+ --> $DIR/use_self_trait.rs:34:9
|
LL | Bad
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:41:19
+ --> $DIR/use_self_trait.rs:39:19
|
LL | type Output = Bad;
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:43:23
+ --> $DIR/use_self_trait.rs:41:23
|
LL | fn mul(self, rhs: Bad) -> Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:43:31
+ --> $DIR/use_self_trait.rs:41:31
|
LL | fn mul(self, rhs: Bad) -> Bad {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:50:9
+ --> $DIR/use_self_trait.rs:48:9
|
LL | Bad
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self_trait.rs:147:13
+ --> $DIR/use_self_trait.rs:145:13
|
LL | std::fmt::Error // Should lint
| ^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.rs b/src/tools/clippy/tests/ui/used_underscore_binding.rs
index 879e2e24a..a8f404b14 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.rs
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.rs
@@ -1,6 +1,5 @@
-//@aux-build:proc_macro_derive.rs:proc-macro
-#![feature(rustc_private)]
-#![warn(clippy::all)]
+//@aux-build:proc_macro_derive.rs
+#![feature(rustc_private, lint_reasons)]
#![warn(clippy::used_underscore_binding)]
#![allow(clippy::disallowed_names, clippy::eq_op, clippy::uninlined_format_args)]
@@ -107,6 +106,31 @@ async fn await_desugaring() {
.await
}
+struct PhantomField<T> {
+ _marker: std::marker::PhantomData<T>,
+}
+
+impl<T> std::fmt::Debug for PhantomField<T> {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ f.debug_struct("PhantomField").field("_marker", &self._marker).finish()
+ }
+}
+
+struct AllowedField {
+ #[allow(clippy::used_underscore_binding)]
+ _allowed: usize,
+}
+
+struct ExpectedField {
+ #[expect(clippy::used_underscore_binding)]
+ _expected: usize,
+}
+
+fn lint_levels(allowed: AllowedField, expected: ExpectedField) {
+ let _ = allowed._allowed;
+ let _ = expected._expected;
+}
+
fn main() {
let foo = 0u32;
// tests of unused_underscore lint
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.stderr b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
index 875fafe43..78d827981 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.stderr
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
@@ -1,40 +1,76 @@
error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
- --> $DIR/used_underscore_binding.rs:24:5
+ --> $DIR/used_underscore_binding.rs:23:5
|
LL | _foo + 1
| ^^^^
|
+note: `_foo` is defined here
+ --> $DIR/used_underscore_binding.rs:22:22
+ |
+LL | fn prefix_underscore(_foo: u32) -> u32 {
+ | ^^^^
= note: `-D clippy::used-underscore-binding` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::used_underscore_binding)]`
error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
- --> $DIR/used_underscore_binding.rs:29:20
+ --> $DIR/used_underscore_binding.rs:28:20
|
LL | println!("{}", _foo);
| ^^^^
+ |
+note: `_foo` is defined here
+ --> $DIR/used_underscore_binding.rs:27:24
+ |
+LL | fn in_macro_or_desugar(_foo: u32) {
+ | ^^^^
error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
- --> $DIR/used_underscore_binding.rs:30:16
+ --> $DIR/used_underscore_binding.rs:29:16
|
LL | assert_eq!(_foo, _foo);
| ^^^^
+ |
+note: `_foo` is defined here
+ --> $DIR/used_underscore_binding.rs:27:24
+ |
+LL | fn in_macro_or_desugar(_foo: u32) {
+ | ^^^^
error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
- --> $DIR/used_underscore_binding.rs:30:22
+ --> $DIR/used_underscore_binding.rs:29:22
|
LL | assert_eq!(_foo, _foo);
| ^^^^
+ |
+note: `_foo` is defined here
+ --> $DIR/used_underscore_binding.rs:27:24
+ |
+LL | fn in_macro_or_desugar(_foo: u32) {
+ | ^^^^
error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
- --> $DIR/used_underscore_binding.rs:43:5
+ --> $DIR/used_underscore_binding.rs:42:5
|
LL | s._underscore_field += 1;
| ^^^^^^^^^^^^^^^^^^^
+ |
+note: `_underscore_field` is defined here
+ --> $DIR/used_underscore_binding.rs:36:5
+ |
+LL | _underscore_field: u32,
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
- --> $DIR/used_underscore_binding.rs:104:16
+ --> $DIR/used_underscore_binding.rs:103:16
|
LL | uses_i(_i);
| ^^
+ |
+note: `_i` is defined here
+ --> $DIR/used_underscore_binding.rs:102:13
+ |
+LL | let _i = 5;
+ | ^^
error: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/useless_asref.fixed b/src/tools/clippy/tests/ui/useless_asref.fixed
index e42731f9b..f6770558b 100644
--- a/src/tools/clippy/tests/ui/useless_asref.fixed
+++ b/src/tools/clippy/tests/ui/useless_asref.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::useless_asref)]
#![allow(
clippy::explicit_auto_deref,
diff --git a/src/tools/clippy/tests/ui/useless_asref.rs b/src/tools/clippy/tests/ui/useless_asref.rs
index 50c9990bb..099621807 100644
--- a/src/tools/clippy/tests/ui/useless_asref.rs
+++ b/src/tools/clippy/tests/ui/useless_asref.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![deny(clippy::useless_asref)]
#![allow(
clippy::explicit_auto_deref,
diff --git a/src/tools/clippy/tests/ui/useless_asref.stderr b/src/tools/clippy/tests/ui/useless_asref.stderr
index c97851ac6..163eb7b14 100644
--- a/src/tools/clippy/tests/ui/useless_asref.stderr
+++ b/src/tools/clippy/tests/ui/useless_asref.stderr
@@ -1,71 +1,71 @@
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:47:18
+ --> $DIR/useless_asref.rs:46:18
|
LL | foo_rstr(rstr.as_ref());
| ^^^^^^^^^^^^^ help: try: `rstr`
|
note: the lint level is defined here
- --> $DIR/useless_asref.rs:2:9
+ --> $DIR/useless_asref.rs:1:9
|
LL | #![deny(clippy::useless_asref)]
| ^^^^^^^^^^^^^^^^^^^^^
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:49:20
+ --> $DIR/useless_asref.rs:48:20
|
LL | foo_rslice(rslice.as_ref());
| ^^^^^^^^^^^^^^^ help: try: `rslice`
error: this call to `as_mut` does nothing
- --> $DIR/useless_asref.rs:53:21
+ --> $DIR/useless_asref.rs:52:21
|
LL | foo_mrslice(mrslice.as_mut());
| ^^^^^^^^^^^^^^^^ help: try: `mrslice`
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:55:20
+ --> $DIR/useless_asref.rs:54:20
|
LL | foo_rslice(mrslice.as_ref());
| ^^^^^^^^^^^^^^^^ help: try: `mrslice`
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:62:20
+ --> $DIR/useless_asref.rs:61:20
|
LL | foo_rslice(rrrrrslice.as_ref());
| ^^^^^^^^^^^^^^^^^^^ help: try: `rrrrrslice`
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:64:18
+ --> $DIR/useless_asref.rs:63:18
|
LL | foo_rstr(rrrrrstr.as_ref());
| ^^^^^^^^^^^^^^^^^ help: try: `rrrrrstr`
error: this call to `as_mut` does nothing
- --> $DIR/useless_asref.rs:69:21
+ --> $DIR/useless_asref.rs:68:21
|
LL | foo_mrslice(mrrrrrslice.as_mut());
| ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice`
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:71:20
+ --> $DIR/useless_asref.rs:70:20
|
LL | foo_rslice(mrrrrrslice.as_ref());
| ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice`
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:75:16
+ --> $DIR/useless_asref.rs:74:16
|
LL | foo_rrrrmr((&&&&MoreRef).as_ref());
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&&&&MoreRef)`
error: this call to `as_mut` does nothing
- --> $DIR/useless_asref.rs:125:13
+ --> $DIR/useless_asref.rs:124:13
|
LL | foo_mrt(mrt.as_mut());
| ^^^^^^^^^^^^ help: try: `mrt`
error: this call to `as_ref` does nothing
- --> $DIR/useless_asref.rs:127:12
+ --> $DIR/useless_asref.rs:126:12
|
LL | foo_rt(mrt.as_ref());
| ^^^^^^^^^^^^ help: try: `mrt`
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index 8e77ec444..98a2bed0e 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![allow(unused)]
#![warn(clippy::useless_attribute)]
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index 27498d9bc..c5e324717 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -1,5 +1,4 @@
-//@run-rustfix
-//@aux-build:proc_macro_derive.rs:proc-macro
+//@aux-build:proc_macro_derive.rs
#![allow(unused)]
#![warn(clippy::useless_attribute)]
diff --git a/src/tools/clippy/tests/ui/useless_attribute.stderr b/src/tools/clippy/tests/ui/useless_attribute.stderr
index a7ea0df22..e65c59aba 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.stderr
+++ b/src/tools/clippy/tests/ui/useless_attribute.stderr
@@ -1,19 +1,20 @@
error: useless lint attribute
- --> $DIR/useless_attribute.rs:9:1
+ --> $DIR/useless_attribute.rs:8:1
|
LL | #[allow(dead_code)]
| ^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(dead_code)]`
|
= note: `-D clippy::useless-attribute` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::useless_attribute)]`
error: useless lint attribute
- --> $DIR/useless_attribute.rs:10:1
+ --> $DIR/useless_attribute.rs:9:1
|
LL | #[cfg_attr(feature = "cargo-clippy", allow(dead_code))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![cfg_attr(feature = "cargo-clippy", allow(dead_code)`
error: useless lint attribute
- --> $DIR/useless_attribute.rs:21:5
+ --> $DIR/useless_attribute.rs:20:5
|
LL | #[allow(clippy::almost_swapped)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(clippy::almost_swapped)]`
diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed
index 53d8a5a9f..ed8387b7e 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.fixed
+++ b/src/tools/clippy/tests/ui/useless_conversion.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::useless_conversion)]
#![allow(clippy::needless_if, clippy::unnecessary_wraps)]
@@ -153,6 +151,8 @@ fn main() {
let _ = s3;
let s4: Foo<'a'> = Foo;
let _ = vec![s4, s4, s4].into_iter();
+
+ issue11300::bar();
}
#[allow(dead_code)]
@@ -198,6 +198,95 @@ fn explicit_into_iter_fn_arg() {
b(macro_generated!());
}
+mod issue11300 {
+ pub fn foo<I>(i: I)
+ where
+ I: IntoIterator<Item = i32> + ExactSizeIterator,
+ {
+ assert_eq!(i.len(), 3);
+ }
+
+ trait Helper<T: ?Sized> {}
+ impl Helper<i32> for [i32; 3] {}
+ impl Helper<i32> for std::array::IntoIter<i32, 3> {}
+ impl Helper<()> for std::array::IntoIter<i32, 3> {}
+
+ fn foo2<X: ?Sized, I>(_: I)
+ where
+ I: IntoIterator<Item = i32> + Helper<X>,
+ {
+ }
+
+ trait Helper2<T> {}
+ impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}
+ impl Helper2<[i32; 3]> for i32 {}
+ fn foo3<I>(_: I)
+ where
+ I: IntoIterator<Item = i32>,
+ i32: Helper2<I>,
+ {
+ }
+
+ pub fn bar() {
+ // This should not trigger the lint:
+ // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be
+ // removed and is not useless.
+ foo([1, 2, 3].into_iter());
+
+ // This should trigger the lint, receiver type [i32; 3] also implements `Helper`
+ foo2::<i32, _>([1, 2, 3]);
+
+ // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,
+ // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).
+ foo2::<(), _>([1, 2, 3].into_iter());
+
+ // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,
+ // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unncessary.
+ foo3([1, 2, 3]);
+ }
+
+ fn ice() {
+ struct S1;
+ impl S1 {
+ pub fn foo<I: IntoIterator>(&self, _: I) {}
+ }
+
+ S1.foo([1, 2]);
+
+ // ICE that occured in itertools
+ trait Itertools {
+ fn interleave_shortest<J>(self, other: J)
+ where
+ J: IntoIterator,
+ Self: Sized;
+ }
+ impl<I: Iterator> Itertools for I {
+ fn interleave_shortest<J>(self, other: J)
+ where
+ J: IntoIterator,
+ Self: Sized,
+ {
+ }
+ }
+ let v0: Vec<i32> = vec![0, 2, 4];
+ let v1: Vec<i32> = vec![1, 3, 5, 7];
+ v0.into_iter().interleave_shortest(v1);
+
+ trait TraitWithLifetime<'a> {}
+ impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}
+
+ struct Helper;
+ impl<'a> Helper {
+ fn with_lt<I>(&self, _: I)
+ where
+ I: IntoIterator + TraitWithLifetime<'a>,
+ {
+ }
+ }
+ Helper.with_lt([&1, &2].into_iter());
+ }
+}
+
#[derive(Copy, Clone)]
struct Foo<const C: char>;
diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs
index 51ba49873..991a7762f 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.rs
+++ b/src/tools/clippy/tests/ui/useless_conversion.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![deny(clippy::useless_conversion)]
#![allow(clippy::needless_if, clippy::unnecessary_wraps)]
@@ -153,6 +151,8 @@ fn main() {
let _ = Foo::<'a'>::from(s3);
let s4: Foo<'a'> = Foo;
let _ = vec![s4, s4, s4].into_iter().into_iter();
+
+ issue11300::bar();
}
#[allow(dead_code)]
@@ -198,6 +198,95 @@ fn explicit_into_iter_fn_arg() {
b(macro_generated!());
}
+mod issue11300 {
+ pub fn foo<I>(i: I)
+ where
+ I: IntoIterator<Item = i32> + ExactSizeIterator,
+ {
+ assert_eq!(i.len(), 3);
+ }
+
+ trait Helper<T: ?Sized> {}
+ impl Helper<i32> for [i32; 3] {}
+ impl Helper<i32> for std::array::IntoIter<i32, 3> {}
+ impl Helper<()> for std::array::IntoIter<i32, 3> {}
+
+ fn foo2<X: ?Sized, I>(_: I)
+ where
+ I: IntoIterator<Item = i32> + Helper<X>,
+ {
+ }
+
+ trait Helper2<T> {}
+ impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}
+ impl Helper2<[i32; 3]> for i32 {}
+ fn foo3<I>(_: I)
+ where
+ I: IntoIterator<Item = i32>,
+ i32: Helper2<I>,
+ {
+ }
+
+ pub fn bar() {
+ // This should not trigger the lint:
+ // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be
+ // removed and is not useless.
+ foo([1, 2, 3].into_iter());
+
+ // This should trigger the lint, receiver type [i32; 3] also implements `Helper`
+ foo2::<i32, _>([1, 2, 3].into_iter());
+
+ // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,
+ // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).
+ foo2::<(), _>([1, 2, 3].into_iter());
+
+ // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,
+ // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unncessary.
+ foo3([1, 2, 3].into_iter());
+ }
+
+ fn ice() {
+ struct S1;
+ impl S1 {
+ pub fn foo<I: IntoIterator>(&self, _: I) {}
+ }
+
+ S1.foo([1, 2].into_iter());
+
+ // ICE that occured in itertools
+ trait Itertools {
+ fn interleave_shortest<J>(self, other: J)
+ where
+ J: IntoIterator,
+ Self: Sized;
+ }
+ impl<I: Iterator> Itertools for I {
+ fn interleave_shortest<J>(self, other: J)
+ where
+ J: IntoIterator,
+ Self: Sized,
+ {
+ }
+ }
+ let v0: Vec<i32> = vec![0, 2, 4];
+ let v1: Vec<i32> = vec![1, 3, 5, 7];
+ v0.into_iter().interleave_shortest(v1.into_iter());
+
+ trait TraitWithLifetime<'a> {}
+ impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}
+
+ struct Helper;
+ impl<'a> Helper {
+ fn with_lt<I>(&self, _: I)
+ where
+ I: IntoIterator + TraitWithLifetime<'a>,
+ {
+ }
+ }
+ Helper.with_lt([&1, &2].into_iter());
+ }
+}
+
#[derive(Copy, Clone)]
struct Foo<const C: char>;
diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr
index 6f7dc01d2..c1f8b6b4a 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion.stderr
@@ -1,119 +1,119 @@
error: useless conversion to the same type: `T`
- --> $DIR/useless_conversion.rs:7:13
+ --> $DIR/useless_conversion.rs:5:13
|
LL | let _ = T::from(val);
| ^^^^^^^^^^^^ help: consider removing `T::from()`: `val`
|
note: the lint level is defined here
- --> $DIR/useless_conversion.rs:3:9
+ --> $DIR/useless_conversion.rs:1:9
|
LL | #![deny(clippy::useless_conversion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: useless conversion to the same type: `T`
- --> $DIR/useless_conversion.rs:8:5
+ --> $DIR/useless_conversion.rs:6:5
|
LL | val.into()
| ^^^^^^^^^^ help: consider removing `.into()`: `val`
error: useless conversion to the same type: `i32`
- --> $DIR/useless_conversion.rs:20:22
+ --> $DIR/useless_conversion.rs:18:22
|
LL | let _: i32 = 0i32.into();
| ^^^^^^^^^^^ help: consider removing `.into()`: `0i32`
error: useless conversion to the same type: `std::str::Lines<'_>`
- --> $DIR/useless_conversion.rs:50:22
+ --> $DIR/useless_conversion.rs:48:22
|
LL | if Some("ok") == lines.into_iter().next() {}
| ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines`
error: useless conversion to the same type: `std::str::Lines<'_>`
- --> $DIR/useless_conversion.rs:55:21
+ --> $DIR/useless_conversion.rs:53:21
|
LL | let mut lines = text.lines().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
error: useless conversion to the same type: `std::str::Lines<'_>`
- --> $DIR/useless_conversion.rs:61:22
+ --> $DIR/useless_conversion.rs:59:22
|
LL | if Some("ok") == text.lines().into_iter().next() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
error: useless conversion to the same type: `std::ops::Range<i32>`
- --> $DIR/useless_conversion.rs:67:13
+ --> $DIR/useless_conversion.rs:65:13
|
LL | let _ = NUMBERS.into_iter().next();
| ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
error: useless conversion to the same type: `std::ops::Range<i32>`
- --> $DIR/useless_conversion.rs:72:17
+ --> $DIR/useless_conversion.rs:70:17
|
LL | let mut n = NUMBERS.into_iter();
| ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion.rs:134:21
+ --> $DIR/useless_conversion.rs:132:21
|
LL | let _: String = "foo".to_string().into();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion.rs:135:21
+ --> $DIR/useless_conversion.rs:133:21
|
LL | let _: String = From::from("foo".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion.rs:136:13
+ --> $DIR/useless_conversion.rs:134:13
|
LL | let _ = String::from("foo".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion.rs:137:13
+ --> $DIR/useless_conversion.rs:135:13
|
LL | let _ = String::from(format!("A: {:04}", 123));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)`
error: useless conversion to the same type: `std::str::Lines<'_>`
- --> $DIR/useless_conversion.rs:138:13
+ --> $DIR/useless_conversion.rs:136:13
|
LL | let _ = "".lines().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()`
error: useless conversion to the same type: `std::vec::IntoIter<i32>`
- --> $DIR/useless_conversion.rs:139:13
+ --> $DIR/useless_conversion.rs:137:13
|
LL | let _ = vec![1, 2, 3].into_iter().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion.rs:140:21
+ --> $DIR/useless_conversion.rs:138:21
|
LL | let _: String = format!("Hello {}", "world").into();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
error: useless conversion to the same type: `i32`
- --> $DIR/useless_conversion.rs:145:13
+ --> $DIR/useless_conversion.rs:143:13
|
LL | let _ = i32::from(a + b) * 3;
| ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)`
error: useless conversion to the same type: `Foo<'a'>`
- --> $DIR/useless_conversion.rs:151:23
+ --> $DIR/useless_conversion.rs:149:23
|
LL | let _: Foo<'a'> = s2.into();
| ^^^^^^^^^ help: consider removing `.into()`: `s2`
error: useless conversion to the same type: `Foo<'a'>`
- --> $DIR/useless_conversion.rs:153:13
+ --> $DIR/useless_conversion.rs:151:13
|
LL | let _ = Foo::<'a'>::from(s3);
| ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3`
error: useless conversion to the same type: `std::vec::IntoIter<Foo<'a'>>`
- --> $DIR/useless_conversion.rs:155:13
+ --> $DIR/useless_conversion.rs:153:13
|
LL | let _ = vec![s4, s4, s4].into_iter().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()`
@@ -178,5 +178,53 @@ note: this parameter accepts any `IntoIterator`, so you don't need to call `.int
LL | fn b<T: IntoIterator<Item = i32>>(_: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 24 previous errors
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+ --> $DIR/useless_conversion.rs:237:24
+ |
+LL | foo2::<i32, _>([1, 2, 3].into_iter());
+ | ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+ |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+ --> $DIR/useless_conversion.rs:216:12
+ |
+LL | I: IntoIterator<Item = i32> + Helper<X>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+ --> $DIR/useless_conversion.rs:245:14
+ |
+LL | foo3([1, 2, 3].into_iter());
+ | ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+ |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+ --> $DIR/useless_conversion.rs:225:12
+ |
+LL | I: IntoIterator<Item = i32>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+ --> $DIR/useless_conversion.rs:254:16
+ |
+LL | S1.foo([1, 2].into_iter());
+ | ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]`
+ |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+ --> $DIR/useless_conversion.rs:251:27
+ |
+LL | pub fn foo<I: IntoIterator>(&self, _: I) {}
+ | ^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+ --> $DIR/useless_conversion.rs:273:44
+ |
+LL | v0.into_iter().interleave_shortest(v1.into_iter());
+ | ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1`
+ |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+ --> $DIR/useless_conversion.rs:260:20
+ |
+LL | J: IntoIterator,
+ | ^^^^^^^^^^^^
+
+error: aborting due to 28 previous errors
diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.rs b/src/tools/clippy/tests/ui/useless_conversion_try.rs
index ec0512ce2..a5feefbe0 100644
--- a/src/tools/clippy/tests/ui/useless_conversion_try.rs
+++ b/src/tools/clippy/tests/ui/useless_conversion_try.rs
@@ -3,7 +3,9 @@
fn test_generic<T: Copy>(val: T) -> T {
let _ = T::try_from(val).unwrap();
+ //~^ ERROR: useless conversion to the same type: `T`
val.try_into().unwrap()
+ //~^ ERROR: useless conversion to the same type: `T`
}
fn test_generic2<T: Copy + Into<i32> + Into<U>, U: From<T>>(val: T) {
@@ -26,12 +28,19 @@ fn main() {
let _: String = "foo".try_into().unwrap();
}
let _: String = "foo".to_string().try_into().unwrap();
+ //~^ ERROR: useless conversion to the same type: `std::string::String`
let _: String = TryFrom::try_from("foo".to_string()).unwrap();
+ //~^ ERROR: useless conversion to the same type: `std::string::String`
let _ = String::try_from("foo".to_string()).unwrap();
+ //~^ ERROR: useless conversion to the same type: `std::string::String`
let _ = String::try_from(format!("A: {:04}", 123)).unwrap();
+ //~^ ERROR: useless conversion to the same type: `std::string::String`
let _: String = format!("Hello {}", "world").try_into().unwrap();
+ //~^ ERROR: useless conversion to the same type: `std::string::String`
let _: String = String::new().try_into().unwrap();
+ //~^ ERROR: useless conversion to the same type: `std::string::String`
let _: String = match String::from("_").try_into() {
+ //~^ ERROR: useless conversion to the same type: `std::string::String`
Ok(a) => a,
Err(_) => String::new(),
};
diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.stderr b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
index 54189f8d2..938bfb523 100644
--- a/src/tools/clippy/tests/ui/useless_conversion_try.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
@@ -12,7 +12,7 @@ LL | #![deny(clippy::useless_conversion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: useless conversion to the same type: `T`
- --> $DIR/useless_conversion_try.rs:6:5
+ --> $DIR/useless_conversion_try.rs:7:5
|
LL | val.try_into().unwrap()
| ^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL | val.try_into().unwrap()
= help: consider removing `.try_into()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion_try.rs:28:21
+ --> $DIR/useless_conversion_try.rs:30:21
|
LL | let _: String = "foo".to_string().try_into().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -28,7 +28,7 @@ LL | let _: String = "foo".to_string().try_into().unwrap();
= help: consider removing `.try_into()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion_try.rs:29:21
+ --> $DIR/useless_conversion_try.rs:32:21
|
LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap();
= help: consider removing `TryFrom::try_from()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion_try.rs:30:13
+ --> $DIR/useless_conversion_try.rs:34:13
|
LL | let _ = String::try_from("foo".to_string()).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL | let _ = String::try_from("foo".to_string()).unwrap();
= help: consider removing `String::try_from()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion_try.rs:31:13
+ --> $DIR/useless_conversion_try.rs:36:13
|
LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,7 +52,7 @@ LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap();
= help: consider removing `String::try_from()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion_try.rs:32:21
+ --> $DIR/useless_conversion_try.rs:38:21
|
LL | let _: String = format!("Hello {}", "world").try_into().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap();
= help: consider removing `.try_into()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion_try.rs:33:21
+ --> $DIR/useless_conversion_try.rs:40:21
|
LL | let _: String = String::new().try_into().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -68,7 +68,7 @@ LL | let _: String = String::new().try_into().unwrap();
= help: consider removing `.try_into()`
error: useless conversion to the same type: `std::string::String`
- --> $DIR/useless_conversion_try.rs:34:27
+ --> $DIR/useless_conversion_try.rs:42:27
|
LL | let _: String = match String::from("_").try_into() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/vec.fixed b/src/tools/clippy/tests/ui/vec.fixed
index 7a7d0026f..bcbca971a 100644
--- a/src/tools/clippy/tests/ui/vec.fixed
+++ b/src/tools/clippy/tests/ui/vec.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::useless_vec)]
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
@@ -121,6 +120,7 @@ fn issue11075() {
stringify!($e)
};
}
+ #[allow(clippy::never_loop)]
for _string in [repro!(true), repro!(null)] {
unimplemented!();
}
diff --git a/src/tools/clippy/tests/ui/vec.rs b/src/tools/clippy/tests/ui/vec.rs
index cbe7685b4..087425585 100644
--- a/src/tools/clippy/tests/ui/vec.rs
+++ b/src/tools/clippy/tests/ui/vec.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::useless_vec)]
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
@@ -121,6 +120,7 @@ fn issue11075() {
stringify!($e)
};
}
+ #[allow(clippy::never_loop)]
for _string in vec![repro!(true), repro!(null)] {
unimplemented!();
}
diff --git a/src/tools/clippy/tests/ui/vec.stderr b/src/tools/clippy/tests/ui/vec.stderr
index 8f6d2a1df..fc261838f 100644
--- a/src/tools/clippy/tests/ui/vec.stderr
+++ b/src/tools/clippy/tests/ui/vec.stderr
@@ -1,85 +1,86 @@
error: useless use of `vec!`
- --> $DIR/vec.rs:31:14
+ --> $DIR/vec.rs:30:14
|
LL | on_slice(&vec![]);
| ^^^^^^^ help: you can use a slice directly: `&[]`
|
= note: `-D clippy::useless-vec` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`
error: useless use of `vec!`
- --> $DIR/vec.rs:33:18
+ --> $DIR/vec.rs:32:18
|
LL | on_mut_slice(&mut vec![]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&mut []`
error: useless use of `vec!`
- --> $DIR/vec.rs:35:14
+ --> $DIR/vec.rs:34:14
|
LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:37:18
+ --> $DIR/vec.rs:36:18
|
LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:39:14
+ --> $DIR/vec.rs:38:14
|
LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:41:18
+ --> $DIR/vec.rs:40:18
|
LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:43:14
+ --> $DIR/vec.rs:42:14
|
LL | on_slice(&vec!(1, 2));
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:45:18
+ --> $DIR/vec.rs:44:18
|
LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:47:14
+ --> $DIR/vec.rs:46:14
|
LL | on_slice(&vec![1; 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:49:18
+ --> $DIR/vec.rs:48:18
|
LL | on_mut_slice(&mut vec![1; 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]`
error: useless use of `vec!`
- --> $DIR/vec.rs:75:19
+ --> $DIR/vec.rs:74:19
|
LL | let _x: i32 = vec![1, 2, 3].iter().sum();
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!`
- --> $DIR/vec.rs:78:17
+ --> $DIR/vec.rs:77:17
|
LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!`
- --> $DIR/vec.rs:84:22
+ --> $DIR/vec.rs:83:22
|
LL | let _x: &[i32] = &vec![1, 2, 3];
| ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
error: useless use of `vec!`
- --> $DIR/vec.rs:86:14
+ --> $DIR/vec.rs:85:14
|
LL | for _ in vec![1, 2, 3] {}
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
diff --git a/src/tools/clippy/tests/ui/vec_box_sized.fixed b/src/tools/clippy/tests/ui/vec_box_sized.fixed
index 0d0f710b5..4363d2224 100644
--- a/src/tools/clippy/tests/ui/vec_box_sized.fixed
+++ b/src/tools/clippy/tests/ui/vec_box_sized.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
struct SizedStruct(i32);
@@ -51,4 +49,9 @@ mod inner_mod {
}
}
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn in_closure() {
+ let _ = |_: Vec<Box<dyn ToString>>| {};
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/vec_box_sized.rs b/src/tools/clippy/tests/ui/vec_box_sized.rs
index fd3a7543e..f4e27fe4b 100644
--- a/src/tools/clippy/tests/ui/vec_box_sized.rs
+++ b/src/tools/clippy/tests/ui/vec_box_sized.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(dead_code)]
struct SizedStruct(i32);
@@ -51,4 +49,9 @@ mod inner_mod {
}
}
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn in_closure() {
+ let _ = |_: Vec<Box<dyn ToString>>| {};
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/vec_box_sized.stderr b/src/tools/clippy/tests/ui/vec_box_sized.stderr
index c518267f0..9118f284b 100644
--- a/src/tools/clippy/tests/ui/vec_box_sized.stderr
+++ b/src/tools/clippy/tests/ui/vec_box_sized.stderr
@@ -1,37 +1,38 @@
error: `Vec<T>` is already on the heap, the boxing is unnecessary
- --> $DIR/vec_box_sized.rs:12:14
+ --> $DIR/vec_box_sized.rs:10:14
|
LL | const C: Vec<Box<i32>> = Vec::new();
| ^^^^^^^^^^^^^ help: try: `Vec<i32>`
|
= note: `-D clippy::vec-box` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::vec_box)]`
error: `Vec<T>` is already on the heap, the boxing is unnecessary
- --> $DIR/vec_box_sized.rs:13:15
+ --> $DIR/vec_box_sized.rs:11:15
|
LL | static S: Vec<Box<i32>> = Vec::new();
| ^^^^^^^^^^^^^ help: try: `Vec<i32>`
error: `Vec<T>` is already on the heap, the boxing is unnecessary
- --> $DIR/vec_box_sized.rs:16:21
+ --> $DIR/vec_box_sized.rs:14:21
|
LL | sized_type: Vec<Box<SizedStruct>>,
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<SizedStruct>`
error: `Vec<T>` is already on the heap, the boxing is unnecessary
- --> $DIR/vec_box_sized.rs:19:14
+ --> $DIR/vec_box_sized.rs:17:14
|
LL | struct A(Vec<Box<SizedStruct>>);
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<SizedStruct>`
error: `Vec<T>` is already on the heap, the boxing is unnecessary
- --> $DIR/vec_box_sized.rs:20:18
+ --> $DIR/vec_box_sized.rs:18:18
|
LL | struct B(Vec<Vec<Box<(u32)>>>);
| ^^^^^^^^^^^^^^^ help: try: `Vec<u32>`
error: `Vec<T>` is already on the heap, the boxing is unnecessary
- --> $DIR/vec_box_sized.rs:48:23
+ --> $DIR/vec_box_sized.rs:46:23
|
LL | pub fn f() -> Vec<Box<S>> {
| ^^^^^^^^^^^ help: try: `Vec<S>`
diff --git a/src/tools/clippy/tests/ui/vec_init_then_push.rs b/src/tools/clippy/tests/ui/vec_init_then_push.rs
index 8dd098a5b..1c60a75c5 100644
--- a/src/tools/clippy/tests/ui/vec_init_then_push.rs
+++ b/src/tools/clippy/tests/ui/vec_init_then_push.rs
@@ -1,14 +1,18 @@
#![allow(unused_variables)]
#![warn(clippy::vec_init_then_push)]
-
+//@no-rustfix
fn main() {
let mut def_err: Vec<u32> = Default::default();
+ //~^ ERROR: calls to `push` immediately after creation
+ //~| NOTE: `-D clippy::vec-init-then-push` implied by `-D warnings`
def_err.push(0);
let mut new_err = Vec::<u32>::new();
+ //~^ ERROR: calls to `push` immediately after creation
new_err.push(1);
let mut cap_err = Vec::with_capacity(2);
+ //~^ ERROR: calls to `push` immediately after creation
cap_err.push(0);
cap_err.push(1);
cap_err.push(2);
@@ -21,6 +25,7 @@ fn main() {
cap_ok.push(0);
new_err = Vec::new();
+ //~^ ERROR: calls to `push` immediately after creation
new_err.push(0);
let mut vec = Vec::new();
@@ -71,6 +76,7 @@ fn _cond_push(x: bool) -> Vec<u32> {
fn _push_then_edit(x: u32) -> Vec<u32> {
let mut v = Vec::new();
+ //~^ ERROR: calls to `push` immediately after creation
v.push(x);
v.push(1);
v[0] = v[1] + 5;
@@ -79,6 +85,7 @@ fn _push_then_edit(x: u32) -> Vec<u32> {
fn _cond_push_with_large_start(x: bool) -> Vec<u32> {
let mut v = Vec::new();
+ //~^ ERROR: calls to `push` immediately after creation
v.push(0);
v.push(1);
v.push(0);
@@ -92,6 +99,7 @@ fn _cond_push_with_large_start(x: bool) -> Vec<u32> {
}
let mut v2 = Vec::new();
+ //~^ ERROR: calls to `push` immediately after creation
v2.push(0);
v2.push(1);
v2.push(0);
@@ -107,6 +115,7 @@ fn _cond_push_with_large_start(x: bool) -> Vec<u32> {
fn f() {
let mut v = Vec::new();
+ //~^ ERROR: calls to `push` immediately after creation
v.push((0i32, 0i32));
let y = v[0].0.abs();
}
diff --git a/src/tools/clippy/tests/ui/vec_init_then_push.stderr b/src/tools/clippy/tests/ui/vec_init_then_push.stderr
index a9da1c520..978201bd1 100644
--- a/src/tools/clippy/tests/ui/vec_init_then_push.stderr
+++ b/src/tools/clippy/tests/ui/vec_init_then_push.stderr
@@ -2,70 +2,78 @@ error: calls to `push` immediately after creation
--> $DIR/vec_init_then_push.rs:5:5
|
LL | / let mut def_err: Vec<u32> = Default::default();
+LL | |
+LL | |
LL | | def_err.push(0);
| |____________________^ help: consider using the `vec![]` macro: `let def_err: Vec<u32> = vec![..];`
|
= note: `-D clippy::vec-init-then-push` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::vec_init_then_push)]`
error: calls to `push` immediately after creation
- --> $DIR/vec_init_then_push.rs:8:5
+ --> $DIR/vec_init_then_push.rs:10:5
|
LL | / let mut new_err = Vec::<u32>::new();
+LL | |
LL | | new_err.push(1);
| |____________________^ help: consider using the `vec![]` macro: `let mut new_err = vec![..];`
error: calls to `push` immediately after creation
- --> $DIR/vec_init_then_push.rs:11:5
+ --> $DIR/vec_init_then_push.rs:14:5
|
LL | / let mut cap_err = Vec::with_capacity(2);
+LL | |
LL | | cap_err.push(0);
LL | | cap_err.push(1);
LL | | cap_err.push(2);
| |____________________^ help: consider using the `vec![]` macro: `let mut cap_err = vec![..];`
error: calls to `push` immediately after creation
- --> $DIR/vec_init_then_push.rs:23:5
+ --> $DIR/vec_init_then_push.rs:27:5
|
LL | / new_err = Vec::new();
+LL | |
LL | | new_err.push(0);
| |____________________^ help: consider using the `vec![]` macro: `new_err = vec![..];`
error: calls to `push` immediately after creation
- --> $DIR/vec_init_then_push.rs:73:5
+ --> $DIR/vec_init_then_push.rs:78:5
|
LL | / let mut v = Vec::new();
+LL | |
LL | | v.push(x);
LL | | v.push(1);
| |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];`
error: calls to `push` immediately after creation
- --> $DIR/vec_init_then_push.rs:81:5
+ --> $DIR/vec_init_then_push.rs:87:5
|
LL | / let mut v = Vec::new();
+LL | |
LL | | v.push(0);
LL | | v.push(1);
-LL | | v.push(0);
... |
LL | | v.push(1);
LL | | v.push(0);
| |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];`
error: calls to `push` immediately after creation
- --> $DIR/vec_init_then_push.rs:94:5
+ --> $DIR/vec_init_then_push.rs:101:5
|
LL | / let mut v2 = Vec::new();
+LL | |
LL | | v2.push(0);
LL | | v2.push(1);
-LL | | v2.push(0);
... |
LL | | v2.push(1);
LL | | v2.push(0);
| |_______________^ help: consider using the `vec![]` macro: `let mut v2 = vec![..];`
error: calls to `push` immediately after creation
- --> $DIR/vec_init_then_push.rs:109:5
+ --> $DIR/vec_init_then_push.rs:117:5
|
LL | / let mut v = Vec::new();
+LL | |
LL | | v.push((0i32, 0i32));
| |_________________________^ help: consider using the `vec![]` macro: `let v = vec![..];`
diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.fixed b/src/tools/clippy/tests/ui/vec_resize_to_zero.fixed
new file mode 100644
index 000000000..b4c2d8209
--- /dev/null
+++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.fixed
@@ -0,0 +1,20 @@
+#![warn(clippy::vec_resize_to_zero)]
+
+fn main() {
+ let mut v = vec![1, 2, 3, 4, 5];
+
+ // applicable here
+ v.clear();
+ //~^ ERROR: emptying a vector with `resize`
+
+ // not applicable
+ v.resize(2, 5);
+
+ let mut v = vec!["foo", "bar", "baz"];
+
+ // applicable here, but only implemented for integer literals for now
+ v.resize(0, "bar");
+
+ // not applicable
+ v.resize(2, "bar")
+}
diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.rs b/src/tools/clippy/tests/ui/vec_resize_to_zero.rs
index a8307e741..5b11c940f 100644
--- a/src/tools/clippy/tests/ui/vec_resize_to_zero.rs
+++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.rs
@@ -5,6 +5,7 @@ fn main() {
// applicable here
v.resize(0, 5);
+ //~^ ERROR: emptying a vector with `resize`
// not applicable
v.resize(2, 5);
diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
index 8851e9f38..715c9923b 100644
--- a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
+++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
@@ -8,6 +8,7 @@ LL | v.resize(0, 5);
|
= help: the arguments may be inverted...
= note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::vec_resize_to_zero)]`
error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/verbose_file_reads.rs b/src/tools/clippy/tests/ui/verbose_file_reads.rs
index df267e987..9dd4f4e1d 100644
--- a/src/tools/clippy/tests/ui/verbose_file_reads.rs
+++ b/src/tools/clippy/tests/ui/verbose_file_reads.rs
@@ -21,8 +21,10 @@ fn main() -> std::io::Result<()> {
let mut f = File::open(path)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
+ //~^ ERROR: use of `File::read_to_end`
// ...and this
let mut string_buffer = String::new();
f.read_to_string(&mut string_buffer)?;
+ //~^ ERROR: use of `File::read_to_string`
Ok(())
}
diff --git a/src/tools/clippy/tests/ui/verbose_file_reads.stderr b/src/tools/clippy/tests/ui/verbose_file_reads.stderr
index 44266c7c0..04e1aedf7 100644
--- a/src/tools/clippy/tests/ui/verbose_file_reads.stderr
+++ b/src/tools/clippy/tests/ui/verbose_file_reads.stderr
@@ -6,9 +6,10 @@ LL | f.read_to_end(&mut buffer)?;
|
= help: consider using `fs::read` instead
= note: `-D clippy::verbose-file-reads` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::verbose_file_reads)]`
error: use of `File::read_to_string`
- --> $DIR/verbose_file_reads.rs:26:5
+ --> $DIR/verbose_file_reads.rs:27:5
|
LL | f.read_to_string(&mut string_buffer)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.rs b/src/tools/clippy/tests/ui/vtable_address_comparisons.rs
index 99c3f468f..75647c027 100644
--- a/src/tools/clippy/tests/ui/vtable_address_comparisons.rs
+++ b/src/tools/clippy/tests/ui/vtable_address_comparisons.rs
@@ -12,16 +12,24 @@ fn main() {
// These should fail:
let _ = a == b;
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
let _ = a != b;
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
let _ = a < b;
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
let _ = a <= b;
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
let _ = a > b;
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
let _ = a >= b;
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
ptr::eq(a, b);
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
let a = &1 as &dyn Debug;
let b = &1 as &dyn Debug;
ptr::eq(a, b);
+ //~^ ERROR: comparing trait object pointers compares a non-unique vtable address
// These should be fine:
let a = &1;
diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr
index 7b866d274..83c82f379 100644
--- a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr
@@ -6,9 +6,10 @@ LL | let _ = a == b;
|
= help: consider extracting and comparing data pointers only
= note: `-D clippy::vtable-address-comparisons` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::vtable_address_comparisons)]`
error: comparing trait object pointers compares a non-unique vtable address
- --> $DIR/vtable_address_comparisons.rs:15:13
+ --> $DIR/vtable_address_comparisons.rs:16:13
|
LL | let _ = a != b;
| ^^^^^^
@@ -16,7 +17,7 @@ LL | let _ = a != b;
= help: consider extracting and comparing data pointers only
error: comparing trait object pointers compares a non-unique vtable address
- --> $DIR/vtable_address_comparisons.rs:16:13
+ --> $DIR/vtable_address_comparisons.rs:18:13
|
LL | let _ = a < b;
| ^^^^^
@@ -24,7 +25,7 @@ LL | let _ = a < b;
= help: consider extracting and comparing data pointers only
error: comparing trait object pointers compares a non-unique vtable address
- --> $DIR/vtable_address_comparisons.rs:17:13
+ --> $DIR/vtable_address_comparisons.rs:20:13
|
LL | let _ = a <= b;
| ^^^^^^
@@ -32,7 +33,7 @@ LL | let _ = a <= b;
= help: consider extracting and comparing data pointers only
error: comparing trait object pointers compares a non-unique vtable address
- --> $DIR/vtable_address_comparisons.rs:18:13
+ --> $DIR/vtable_address_comparisons.rs:22:13
|
LL | let _ = a > b;
| ^^^^^
@@ -40,7 +41,7 @@ LL | let _ = a > b;
= help: consider extracting and comparing data pointers only
error: comparing trait object pointers compares a non-unique vtable address
- --> $DIR/vtable_address_comparisons.rs:19:13
+ --> $DIR/vtable_address_comparisons.rs:24:13
|
LL | let _ = a >= b;
| ^^^^^^
@@ -48,7 +49,7 @@ LL | let _ = a >= b;
= help: consider extracting and comparing data pointers only
error: comparing trait object pointers compares a non-unique vtable address
- --> $DIR/vtable_address_comparisons.rs:20:5
+ --> $DIR/vtable_address_comparisons.rs:26:5
|
LL | ptr::eq(a, b);
| ^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | ptr::eq(a, b);
= help: consider extracting and comparing data pointers only
error: comparing trait object pointers compares a non-unique vtable address
- --> $DIR/vtable_address_comparisons.rs:24:5
+ --> $DIR/vtable_address_comparisons.rs:31:5
|
LL | ptr::eq(a, b);
| ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/while_let_loop.rs b/src/tools/clippy/tests/ui/while_let_loop.rs
index 5b8075731..fa5325beb 100644
--- a/src/tools/clippy/tests/ui/while_let_loop.rs
+++ b/src/tools/clippy/tests/ui/while_let_loop.rs
@@ -1,9 +1,11 @@
#![warn(clippy::while_let_loop)]
#![allow(clippy::uninlined_format_args)]
-
+//@no-rustfix
fn main() {
let y = Some(true);
loop {
+ //~^ ERROR: this loop could be written as a `while let` loop
+ //~| NOTE: `-D clippy::while-let-loop` implied by `-D warnings`
if let Some(_x) = y {
let _v = 1;
} else {
@@ -21,6 +23,7 @@ fn main() {
}
loop {
+ //~^ ERROR: this loop could be written as a `while let` loop
match y {
Some(_x) => true,
None => break,
@@ -28,6 +31,7 @@ fn main() {
}
loop {
+ //~^ ERROR: this loop could be written as a `while let` loop
let x = match y {
Some(x) => x,
None => break,
@@ -37,6 +41,7 @@ fn main() {
}
loop {
+ //~^ ERROR: this loop could be written as a `while let` loop
let x = match y {
Some(x) => x,
None => break,
@@ -67,6 +72,7 @@ fn main() {
// #675, this used to have a wrong suggestion
loop {
+ //~^ ERROR: this loop could be written as a `while let` loop
let (e, l) = match "".split_whitespace().next() {
Some(word) => (word.is_empty(), word.len()),
None => break,
diff --git a/src/tools/clippy/tests/ui/while_let_loop.stderr b/src/tools/clippy/tests/ui/while_let_loop.stderr
index 04808c0b3..db887dc65 100644
--- a/src/tools/clippy/tests/ui/while_let_loop.stderr
+++ b/src/tools/clippy/tests/ui/while_let_loop.stderr
@@ -2,20 +2,22 @@ error: this loop could be written as a `while let` loop
--> $DIR/while_let_loop.rs:6:5
|
LL | / loop {
+LL | |
+LL | |
LL | | if let Some(_x) = y {
-LL | | let _v = 1;
-LL | | } else {
-LL | | break;
+... |
LL | | }
LL | | }
| |_____^ help: try: `while let Some(_x) = y { .. }`
|
= note: `-D clippy::while-let-loop` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]`
error: this loop could be written as a `while let` loop
- --> $DIR/while_let_loop.rs:23:5
+ --> $DIR/while_let_loop.rs:25:5
|
LL | / loop {
+LL | |
LL | | match y {
LL | | Some(_x) => true,
LL | | None => break,
@@ -24,36 +26,36 @@ LL | | }
| |_____^ help: try: `while let Some(_x) = y { .. }`
error: this loop could be written as a `while let` loop
- --> $DIR/while_let_loop.rs:30:5
+ --> $DIR/while_let_loop.rs:33:5
|
LL | / loop {
+LL | |
LL | | let x = match y {
LL | | Some(x) => x,
-LL | | None => break,
... |
LL | | let _str = "foo";
LL | | }
| |_____^ help: try: `while let Some(x) = y { .. }`
error: this loop could be written as a `while let` loop
- --> $DIR/while_let_loop.rs:39:5
+ --> $DIR/while_let_loop.rs:43:5
|
LL | / loop {
+LL | |
LL | | let x = match y {
LL | | Some(x) => x,
-LL | | None => break,
... |
LL | | }
LL | | }
| |_____^ help: try: `while let Some(x) = y { .. }`
error: this loop could be written as a `while let` loop
- --> $DIR/while_let_loop.rs:69:5
+ --> $DIR/while_let_loop.rs:74:5
|
LL | / loop {
+LL | |
LL | | let (e, l) = match "".split_whitespace().next() {
LL | | Some(word) => (word.is_empty(), word.len()),
-LL | | None => break,
... |
LL | | let _ = (e, l);
LL | | }
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
index 41a380ab8..d628d2227 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::while_let_on_iterator)]
#![allow(dead_code, unreachable_code, unused_mut)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.rs b/src/tools/clippy/tests/ui/while_let_on_iterator.rs
index 4c6433880..525dbbaaa 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.rs
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
#![warn(clippy::while_let_on_iterator)]
#![allow(dead_code, unreachable_code, unused_mut)]
#![allow(
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.stderr b/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
index 3236765e1..cdc83b816 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
@@ -1,157 +1,158 @@
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:16:5
+ --> $DIR/while_let_on_iterator.rs:15:5
|
LL | while let Option::Some(x) = iter.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`
|
= note: `-D clippy::while-let-on-iterator` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::while_let_on_iterator)]`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:21:5
+ --> $DIR/while_let_on_iterator.rs:20:5
|
LL | while let Some(x) = iter.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:26:5
+ --> $DIR/while_let_on_iterator.rs:25:5
|
LL | while let Some(_) = iter.next() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in iter`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:102:9
+ --> $DIR/while_let_on_iterator.rs:101:9
|
LL | while let Some([..]) = it.next() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [..] in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:109:9
+ --> $DIR/while_let_on_iterator.rs:108:9
|
LL | while let Some([_x]) = it.next() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [_x] in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:122:9
+ --> $DIR/while_let_on_iterator.rs:121:9
|
LL | while let Some(x @ [_]) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x @ [_] in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:142:9
+ --> $DIR/while_let_on_iterator.rs:141:9
|
LL | while let Some(_) = y.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in y`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:199:9
+ --> $DIR/while_let_on_iterator.rs:198:9
|
LL | while let Some(m) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:210:5
+ --> $DIR/while_let_on_iterator.rs:209:5
|
LL | while let Some(n) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:212:9
+ --> $DIR/while_let_on_iterator.rs:211:9
|
LL | while let Some(m) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:221:9
+ --> $DIR/while_let_on_iterator.rs:220:9
|
LL | while let Some(m) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:230:9
+ --> $DIR/while_let_on_iterator.rs:229:9
|
LL | while let Some(m) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:247:9
+ --> $DIR/while_let_on_iterator.rs:246:9
|
LL | while let Some(m) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:262:13
+ --> $DIR/while_let_on_iterator.rs:261:13
|
LL | while let Some(i) = self.0.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:294:13
+ --> $DIR/while_let_on_iterator.rs:293:13
|
LL | while let Some(i) = self.0.0.0.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.0.0.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:323:5
+ --> $DIR/while_let_on_iterator.rs:322:5
|
LL | while let Some(n) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:335:9
+ --> $DIR/while_let_on_iterator.rs:334:9
|
LL | while let Some(x) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:349:5
+ --> $DIR/while_let_on_iterator.rs:348:5
|
LL | while let Some(x) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:360:5
+ --> $DIR/while_let_on_iterator.rs:359:5
|
LL | while let Some(x) = it.0.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.0.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:395:5
+ --> $DIR/while_let_on_iterator.rs:394:5
|
LL | while let Some(x) = s.x.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in s.x.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:402:5
+ --> $DIR/while_let_on_iterator.rs:401:5
|
LL | while let Some(x) = x[0].next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in x[0].by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:410:9
+ --> $DIR/while_let_on_iterator.rs:409:9
|
LL | while let Some(x) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:420:9
+ --> $DIR/while_let_on_iterator.rs:419:9
|
LL | while let Some(x) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:430:9
+ --> $DIR/while_let_on_iterator.rs:429:9
|
LL | while let Some(x) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:440:9
+ --> $DIR/while_let_on_iterator.rs:439:9
|
LL | while let Some(x) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:450:5
+ --> $DIR/while_let_on_iterator.rs:449:5
|
LL | while let Some(..) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`
diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.rs b/src/tools/clippy/tests/ui/wild_in_or_pats.rs
index ad600f125..f8bb31b83 100644
--- a/src/tools/clippy/tests/ui/wild_in_or_pats.rs
+++ b/src/tools/clippy/tests/ui/wild_in_or_pats.rs
@@ -6,6 +6,7 @@ fn main() {
dbg!("matched a");
},
"bar" | _ => {
+ //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway
dbg!("matched (bar or) wild");
},
};
@@ -14,6 +15,7 @@ fn main() {
dbg!("matched a");
},
"bar" | "bar2" | _ => {
+ //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway
dbg!("matched (bar or bar2 or) wild");
},
};
@@ -22,6 +24,7 @@ fn main() {
dbg!("matched a");
},
_ | "bar" | _ => {
+ //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway
dbg!("matched (bar or) wild");
},
};
@@ -30,6 +33,7 @@ fn main() {
dbg!("matched a");
},
_ | "bar" => {
+ //~^ ERROR: wildcard pattern covers any other pattern as it will match anyway
dbg!("matched (bar or) wild");
},
};
diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
index bd5860f45..4cfa0d993 100644
--- a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
+++ b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
@@ -6,9 +6,10 @@ LL | "bar" | _ => {
|
= help: consider handling `_` separately
= note: `-D clippy::wildcard-in-or-patterns` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wildcard_in_or_patterns)]`
error: wildcard pattern covers any other pattern as it will match anyway
- --> $DIR/wild_in_or_pats.rs:16:9
+ --> $DIR/wild_in_or_pats.rs:17:9
|
LL | "bar" | "bar2" | _ => {
| ^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | "bar" | "bar2" | _ => {
= help: consider handling `_` separately
error: wildcard pattern covers any other pattern as it will match anyway
- --> $DIR/wild_in_or_pats.rs:24:9
+ --> $DIR/wild_in_or_pats.rs:26:9
|
LL | _ | "bar" | _ => {
| ^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | _ | "bar" | _ => {
= help: consider handling `_` separately
error: wildcard pattern covers any other pattern as it will match anyway
- --> $DIR/wild_in_or_pats.rs:32:9
+ --> $DIR/wild_in_or_pats.rs:35:9
|
LL | _ | "bar" => {
| ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed
index ccb40acfb..108941573 100644
--- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:non-exhaustive-enum.rs
#![deny(clippy::wildcard_enum_match_arm)]
#![allow(dead_code, unreachable_code, unused_variables)]
diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs
index 3ce00b021..d9285c56f 100644
--- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs
+++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
//@aux-build:non-exhaustive-enum.rs
#![deny(clippy::wildcard_enum_match_arm)]
#![allow(dead_code, unreachable_code, unused_variables)]
diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr
index 5b88ae4ab..7fbb16e69 100644
--- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr
@@ -1,41 +1,41 @@
error: wildcard match will also match any future added variants
- --> $DIR/wildcard_enum_match_arm.rs:40:9
+ --> $DIR/wildcard_enum_match_arm.rs:39:9
|
LL | _ => eprintln!("Not red"),
| ^ help: try: `Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`
|
note: the lint level is defined here
- --> $DIR/wildcard_enum_match_arm.rs:3:9
+ --> $DIR/wildcard_enum_match_arm.rs:2:9
|
LL | #![deny(clippy::wildcard_enum_match_arm)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: wildcard match will also match any future added variants
- --> $DIR/wildcard_enum_match_arm.rs:44:9
+ --> $DIR/wildcard_enum_match_arm.rs:43:9
|
LL | _not_red => eprintln!("Not red"),
| ^^^^^^^^ help: try: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan`
error: wildcard match will also match any future added variants
- --> $DIR/wildcard_enum_match_arm.rs:48:9
+ --> $DIR/wildcard_enum_match_arm.rs:47:9
|
LL | not_red => format!("{:?}", not_red),
| ^^^^^^^ help: try: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan`
error: wildcard match will also match any future added variants
- --> $DIR/wildcard_enum_match_arm.rs:64:9
+ --> $DIR/wildcard_enum_match_arm.rs:63:9
|
LL | _ => "No red",
| ^ help: try: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`
error: wildcard matches known variants and will also match future added variants
- --> $DIR/wildcard_enum_match_arm.rs:81:9
+ --> $DIR/wildcard_enum_match_arm.rs:80:9
|
LL | _ => {},
| ^ help: try: `ErrorKind::PermissionDenied | _`
error: wildcard match will also match any future added variants
- --> $DIR/wildcard_enum_match_arm.rs:99:13
+ --> $DIR/wildcard_enum_match_arm.rs:98:13
|
LL | _ => (),
| ^ help: try: `Enum::B | Enum::__Private`
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.fixed b/src/tools/clippy/tests/ui/wildcard_imports.fixed
index 67173f406..2828f9d04 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports.fixed
@@ -1,5 +1,5 @@
//@edition:2015
-//@run-rustfix
+
//@aux-build:wildcard_imports_helper.rs
// the 2015 edition here is needed because edition 2018 changed the module system
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.rs b/src/tools/clippy/tests/ui/wildcard_imports.rs
index 8223b6930..cbe70e505 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.rs
+++ b/src/tools/clippy/tests/ui/wildcard_imports.rs
@@ -1,5 +1,5 @@
//@edition:2015
-//@run-rustfix
+
//@aux-build:wildcard_imports_helper.rs
// the 2015 edition here is needed because edition 2018 changed the module system
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.stderr b/src/tools/clippy/tests/ui/wildcard_imports.stderr
index f7baf234c..3c750815b 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports.stderr
@@ -5,6 +5,7 @@ LL | use crate::fn_mod::*;
| ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
|
= note: `-D clippy::wildcard-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
error: usage of wildcard import
--> $DIR/wildcard_imports.rs:16:5
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
index 8a6337567..b27281fa2 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
@@ -1,7 +1,7 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
+
//@aux-build:wildcard_imports_helper.rs
#![warn(clippy::wildcard_imports)]
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
index af9ae6e78..709a665d6 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
@@ -5,6 +5,7 @@ LL | use crate::fn_mod::*;
| ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
|
= note: `-D clippy::wildcard-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
error: usage of wildcard import
--> $DIR/wildcard_imports_2021.rs:14:5
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
index 8a6337567..b27281fa2 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
@@ -1,7 +1,7 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
+
//@aux-build:wildcard_imports_helper.rs
#![warn(clippy::wildcard_imports)]
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
index af9ae6e78..709a665d6 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
@@ -5,6 +5,7 @@ LL | use crate::fn_mod::*;
| ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
|
= note: `-D clippy::wildcard-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
error: usage of wildcard import
--> $DIR/wildcard_imports_2021.rs:14:5
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs
index 52cd2c828..7dd2103ec 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs
@@ -1,7 +1,7 @@
//@revisions: edition2018 edition2021
//@[edition2018] edition:2018
//@[edition2021] edition:2021
-//@run-rustfix
+
//@aux-build:wildcard_imports_helper.rs
#![warn(clippy::wildcard_imports)]
diff --git a/src/tools/clippy/tests/ui/write_literal.fixed b/src/tools/clippy/tests/ui/write_literal.fixed
new file mode 100644
index 000000000..ee577574d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/write_literal.fixed
@@ -0,0 +1,58 @@
+#![warn(clippy::write_literal)]
+#![allow(clippy::uninlined_format_args, unused_must_use)]
+
+use std::io::Write;
+
+fn main() {
+ let mut v = Vec::new();
+
+ // these should be fine
+ write!(v, "Hello");
+ writeln!(v, "Hello");
+ let world = "world";
+ writeln!(v, "Hello {}", world);
+ writeln!(v, "Hello {world}", world = world);
+ writeln!(v, "3 in hex is {:X}", 3);
+ writeln!(v, "2 + 1 = {:.4}", 3);
+ writeln!(v, "2 + 1 = {:5.4}", 3);
+ writeln!(v, "Debug test {:?}", "hello, world");
+ writeln!(v, "{0:8} {1:>8}", "hello", "world");
+ writeln!(v, "{1:8} {0:>8}", "hello", "world");
+ writeln!(v, "{foo:8} {bar:>8}", foo = "hello", bar = "world");
+ writeln!(v, "{bar:8} {foo:>8}", foo = "hello", bar = "world");
+ writeln!(v, "{number:>width$}", number = 1, width = 6);
+ writeln!(v, "{number:>0width$}", number = 1, width = 6);
+ writeln!(v, "{} of {:b} people know binary, the other half doesn't", 1, 2);
+ writeln!(v, "10 / 4 is {}", 2.5);
+ writeln!(v, "2 + 1 = {}", 3);
+ writeln!(v, "From expansion {}", stringify!(not a string literal));
+
+ // these should throw warnings
+ write!(v, "Hello world");
+ //~^ ERROR: literal with an empty format string
+ //~| NOTE: `-D clippy::write-literal` implied by `-D warnings`
+ writeln!(v, "Hello {} world", world);
+ //~^ ERROR: literal with an empty format string
+ writeln!(v, "Hello world");
+ //~^ ERROR: literal with an empty format string
+ writeln!(v, "a literal {:.4}", 5);
+ //~^ ERROR: literal with an empty format string
+
+ // positional args don't change the fact
+ // that we're using a literal -- this should
+ // throw a warning
+ writeln!(v, "hello world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+ writeln!(v, "world hello");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+
+ // named args shouldn't change anything either
+ writeln!(v, "hello world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+ writeln!(v, "world hello");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+}
diff --git a/src/tools/clippy/tests/ui/write_literal.rs b/src/tools/clippy/tests/ui/write_literal.rs
index 218385ea1..588e8fd41 100644
--- a/src/tools/clippy/tests/ui/write_literal.rs
+++ b/src/tools/clippy/tests/ui/write_literal.rs
@@ -29,17 +29,30 @@ fn main() {
// these should throw warnings
write!(v, "Hello {}", "world");
+ //~^ ERROR: literal with an empty format string
+ //~| NOTE: `-D clippy::write-literal` implied by `-D warnings`
writeln!(v, "Hello {} {}", world, "world");
+ //~^ ERROR: literal with an empty format string
writeln!(v, "Hello {}", "world");
+ //~^ ERROR: literal with an empty format string
writeln!(v, "{} {:.4}", "a literal", 5);
+ //~^ ERROR: literal with an empty format string
// positional args don't change the fact
// that we're using a literal -- this should
// throw a warning
writeln!(v, "{0} {1}", "hello", "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
writeln!(v, "{1} {0}", "hello", "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
// named args shouldn't change anything either
writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
}
diff --git a/src/tools/clippy/tests/ui/write_literal.stderr b/src/tools/clippy/tests/ui/write_literal.stderr
index 8b72c8bd2..372a54cf7 100644
--- a/src/tools/clippy/tests/ui/write_literal.stderr
+++ b/src/tools/clippy/tests/ui/write_literal.stderr
@@ -5,6 +5,7 @@ LL | write!(v, "Hello {}", "world");
| ^^^^^^^
|
= note: `-D clippy::write-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::write_literal)]`
help: try
|
LL - write!(v, "Hello {}", "world");
@@ -12,7 +13,7 @@ LL + write!(v, "Hello world");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:32:39
+ --> $DIR/write_literal.rs:34:39
|
LL | writeln!(v, "Hello {} {}", world, "world");
| ^^^^^^^
@@ -24,7 +25,7 @@ LL + writeln!(v, "Hello {} world", world);
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:33:29
+ --> $DIR/write_literal.rs:36:29
|
LL | writeln!(v, "Hello {}", "world");
| ^^^^^^^
@@ -36,7 +37,7 @@ LL + writeln!(v, "Hello world");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:34:29
+ --> $DIR/write_literal.rs:38:29
|
LL | writeln!(v, "{} {:.4}", "a literal", 5);
| ^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL + writeln!(v, "a literal {:.4}", 5);
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:39:28
+ --> $DIR/write_literal.rs:44:28
|
LL | writeln!(v, "{0} {1}", "hello", "world");
| ^^^^^^^
@@ -60,7 +61,7 @@ LL + writeln!(v, "hello {1}", "world");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:39:37
+ --> $DIR/write_literal.rs:44:37
|
LL | writeln!(v, "{0} {1}", "hello", "world");
| ^^^^^^^
@@ -72,7 +73,7 @@ LL + writeln!(v, "{0} world", "hello");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:40:37
+ --> $DIR/write_literal.rs:47:37
|
LL | writeln!(v, "{1} {0}", "hello", "world");
| ^^^^^^^
@@ -84,7 +85,7 @@ LL + writeln!(v, "world {0}", "hello");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:40:28
+ --> $DIR/write_literal.rs:47:28
|
LL | writeln!(v, "{1} {0}", "hello", "world");
| ^^^^^^^
@@ -96,7 +97,7 @@ LL + writeln!(v, "{1} hello", "world");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:43:38
+ --> $DIR/write_literal.rs:52:38
|
LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^
@@ -108,7 +109,7 @@ LL + writeln!(v, "hello {bar}", bar = "world");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:43:53
+ --> $DIR/write_literal.rs:52:53
|
LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^
@@ -120,7 +121,7 @@ LL + writeln!(v, "{foo} world", foo = "hello");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:44:53
+ --> $DIR/write_literal.rs:55:53
|
LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^
@@ -132,7 +133,7 @@ LL + writeln!(v, "world {foo}", foo = "hello");
|
error: literal with an empty format string
- --> $DIR/write_literal.rs:44:38
+ --> $DIR/write_literal.rs:55:38
|
LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/write_literal_2.rs b/src/tools/clippy/tests/ui/write_literal_2.rs
index 805127e27..aa0c13c13 100644
--- a/src/tools/clippy/tests/ui/write_literal_2.rs
+++ b/src/tools/clippy/tests/ui/write_literal_2.rs
@@ -1,3 +1,4 @@
+//@no-rustfix: overlapping suggestions
#![allow(unused_must_use)]
#![warn(clippy::needless_raw_strings, clippy::write_literal)]
@@ -7,28 +8,50 @@ fn main() {
let mut v = Vec::new();
writeln!(v, "{}", "{hello}");
+ //~^ ERROR: literal with an empty format string
+ //~| NOTE: `-D clippy::write-literal` implied by `-D warnings`
writeln!(v, r"{}", r"{hello}");
+ //~^ ERROR: unnecessary raw string literal
+ //~| NOTE: `-D clippy::needless-raw-strings` implied by `-D warnings`
+ //~| ERROR: literal with an empty format string
writeln!(v, "{}", '\'');
+ //~^ ERROR: literal with an empty format string
writeln!(v, "{}", '"');
+ //~^ ERROR: literal with an empty format string
writeln!(v, r"{}", '"');
+ //~^ ERROR: literal with an empty format string
writeln!(v, r"{}", '\'');
+ //~^ ERROR: literal with an empty format string
writeln!(
v,
"some {}",
"hello \
+ //~^ ERROR: literal with an empty format string
world!"
);
writeln!(
v,
"some {}\
{} \\ {}",
- "1", "2", "3",
+ "1",
+ "2",
+ "3",
+ //~^ ERROR: literal with an empty format string
);
writeln!(v, "{}", "\\");
+ //~^ ERROR: literal with an empty format string
writeln!(v, r"{}", "\\");
+ //~^ ERROR: literal with an empty format string
writeln!(v, r#"{}"#, "\\");
+ //~^ ERROR: literal with an empty format string
writeln!(v, "{}", r"\");
+ //~^ ERROR: literal with an empty format string
writeln!(v, "{}", "\r");
- writeln!(v, r#"{}{}"#, '#', '"'); // hard mode
- writeln!(v, r"{}", "\r"); // should not lint
+ //~^ ERROR: literal with an empty format string
+ // hard mode
+ writeln!(v, r#"{}{}"#, '#', '"');
+ //~^ ERROR: literal with an empty format string
+ //~| ERROR: literal with an empty format string
+ // should not lint
+ writeln!(v, r"{}", "\r");
}
diff --git a/src/tools/clippy/tests/ui/write_literal_2.stderr b/src/tools/clippy/tests/ui/write_literal_2.stderr
index c30ec385b..6d382a267 100644
--- a/src/tools/clippy/tests/ui/write_literal_2.stderr
+++ b/src/tools/clippy/tests/ui/write_literal_2.stderr
@@ -1,18 +1,22 @@
error: unnecessary raw string literal
- --> $DIR/write_literal_2.rs:10:24
+ --> $DIR/write_literal_2.rs:13:24
|
LL | writeln!(v, r"{}", r"{hello}");
- | ^^^^^^^^^^ help: try: `"{hello}"`
+ | -^^^^^^^^^
+ | |
+ | help: use a string literal instead: `"{hello}"`
|
= note: `-D clippy::needless-raw-strings` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]`
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:9:23
+ --> $DIR/write_literal_2.rs:10:23
|
LL | writeln!(v, "{}", "{hello}");
| ^^^^^^^^^
|
= note: `-D clippy::write-literal` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::write_literal)]`
help: try
|
LL - writeln!(v, "{}", "{hello}");
@@ -20,7 +24,7 @@ LL + writeln!(v, "{{hello}}");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:10:24
+ --> $DIR/write_literal_2.rs:13:24
|
LL | writeln!(v, r"{}", r"{hello}");
| ^^^^^^^^^^
@@ -32,19 +36,19 @@ LL + writeln!(v, r"{{hello}}");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:11:23
+ --> $DIR/write_literal_2.rs:17:23
|
-LL | writeln!(v, "{}", '/'');
+LL | writeln!(v, "{}", '\'');
| ^^^^
|
help: try
|
-LL - writeln!(v, "{}", '/'');
+LL - writeln!(v, "{}", '\'');
LL + writeln!(v, "'");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:12:23
+ --> $DIR/write_literal_2.rs:19:23
|
LL | writeln!(v, "{}", '"');
| ^^^
@@ -52,146 +56,149 @@ LL | writeln!(v, "{}", '"');
help: try
|
LL - writeln!(v, "{}", '"');
-LL + writeln!(v, "/"");
+LL + writeln!(v, "\"");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:13:24
+ --> $DIR/write_literal_2.rs:21:24
|
LL | writeln!(v, r"{}", '"');
| ^^^
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:14:24
+ --> $DIR/write_literal_2.rs:23:24
|
-LL | writeln!(v, r"{}", '/'');
+LL | writeln!(v, r"{}", '\'');
| ^^^^
|
help: try
|
-LL - writeln!(v, r"{}", '/'');
+LL - writeln!(v, r"{}", '\'');
LL + writeln!(v, r"'");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:18:9
+ --> $DIR/write_literal_2.rs:28:9
|
-LL | / "hello /
+LL | / "hello \
+LL | |
LL | | world!"
| |_______________^
|
help: try
|
-LL ~ "some hello /
+LL ~ "some hello \
+LL +
LL ~ world!"
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:25:9
+ --> $DIR/write_literal_2.rs:36:9
|
-LL | "1", "2", "3",
+LL | "1",
| ^^^
|
help: try
|
-LL ~ "some 1/
-LL ~ {} // {}", "2", "3",
+LL ~ "some 1\
+LL ~ {} \\ {}",
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:25:14
+ --> $DIR/write_literal_2.rs:37:9
|
-LL | "1", "2", "3",
- | ^^^
+LL | "2",
+ | ^^^
|
help: try
|
-LL ~ 2 // {}",
-LL ~ "1", "3",
+LL ~ 2 \\ {}",
+LL ~ "1",
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:25:19
+ --> $DIR/write_literal_2.rs:38:9
|
-LL | "1", "2", "3",
- | ^^^
+LL | "3",
+ | ^^^
|
help: try
|
-LL ~ {} // 3",
-LL ~ "1", "2",
+LL ~ {} \\ 3",
+LL | "1",
+LL ~ "2",
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:27:23
+ --> $DIR/write_literal_2.rs:41:23
|
-LL | writeln!(v, "{}", "//");
+LL | writeln!(v, "{}", "\\");
| ^^^^
|
help: try
|
-LL - writeln!(v, "{}", "//");
-LL + writeln!(v, "//");
+LL - writeln!(v, "{}", "\\");
+LL + writeln!(v, "\\");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:28:24
+ --> $DIR/write_literal_2.rs:43:24
|
-LL | writeln!(v, r"{}", "//");
+LL | writeln!(v, r"{}", "\\");
| ^^^^
|
help: try
|
-LL - writeln!(v, r"{}", "//");
-LL + writeln!(v, r"/");
+LL - writeln!(v, r"{}", "\\");
+LL + writeln!(v, r"\");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:29:26
+ --> $DIR/write_literal_2.rs:45:26
|
-LL | writeln!(v, r#"{}"#, "//");
+LL | writeln!(v, r#"{}"#, "\\");
| ^^^^
|
help: try
|
-LL - writeln!(v, r#"{}"#, "//");
-LL + writeln!(v, r#"/"#);
+LL - writeln!(v, r#"{}"#, "\\");
+LL + writeln!(v, r#"\"#);
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:30:23
+ --> $DIR/write_literal_2.rs:47:23
|
-LL | writeln!(v, "{}", r"/");
+LL | writeln!(v, "{}", r"\");
| ^^^^
|
help: try
|
-LL - writeln!(v, "{}", r"/");
-LL + writeln!(v, "//");
+LL - writeln!(v, "{}", r"\");
+LL + writeln!(v, "\\");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:31:23
+ --> $DIR/write_literal_2.rs:49:23
|
-LL | writeln!(v, "{}", "/r");
+LL | writeln!(v, "{}", "\r");
| ^^^^
|
help: try
|
-LL - writeln!(v, "{}", "/r");
-LL + writeln!(v, "/r");
+LL - writeln!(v, "{}", "\r");
+LL + writeln!(v, "\r");
|
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:32:28
+ --> $DIR/write_literal_2.rs:52:28
|
-LL | writeln!(v, r#"{}{}"#, '#', '"'); // hard mode
+LL | writeln!(v, r#"{}{}"#, '#', '"');
| ^^^
error: literal with an empty format string
- --> $DIR/write_literal_2.rs:32:33
+ --> $DIR/write_literal_2.rs:52:33
|
-LL | writeln!(v, r#"{}{}"#, '#', '"'); // hard mode
+LL | writeln!(v, r#"{}{}"#, '#', '"');
| ^^^
error: aborting due to 18 previous errors
diff --git a/src/tools/clippy/tests/ui/write_with_newline.fixed b/src/tools/clippy/tests/ui/write_with_newline.fixed
index 0a10e526a..82afff5c8 100644
--- a/src/tools/clippy/tests/ui/write_with_newline.fixed
+++ b/src/tools/clippy/tests/ui/write_with_newline.fixed
@@ -1,5 +1,4 @@
// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934
-// //@run-rustfix
#![allow(clippy::write_literal)]
#![warn(clippy::write_with_newline)]
@@ -11,10 +10,16 @@ fn main() {
// These should fail
writeln!(v, "Hello");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
+ //~| NOTE: `-D clippy::write-with-newline` implied by `-D warnings`
writeln!(v, "Hello {}", "world");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
writeln!(v, "Hello {} {}", "world", "#2");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
writeln!(v, "{}", 1265);
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
writeln!(v);
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
// These should be fine
write!(v, "");
@@ -28,29 +33,37 @@ fn main() {
write!(v, "\n\n");
write!(v, "like eof\n\n");
write!(v, "Hello {} {}\n\n", "world", "#2");
- writeln!(v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
- writeln!(v, "\nbla\n\n"); // #3126
+ // #3126
+ writeln!(v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n");
+ // #3126
+ writeln!(v, "\nbla\n\n");
// Escaping
- write!(v, "\\n"); // #3514
- writeln!(v, "\\"); // should fail
+ // #3514
+ write!(v, "\\n");
+ writeln!(v, "\\");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
write!(v, "\\\\n");
// Raw strings
- write!(v, r"\n"); // #3778
+ // #3778
+ write!(v, r"\n");
// Literal newlines should also fail
writeln!(
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
v
);
writeln!(
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
v
);
// Don't warn on CRLF (#4208)
write!(v, "\r\n");
write!(v, "foo\r\n");
- writeln!(v, "\\r"); // warns
+ writeln!(v, "\\r");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
write!(v, "foo\rbar\n");
// Ignore expanded format strings
diff --git a/src/tools/clippy/tests/ui/write_with_newline.rs b/src/tools/clippy/tests/ui/write_with_newline.rs
index 35bd9e7f3..96e4bf0fb 100644
--- a/src/tools/clippy/tests/ui/write_with_newline.rs
+++ b/src/tools/clippy/tests/ui/write_with_newline.rs
@@ -1,5 +1,4 @@
// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934
-//
#![allow(clippy::write_literal)]
#![warn(clippy::write_with_newline)]
@@ -11,10 +10,16 @@ fn main() {
// These should fail
write!(v, "Hello\n");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
+ //~| NOTE: `-D clippy::write-with-newline` implied by `-D warnings`
write!(v, "Hello {}\n", "world");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
write!(v, "Hello {} {}\n", "world", "#2");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
write!(v, "{}\n", 1265);
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
write!(v, "\n");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
// These should be fine
write!(v, "");
@@ -28,24 +33,31 @@ fn main() {
write!(v, "\n\n");
write!(v, "like eof\n\n");
write!(v, "Hello {} {}\n\n", "world", "#2");
- writeln!(v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
- writeln!(v, "\nbla\n\n"); // #3126
+ // #3126
+ writeln!(v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n");
+ // #3126
+ writeln!(v, "\nbla\n\n");
// Escaping
- write!(v, "\\n"); // #3514
- write!(v, "\\\n"); // should fail
+ // #3514
+ write!(v, "\\n");
+ write!(v, "\\\n");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
write!(v, "\\\\n");
// Raw strings
- write!(v, r"\n"); // #3778
+ // #3778
+ write!(v, r"\n");
// Literal newlines should also fail
write!(
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
v,
"
"
);
write!(
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
v,
r"
"
@@ -55,6 +67,7 @@ fn main() {
write!(v, "\r\n");
write!(v, "foo\r\n");
write!(v, "\\r\n");
+ //~^ ERROR: using `write!()` with a format string that ends in a single newline
write!(v, "foo\rbar\n");
// Ignore expanded format strings
diff --git a/src/tools/clippy/tests/ui/write_with_newline.stderr b/src/tools/clippy/tests/ui/write_with_newline.stderr
index 03a18a4dc..78874ffad 100644
--- a/src/tools/clippy/tests/ui/write_with_newline.stderr
+++ b/src/tools/clippy/tests/ui/write_with_newline.stderr
@@ -1,80 +1,82 @@
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:13:5
+ --> $DIR/write_with_newline.rs:12:5
|
-LL | write!(v, "Hello/n");
+LL | write!(v, "Hello\n");
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::write-with-newline` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::write_with_newline)]`
help: use `writeln!` instead
|
-LL - write!(v, "Hello/n");
+LL - write!(v, "Hello\n");
LL + writeln!(v, "Hello");
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:14:5
+ --> $DIR/write_with_newline.rs:15:5
|
-LL | write!(v, "Hello {}/n", "world");
+LL | write!(v, "Hello {}\n", "world");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `writeln!` instead
|
-LL - write!(v, "Hello {}/n", "world");
+LL - write!(v, "Hello {}\n", "world");
LL + writeln!(v, "Hello {}", "world");
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:15:5
+ --> $DIR/write_with_newline.rs:17:5
|
-LL | write!(v, "Hello {} {}/n", "world", "#2");
+LL | write!(v, "Hello {} {}\n", "world", "#2");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `writeln!` instead
|
-LL - write!(v, "Hello {} {}/n", "world", "#2");
+LL - write!(v, "Hello {} {}\n", "world", "#2");
LL + writeln!(v, "Hello {} {}", "world", "#2");
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:16:5
+ --> $DIR/write_with_newline.rs:19:5
|
-LL | write!(v, "{}/n", 1265);
+LL | write!(v, "{}\n", 1265);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `writeln!` instead
|
-LL - write!(v, "{}/n", 1265);
+LL - write!(v, "{}\n", 1265);
LL + writeln!(v, "{}", 1265);
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:17:5
+ --> $DIR/write_with_newline.rs:21:5
|
-LL | write!(v, "/n");
+LL | write!(v, "\n");
| ^^^^^^^^^^^^^^^
|
help: use `writeln!` instead
|
-LL - write!(v, "/n");
+LL - write!(v, "\n");
LL + writeln!(v);
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:36:5
+ --> $DIR/write_with_newline.rs:44:5
|
-LL | write!(v, "///n"); // should fail
+LL | write!(v, "\\\n");
| ^^^^^^^^^^^^^^^^^
|
help: use `writeln!` instead
|
-LL - write!(v, "///n"); // should fail
-LL + writeln!(v, "//"); // should fail
+LL - write!(v, "\\\n");
+LL + writeln!(v, "\\");
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:43:5
+ --> $DIR/write_with_newline.rs:53:5
|
LL | / write!(
+LL | |
LL | | v,
LL | | "
LL | | "
@@ -84,13 +86,15 @@ LL | | );
help: use `writeln!` instead
|
LL ~ writeln!(
+LL |
LL ~ v
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:48:5
+ --> $DIR/write_with_newline.rs:59:5
|
LL | / write!(
+LL | |
LL | | v,
LL | | r"
LL | | "
@@ -100,19 +104,20 @@ LL | | );
help: use `writeln!` instead
|
LL ~ writeln!(
+LL |
LL ~ v
|
error: using `write!()` with a format string that ends in a single newline
- --> $DIR/write_with_newline.rs:57:5
+ --> $DIR/write_with_newline.rs:69:5
|
-LL | write!(v, "//r/n");
+LL | write!(v, "\\r\n");
| ^^^^^^^^^^^^^^^^^^
|
help: use `writeln!` instead
|
-LL - write!(v, "//r/n");
-LL + writeln!(v, "//r");
+LL - write!(v, "\\r\n");
+LL + writeln!(v, "\\r");
|
error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/writeln_empty_string.fixed b/src/tools/clippy/tests/ui/writeln_empty_string.fixed
index 45dedd9ea..f6a7481f6 100644
--- a/src/tools/clippy/tests/ui/writeln_empty_string.fixed
+++ b/src/tools/clippy/tests/ui/writeln_empty_string.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_must_use)]
#![warn(clippy::writeln_empty_string)]
use std::io::Write;
diff --git a/src/tools/clippy/tests/ui/writeln_empty_string.rs b/src/tools/clippy/tests/ui/writeln_empty_string.rs
index 3b9f51a15..0297dba8c 100644
--- a/src/tools/clippy/tests/ui/writeln_empty_string.rs
+++ b/src/tools/clippy/tests/ui/writeln_empty_string.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![allow(unused_must_use)]
#![warn(clippy::writeln_empty_string)]
use std::io::Write;
diff --git a/src/tools/clippy/tests/ui/writeln_empty_string.stderr b/src/tools/clippy/tests/ui/writeln_empty_string.stderr
index 25e69ec48..037475543 100644
--- a/src/tools/clippy/tests/ui/writeln_empty_string.stderr
+++ b/src/tools/clippy/tests/ui/writeln_empty_string.stderr
@@ -1,5 +1,5 @@
error: empty string literal in `writeln!`
- --> $DIR/writeln_empty_string.rs:11:5
+ --> $DIR/writeln_empty_string.rs:9:5
|
LL | writeln!(v, "");
| ^^^^^^^^^^----^
@@ -7,9 +7,10 @@ LL | writeln!(v, "");
| help: remove the empty string
|
= note: `-D clippy::writeln-empty-string` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::writeln_empty_string)]`
error: empty string literal in `writeln!`
- --> $DIR/writeln_empty_string.rs:14:5
+ --> $DIR/writeln_empty_string.rs:12:5
|
LL | writeln!(suggestion, "");
| ^^^^^^^^^^^^^^^^^^^----^
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.rs b/src/tools/clippy/tests/ui/wrong_self_convention.rs
index e3cc90ee2..d7ed883b7 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention.rs
+++ b/src/tools/clippy/tests/ui/wrong_self_convention.rs
@@ -14,12 +14,14 @@ impl Foo {
fn is_u32(&self) {}
fn to_i32(self) {}
fn from_i32(self) {}
+ //~^ ERROR: methods called `from_*` usually take no `self`
pub fn as_i64(self) {}
pub fn into_i64(self) {}
pub fn is_i64(self) {}
pub fn to_i64(self) {}
pub fn from_i64(self) {}
+ //~^ ERROR: methods called `from_*` usually take no `self`
// check whether the lint can be allowed at the function level
#[allow(clippy::wrong_self_convention)]
pub fn from_cake(self) {}
@@ -32,20 +34,30 @@ struct Bar;
impl Bar {
fn as_i32(self) {}
+ //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mutabl
fn as_u32(&self) {}
fn into_i32(&self) {}
+ //~^ ERROR: methods called `into_*` usually take `self` by value
fn into_u32(self) {}
fn is_i32(self) {}
+ //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `self` b
fn is_u32(&self) {}
fn to_i32(self) {}
+ //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is not
fn to_u32(&self) {}
fn from_i32(self) {}
+ //~^ ERROR: methods called `from_*` usually take no `self`
pub fn as_i64(self) {}
+ //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mutabl
pub fn into_i64(&self) {}
+ //~^ ERROR: methods called `into_*` usually take `self` by value
pub fn is_i64(self) {}
+ //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `self` b
pub fn to_i64(self) {}
+ //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is not
pub fn from_i64(self) {}
+ //~^ ERROR: methods called `from_*` usually take no `self`
// test for false positives
fn as_(self) {}
@@ -91,15 +103,19 @@ mod issue4037 {
mod issue6307 {
trait T: Sized {
fn as_i32(self) {}
+ //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mu
fn as_u32(&self) {}
fn into_i32(self) {}
fn into_i32_ref(&self) {}
+ //~^ ERROR: methods called `into_*` usually take `self` by value
fn into_u32(self) {}
fn is_i32(self) {}
+ //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `sel
fn is_u32(&self) {}
fn to_i32(self) {}
fn to_u32(&self) {}
fn from_i32(self) {}
+ //~^ ERROR: methods called `from_*` usually take no `self`
// check whether the lint can be allowed at the function level
#[allow(clippy::wrong_self_convention)]
fn from_cake(self) {}
@@ -115,15 +131,19 @@ mod issue6307 {
trait U {
fn as_i32(self);
+ //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mu
fn as_u32(&self);
fn into_i32(self);
fn into_i32_ref(&self);
+ //~^ ERROR: methods called `into_*` usually take `self` by value
fn into_u32(self);
fn is_i32(self);
+ //~^ ERROR: methods called `is_*` usually take `self` by mutable reference or `sel
fn is_u32(&self);
fn to_i32(self);
fn to_u32(&self);
fn from_i32(self);
+ //~^ ERROR: methods called `from_*` usually take no `self`
// check whether the lint can be allowed at the function level
#[allow(clippy::wrong_self_convention)]
fn from_cake(self);
@@ -142,12 +162,14 @@ mod issue6307 {
fn as_u32(&self);
fn into_i32(self);
fn into_i32_ref(&self);
+ //~^ ERROR: methods called `into_*` usually take `self` by value
fn into_u32(self);
fn is_i32(self);
fn is_u32(&self);
fn to_i32(self);
fn to_u32(&self);
fn from_i32(self);
+ //~^ ERROR: methods called `from_*` usually take no `self`
// check whether the lint can be allowed at the function level
#[allow(clippy::wrong_self_convention)]
fn from_cake(self);
@@ -172,6 +194,7 @@ mod issue6727 {
}
// trigger lint
fn to_u64_v2(&self) -> u64 {
+ //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is
1
}
}
@@ -181,6 +204,7 @@ mod issue6727 {
impl FooNoCopy {
// trigger lint
fn to_u64(self) -> u64 {
+ //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is
2
}
fn to_u64_v2(&self) -> u64 {
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.stderr b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
index d002e55c5..9f457b50c 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
@@ -6,9 +6,10 @@ LL | fn from_i32(self) {}
|
= help: consider choosing a less ambiguous name
= note: `-D clippy::wrong-self-convention` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`
error: methods called `from_*` usually take no `self`
- --> $DIR/wrong_self_convention.rs:22:21
+ --> $DIR/wrong_self_convention.rs:23:21
|
LL | pub fn from_i64(self) {}
| ^^^^
@@ -16,7 +17,7 @@ LL | pub fn from_i64(self) {}
= help: consider choosing a less ambiguous name
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
- --> $DIR/wrong_self_convention.rs:34:15
+ --> $DIR/wrong_self_convention.rs:36:15
|
LL | fn as_i32(self) {}
| ^^^^
@@ -24,7 +25,7 @@ LL | fn as_i32(self) {}
= help: consider choosing a less ambiguous name
error: methods called `into_*` usually take `self` by value
- --> $DIR/wrong_self_convention.rs:36:17
+ --> $DIR/wrong_self_convention.rs:39:17
|
LL | fn into_i32(&self) {}
| ^^^^^
@@ -32,7 +33,7 @@ LL | fn into_i32(&self) {}
= help: consider choosing a less ambiguous name
error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
- --> $DIR/wrong_self_convention.rs:38:15
+ --> $DIR/wrong_self_convention.rs:42:15
|
LL | fn is_i32(self) {}
| ^^^^
@@ -40,7 +41,7 @@ LL | fn is_i32(self) {}
= help: consider choosing a less ambiguous name
error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference
- --> $DIR/wrong_self_convention.rs:40:15
+ --> $DIR/wrong_self_convention.rs:45:15
|
LL | fn to_i32(self) {}
| ^^^^
@@ -48,7 +49,7 @@ LL | fn to_i32(self) {}
= help: consider choosing a less ambiguous name
error: methods called `from_*` usually take no `self`
- --> $DIR/wrong_self_convention.rs:42:17
+ --> $DIR/wrong_self_convention.rs:48:17
|
LL | fn from_i32(self) {}
| ^^^^
@@ -56,7 +57,7 @@ LL | fn from_i32(self) {}
= help: consider choosing a less ambiguous name
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
- --> $DIR/wrong_self_convention.rs:44:19
+ --> $DIR/wrong_self_convention.rs:51:19
|
LL | pub fn as_i64(self) {}
| ^^^^
@@ -64,7 +65,7 @@ LL | pub fn as_i64(self) {}
= help: consider choosing a less ambiguous name
error: methods called `into_*` usually take `self` by value
- --> $DIR/wrong_self_convention.rs:45:21
+ --> $DIR/wrong_self_convention.rs:53:21
|
LL | pub fn into_i64(&self) {}
| ^^^^^
@@ -72,7 +73,7 @@ LL | pub fn into_i64(&self) {}
= help: consider choosing a less ambiguous name
error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
- --> $DIR/wrong_self_convention.rs:46:19
+ --> $DIR/wrong_self_convention.rs:55:19
|
LL | pub fn is_i64(self) {}
| ^^^^
@@ -80,7 +81,7 @@ LL | pub fn is_i64(self) {}
= help: consider choosing a less ambiguous name
error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference
- --> $DIR/wrong_self_convention.rs:47:19
+ --> $DIR/wrong_self_convention.rs:57:19
|
LL | pub fn to_i64(self) {}
| ^^^^
@@ -88,7 +89,7 @@ LL | pub fn to_i64(self) {}
= help: consider choosing a less ambiguous name
error: methods called `from_*` usually take no `self`
- --> $DIR/wrong_self_convention.rs:48:21
+ --> $DIR/wrong_self_convention.rs:59:21
|
LL | pub fn from_i64(self) {}
| ^^^^
@@ -96,7 +97,7 @@ LL | pub fn from_i64(self) {}
= help: consider choosing a less ambiguous name
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
- --> $DIR/wrong_self_convention.rs:93:19
+ --> $DIR/wrong_self_convention.rs:105:19
|
LL | fn as_i32(self) {}
| ^^^^
@@ -104,7 +105,7 @@ LL | fn as_i32(self) {}
= help: consider choosing a less ambiguous name
error: methods called `into_*` usually take `self` by value
- --> $DIR/wrong_self_convention.rs:96:25
+ --> $DIR/wrong_self_convention.rs:109:25
|
LL | fn into_i32_ref(&self) {}
| ^^^^^
@@ -112,7 +113,7 @@ LL | fn into_i32_ref(&self) {}
= help: consider choosing a less ambiguous name
error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
- --> $DIR/wrong_self_convention.rs:98:19
+ --> $DIR/wrong_self_convention.rs:112:19
|
LL | fn is_i32(self) {}
| ^^^^
@@ -120,7 +121,7 @@ LL | fn is_i32(self) {}
= help: consider choosing a less ambiguous name
error: methods called `from_*` usually take no `self`
- --> $DIR/wrong_self_convention.rs:102:21
+ --> $DIR/wrong_self_convention.rs:117:21
|
LL | fn from_i32(self) {}
| ^^^^
@@ -128,7 +129,7 @@ LL | fn from_i32(self) {}
= help: consider choosing a less ambiguous name
error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
- --> $DIR/wrong_self_convention.rs:117:19
+ --> $DIR/wrong_self_convention.rs:133:19
|
LL | fn as_i32(self);
| ^^^^
@@ -136,7 +137,7 @@ LL | fn as_i32(self);
= help: consider choosing a less ambiguous name
error: methods called `into_*` usually take `self` by value
- --> $DIR/wrong_self_convention.rs:120:25
+ --> $DIR/wrong_self_convention.rs:137:25
|
LL | fn into_i32_ref(&self);
| ^^^^^
@@ -144,7 +145,7 @@ LL | fn into_i32_ref(&self);
= help: consider choosing a less ambiguous name
error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
- --> $DIR/wrong_self_convention.rs:122:19
+ --> $DIR/wrong_self_convention.rs:140:19
|
LL | fn is_i32(self);
| ^^^^
@@ -152,7 +153,7 @@ LL | fn is_i32(self);
= help: consider choosing a less ambiguous name
error: methods called `from_*` usually take no `self`
- --> $DIR/wrong_self_convention.rs:126:21
+ --> $DIR/wrong_self_convention.rs:145:21
|
LL | fn from_i32(self);
| ^^^^
@@ -160,7 +161,7 @@ LL | fn from_i32(self);
= help: consider choosing a less ambiguous name
error: methods called `into_*` usually take `self` by value
- --> $DIR/wrong_self_convention.rs:144:25
+ --> $DIR/wrong_self_convention.rs:164:25
|
LL | fn into_i32_ref(&self);
| ^^^^^
@@ -168,7 +169,7 @@ LL | fn into_i32_ref(&self);
= help: consider choosing a less ambiguous name
error: methods called `from_*` usually take no `self`
- --> $DIR/wrong_self_convention.rs:150:21
+ --> $DIR/wrong_self_convention.rs:171:21
|
LL | fn from_i32(self);
| ^^^^
@@ -176,7 +177,7 @@ LL | fn from_i32(self);
= help: consider choosing a less ambiguous name
error: methods with the following characteristics: (`to_*` and `self` type is `Copy`) usually take `self` by value
- --> $DIR/wrong_self_convention.rs:174:22
+ --> $DIR/wrong_self_convention.rs:196:22
|
LL | fn to_u64_v2(&self) -> u64 {
| ^^^^^
@@ -184,7 +185,7 @@ LL | fn to_u64_v2(&self) -> u64 {
= help: consider choosing a less ambiguous name
error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference
- --> $DIR/wrong_self_convention.rs:183:19
+ --> $DIR/wrong_self_convention.rs:206:19
|
LL | fn to_u64(self) -> u64 {
| ^^^^
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention2.rs b/src/tools/clippy/tests/ui/wrong_self_convention2.rs
index 0dcf4743e..44b70f877 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention2.rs
+++ b/src/tools/clippy/tests/ui/wrong_self_convention2.rs
@@ -52,6 +52,7 @@ mod issue7179 {
// lint
pub fn from_be_self(self) -> Self {
+ //~^ ERROR: methods called `from_*` usually take no `self`
S(i32::from_be(self.0))
}
}
@@ -61,6 +62,7 @@ mod issue7179 {
fn from_be(s: Self) -> Self;
// lint
fn from_be_self(self) -> Self;
+ //~^ ERROR: methods called `from_*` usually take no `self`
}
trait Foo: Sized {
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention2.stderr b/src/tools/clippy/tests/ui/wrong_self_convention2.stderr
index 8de10e7be..dc12a8443 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention2.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_convention2.stderr
@@ -6,9 +6,10 @@ LL | pub fn from_be_self(self) -> Self {
|
= help: consider choosing a less ambiguous name
= note: `-D clippy::wrong-self-convention` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`
error: methods called `from_*` usually take no `self`
- --> $DIR/wrong_self_convention2.rs:63:25
+ --> $DIR/wrong_self_convention2.rs:64:25
|
LL | fn from_be_self(self) -> Self;
| ^^^^
diff --git a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.rs b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.rs
index 5bb2116bd..9169fc6d7 100644
--- a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.rs
+++ b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.rs
@@ -12,6 +12,7 @@ mod issue6758 {
impl<T> Test<T> {
// If a method starts with `to_` and not ends with `_mut` it should expect `&self`
pub fn to_many(&mut self) -> Option<&mut [T]> {
+ //~^ ERROR: methods with the following characteristics: (`to_*` and `self` type is
match self {
Self::Many(data) => Some(data),
_ => None,
@@ -20,6 +21,7 @@ mod issue6758 {
// If a method starts with `to_` and ends with `_mut` it should expect `&mut self`
pub fn to_many_mut(&self) -> Option<&[T]> {
+ //~^ ERROR: methods with the following characteristics: (`to_*` and `*_mut`) usual
match self {
Self::Many(data) => Some(data),
_ => None,
diff --git a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr
index 3d009083c..21255287d 100644
--- a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr
@@ -6,9 +6,10 @@ LL | pub fn to_many(&mut self) -> Option<&mut [T]> {
|
= help: consider choosing a less ambiguous name
= note: `-D clippy::wrong-self-convention` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`
error: methods with the following characteristics: (`to_*` and `*_mut`) usually take `self` by mutable reference
- --> $DIR/wrong_self_conventions_mut.rs:22:28
+ --> $DIR/wrong_self_conventions_mut.rs:23:28
|
LL | pub fn to_many_mut(&self) -> Option<&[T]> {
| ^^^^^
diff --git a/src/tools/clippy/tests/ui/zero_div_zero.rs b/src/tools/clippy/tests/ui/zero_div_zero.rs
index 968c58f40..340ed5ef1 100644
--- a/src/tools/clippy/tests/ui/zero_div_zero.rs
+++ b/src/tools/clippy/tests/ui/zero_div_zero.rs
@@ -2,9 +2,13 @@
#[warn(clippy::zero_divided_by_zero)]
fn main() {
let nan = 0.0 / 0.0;
+ //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN
let f64_nan = 0.0 / 0.0f64;
+ //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN
let other_f64_nan = 0.0f64 / 0.0;
+ //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN
let one_more_f64_nan = 0.0f64 / 0.0f64;
+ //~^ ERROR: constant division of `0.0` with `0.0` will always result in NaN
let zero = 0.0;
let other_zero = 0.0;
let other_nan = zero / other_zero; // fine - this lint doesn't propagate constants.
diff --git a/src/tools/clippy/tests/ui/zero_div_zero.stderr b/src/tools/clippy/tests/ui/zero_div_zero.stderr
index 2793d1606..797ae2537 100644
--- a/src/tools/clippy/tests/ui/zero_div_zero.stderr
+++ b/src/tools/clippy/tests/ui/zero_div_zero.stderr
@@ -6,9 +6,10 @@ LL | let nan = 0.0 / 0.0;
|
= help: consider using `f64::NAN` if you would like a constant representing NaN
= note: `-D clippy::zero-divided-by-zero` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::zero_divided_by_zero)]`
error: constant division of `0.0` with `0.0` will always result in NaN
- --> $DIR/zero_div_zero.rs:5:19
+ --> $DIR/zero_div_zero.rs:6:19
|
LL | let f64_nan = 0.0 / 0.0f64;
| ^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | let f64_nan = 0.0 / 0.0f64;
= help: consider using `f64::NAN` if you would like a constant representing NaN
error: constant division of `0.0` with `0.0` will always result in NaN
- --> $DIR/zero_div_zero.rs:6:25
+ --> $DIR/zero_div_zero.rs:8:25
|
LL | let other_f64_nan = 0.0f64 / 0.0;
| ^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | let other_f64_nan = 0.0f64 / 0.0;
= help: consider using `f64::NAN` if you would like a constant representing NaN
error: constant division of `0.0` with `0.0` will always result in NaN
- --> $DIR/zero_div_zero.rs:7:28
+ --> $DIR/zero_div_zero.rs:10:28
|
LL | let one_more_f64_nan = 0.0f64 / 0.0f64;
| ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/zero_offset.rs b/src/tools/clippy/tests/ui/zero_offset.rs
index fd9ac1fa7..c7a69dee4 100644
--- a/src/tools/clippy/tests/ui/zero_offset.rs
+++ b/src/tools/clippy/tests/ui/zero_offset.rs
@@ -3,15 +3,24 @@ fn main() {
unsafe {
let m = &mut () as *mut ();
m.offset(0);
+ //~^ ERROR: offset calculation on zero-sized value
+ //~| NOTE: `#[deny(clippy::zst_offset)]` on by default
m.wrapping_add(0);
+ //~^ ERROR: offset calculation on zero-sized value
m.sub(0);
+ //~^ ERROR: offset calculation on zero-sized value
m.wrapping_sub(0);
+ //~^ ERROR: offset calculation on zero-sized value
let c = &() as *const ();
c.offset(0);
+ //~^ ERROR: offset calculation on zero-sized value
c.wrapping_add(0);
+ //~^ ERROR: offset calculation on zero-sized value
c.sub(0);
+ //~^ ERROR: offset calculation on zero-sized value
c.wrapping_sub(0);
+ //~^ ERROR: offset calculation on zero-sized value
let sized = &1 as *const i32;
sized.offset(0);
diff --git a/src/tools/clippy/tests/ui/zero_offset.stderr b/src/tools/clippy/tests/ui/zero_offset.stderr
index 481a44657..bb616f456 100644
--- a/src/tools/clippy/tests/ui/zero_offset.stderr
+++ b/src/tools/clippy/tests/ui/zero_offset.stderr
@@ -7,43 +7,43 @@ LL | m.offset(0);
= note: `#[deny(clippy::zst_offset)]` on by default
error: offset calculation on zero-sized value
- --> $DIR/zero_offset.rs:6:9
+ --> $DIR/zero_offset.rs:8:9
|
LL | m.wrapping_add(0);
| ^^^^^^^^^^^^^^^^^
error: offset calculation on zero-sized value
- --> $DIR/zero_offset.rs:7:9
+ --> $DIR/zero_offset.rs:10:9
|
LL | m.sub(0);
| ^^^^^^^^
error: offset calculation on zero-sized value
- --> $DIR/zero_offset.rs:8:9
+ --> $DIR/zero_offset.rs:12:9
|
LL | m.wrapping_sub(0);
| ^^^^^^^^^^^^^^^^^
error: offset calculation on zero-sized value
- --> $DIR/zero_offset.rs:11:9
+ --> $DIR/zero_offset.rs:16:9
|
LL | c.offset(0);
| ^^^^^^^^^^^
error: offset calculation on zero-sized value
- --> $DIR/zero_offset.rs:12:9
+ --> $DIR/zero_offset.rs:18:9
|
LL | c.wrapping_add(0);
| ^^^^^^^^^^^^^^^^^
error: offset calculation on zero-sized value
- --> $DIR/zero_offset.rs:13:9
+ --> $DIR/zero_offset.rs:20:9
|
LL | c.sub(0);
| ^^^^^^^^
error: offset calculation on zero-sized value
- --> $DIR/zero_offset.rs:14:9
+ --> $DIR/zero_offset.rs:22:9
|
LL | c.wrapping_sub(0);
| ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/zero_ptr.fixed b/src/tools/clippy/tests/ui/zero_ptr.fixed
index bed38ecaf..5d99bc9b7 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.fixed
+++ b/src/tools/clippy/tests/ui/zero_ptr.fixed
@@ -1,4 +1,3 @@
-//@run-rustfix
pub fn foo(_const: *const f32, _mut: *mut i64) {}
fn main() {
diff --git a/src/tools/clippy/tests/ui/zero_ptr.rs b/src/tools/clippy/tests/ui/zero_ptr.rs
index b7b778915..09d321c7a 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.rs
+++ b/src/tools/clippy/tests/ui/zero_ptr.rs
@@ -1,4 +1,3 @@
-//@run-rustfix
pub fn foo(_const: *const f32, _mut: *mut i64) {}
fn main() {
diff --git a/src/tools/clippy/tests/ui/zero_ptr.stderr b/src/tools/clippy/tests/ui/zero_ptr.stderr
index 4ee5e9a26..57679a8ac 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.stderr
+++ b/src/tools/clippy/tests/ui/zero_ptr.stderr
@@ -1,31 +1,32 @@
error: `0 as *const _` detected
- --> $DIR/zero_ptr.rs:5:13
+ --> $DIR/zero_ptr.rs:4:13
|
LL | let _ = 0 as *const usize;
| ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::null::<usize>()`
|
= note: `-D clippy::zero-ptr` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::zero_ptr)]`
error: `0 as *mut _` detected
- --> $DIR/zero_ptr.rs:6:13
+ --> $DIR/zero_ptr.rs:5:13
|
LL | let _ = 0 as *mut f64;
| ^^^^^^^^^^^^^ help: try: `std::ptr::null_mut::<f64>()`
error: `0 as *const _` detected
- --> $DIR/zero_ptr.rs:7:24
+ --> $DIR/zero_ptr.rs:6:24
|
LL | let _: *const u8 = 0 as *const _;
| ^^^^^^^^^^^^^ help: try: `std::ptr::null()`
error: `0 as *const _` detected
- --> $DIR/zero_ptr.rs:10:9
+ --> $DIR/zero_ptr.rs:9:9
|
LL | foo(0 as *const _, 0 as *mut _);
| ^^^^^^^^^^^^^ help: try: `std::ptr::null()`
error: `0 as *mut _` detected
- --> $DIR/zero_ptr.rs:10:24
+ --> $DIR/zero_ptr.rs:9:24
|
LL | foo(0 as *const _, 0 as *mut _);
| ^^^^^^^^^^^ help: try: `std::ptr::null_mut()`
diff --git a/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed b/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed
index 7afd80cca..4f4d19e88 100644
--- a/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed
+++ b/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(lang_items, start, libc)]
#![no_std]
#![deny(clippy::zero_ptr)]
diff --git a/src/tools/clippy/tests/ui/zero_ptr_no_std.rs b/src/tools/clippy/tests/ui/zero_ptr_no_std.rs
index 05a0587d2..54954d8d1 100644
--- a/src/tools/clippy/tests/ui/zero_ptr_no_std.rs
+++ b/src/tools/clippy/tests/ui/zero_ptr_no_std.rs
@@ -1,5 +1,3 @@
-//@run-rustfix
-
#![feature(lang_items, start, libc)]
#![no_std]
#![deny(clippy::zero_ptr)]
diff --git a/src/tools/clippy/tests/ui/zero_ptr_no_std.stderr b/src/tools/clippy/tests/ui/zero_ptr_no_std.stderr
index d92bb4a65..915b9c477 100644
--- a/src/tools/clippy/tests/ui/zero_ptr_no_std.stderr
+++ b/src/tools/clippy/tests/ui/zero_ptr_no_std.stderr
@@ -1,23 +1,23 @@
error: `0 as *const _` detected
- --> $DIR/zero_ptr_no_std.rs:9:13
+ --> $DIR/zero_ptr_no_std.rs:7:13
|
LL | let _ = 0 as *const usize;
| ^^^^^^^^^^^^^^^^^ help: try: `core::ptr::null::<usize>()`
|
note: the lint level is defined here
- --> $DIR/zero_ptr_no_std.rs:5:9
+ --> $DIR/zero_ptr_no_std.rs:3:9
|
LL | #![deny(clippy::zero_ptr)]
| ^^^^^^^^^^^^^^^^
error: `0 as *mut _` detected
- --> $DIR/zero_ptr_no_std.rs:10:13
+ --> $DIR/zero_ptr_no_std.rs:8:13
|
LL | let _ = 0 as *mut f64;
| ^^^^^^^^^^^^^ help: try: `core::ptr::null_mut::<f64>()`
error: `0 as *const _` detected
- --> $DIR/zero_ptr_no_std.rs:11:24
+ --> $DIR/zero_ptr_no_std.rs:9:24
|
LL | let _: *const u8 = 0 as *const _;
| ^^^^^^^^^^^^^ help: try: `core::ptr::null()`
diff --git a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs
index 5cd254787..565f63920 100644
--- a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs
+++ b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs
@@ -3,23 +3,28 @@ use std::collections::BTreeMap;
const CONST_OK: Option<BTreeMap<String, usize>> = None;
const CONST_NOT_OK: Option<BTreeMap<String, ()>> = None;
+//~^ ERROR: map with zero-sized value type
static STATIC_OK: Option<BTreeMap<String, usize>> = None;
static STATIC_NOT_OK: Option<BTreeMap<String, ()>> = None;
+//~^ ERROR: map with zero-sized value type
type OkMap = BTreeMap<String, usize>;
type NotOkMap = BTreeMap<String, ()>;
+//~^ ERROR: map with zero-sized value type
enum TestEnum {
Ok(BTreeMap<String, usize>),
NotOk(BTreeMap<String, ()>),
+ //~^ ERROR: map with zero-sized value type
}
struct Test {
ok: BTreeMap<String, usize>,
not_ok: BTreeMap<String, ()>,
-
+ //~^ ERROR: map with zero-sized value type
also_not_ok: Vec<BTreeMap<usize, ()>>,
+ //~^ ERROR: map with zero-sized value type
}
trait TestTrait {
@@ -28,6 +33,7 @@ trait TestTrait {
fn produce_output() -> Self::Output;
fn weird_map(&self, map: BTreeMap<usize, ()>);
+ //~^ ERROR: map with zero-sized value type
}
impl Test {
@@ -36,6 +42,7 @@ impl Test {
}
fn not_ok(&self) -> BTreeMap<String, ()> {
+ //~^ ERROR: map with zero-sized value type
todo!()
}
}
@@ -53,6 +60,8 @@ impl TestTrait for Test {
}
fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
+ //~^ ERROR: map with zero-sized value type
+ //~| ERROR: map with zero-sized value type
todo!();
}
@@ -62,7 +71,10 @@ fn test2(map: BTreeMap<String, usize>, key: &str) -> BTreeMap<String, usize> {
fn main() {
let _: BTreeMap<String, ()> = BTreeMap::new();
+ //~^ ERROR: map with zero-sized value type
+ //~| ERROR: map with zero-sized value type
let _: BTreeMap<String, usize> = BTreeMap::new();
let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect();
+ //~^ ERROR: map with zero-sized value type
}
diff --git a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
index c6ba6fa76..c48e19a76 100644
--- a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
+++ b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
@@ -6,9 +6,10 @@ LL | const CONST_NOT_OK: Option<BTreeMap<String, ()>> = None;
|
= help: consider using a set instead
= note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]`
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:8:30
+ --> $DIR/zero_sized_btreemap_values.rs:9:30
|
LL | static STATIC_NOT_OK: Option<BTreeMap<String, ()>> = None;
| ^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | static STATIC_NOT_OK: Option<BTreeMap<String, ()>> = None;
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:11:17
+ --> $DIR/zero_sized_btreemap_values.rs:13:17
|
LL | type NotOkMap = BTreeMap<String, ()>;
| ^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | type NotOkMap = BTreeMap<String, ()>;
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:15:11
+ --> $DIR/zero_sized_btreemap_values.rs:18:11
|
LL | NotOk(BTreeMap<String, ()>),
| ^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | NotOk(BTreeMap<String, ()>),
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:20:13
+ --> $DIR/zero_sized_btreemap_values.rs:24:13
|
LL | not_ok: BTreeMap<String, ()>,
| ^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | not_ok: BTreeMap<String, ()>,
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:22:22
+ --> $DIR/zero_sized_btreemap_values.rs:26:22
|
LL | also_not_ok: Vec<BTreeMap<usize, ()>>,
| ^^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | also_not_ok: Vec<BTreeMap<usize, ()>>,
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:30:30
+ --> $DIR/zero_sized_btreemap_values.rs:35:30
|
LL | fn weird_map(&self, map: BTreeMap<usize, ()>);
| ^^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | fn weird_map(&self, map: BTreeMap<usize, ()>);
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:38:25
+ --> $DIR/zero_sized_btreemap_values.rs:44:25
|
LL | fn not_ok(&self) -> BTreeMap<String, ()> {
| ^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | fn not_ok(&self) -> BTreeMap<String, ()> {
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:55:14
+ --> $DIR/zero_sized_btreemap_values.rs:62:14
|
LL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
| ^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:55:50
+ --> $DIR/zero_sized_btreemap_values.rs:62:50
|
LL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
| ^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +81,7 @@ LL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:64:35
+ --> $DIR/zero_sized_btreemap_values.rs:73:35
|
LL | let _: BTreeMap<String, ()> = BTreeMap::new();
| ^^^^^^^^
@@ -88,7 +89,7 @@ LL | let _: BTreeMap<String, ()> = BTreeMap::new();
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:64:12
+ --> $DIR/zero_sized_btreemap_values.rs:73:12
|
LL | let _: BTreeMap<String, ()> = BTreeMap::new();
| ^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL | let _: BTreeMap<String, ()> = BTreeMap::new();
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_btreemap_values.rs:67:12
+ --> $DIR/zero_sized_btreemap_values.rs:78:12
|
LL | let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect();
| ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs
index a1608d863..5498261ee 100644
--- a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs
+++ b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs
@@ -3,23 +3,28 @@ use std::collections::HashMap;
const CONST_OK: Option<HashMap<String, usize>> = None;
const CONST_NOT_OK: Option<HashMap<String, ()>> = None;
+//~^ ERROR: map with zero-sized value type
static STATIC_OK: Option<HashMap<String, usize>> = None;
static STATIC_NOT_OK: Option<HashMap<String, ()>> = None;
+//~^ ERROR: map with zero-sized value type
type OkMap = HashMap<String, usize>;
type NotOkMap = HashMap<String, ()>;
+//~^ ERROR: map with zero-sized value type
enum TestEnum {
Ok(HashMap<String, usize>),
NotOk(HashMap<String, ()>),
+ //~^ ERROR: map with zero-sized value type
}
struct Test {
ok: HashMap<String, usize>,
not_ok: HashMap<String, ()>,
-
+ //~^ ERROR: map with zero-sized value type
also_not_ok: Vec<HashMap<usize, ()>>,
+ //~^ ERROR: map with zero-sized value type
}
trait TestTrait {
@@ -28,6 +33,7 @@ trait TestTrait {
fn produce_output() -> Self::Output;
fn weird_map(&self, map: HashMap<usize, ()>);
+ //~^ ERROR: map with zero-sized value type
}
impl Test {
@@ -36,6 +42,7 @@ impl Test {
}
fn not_ok(&self) -> HashMap<String, ()> {
+ //~^ ERROR: map with zero-sized value type
todo!()
}
}
@@ -53,6 +60,8 @@ impl TestTrait for Test {
}
fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
+ //~^ ERROR: map with zero-sized value type
+ //~| ERROR: map with zero-sized value type
todo!();
}
@@ -62,7 +71,10 @@ fn test2(map: HashMap<String, usize>, key: &str) -> HashMap<String, usize> {
fn main() {
let _: HashMap<String, ()> = HashMap::new();
+ //~^ ERROR: map with zero-sized value type
+ //~| ERROR: map with zero-sized value type
let _: HashMap<String, usize> = HashMap::new();
let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect();
+ //~^ ERROR: map with zero-sized value type
}
diff --git a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
index 75bdeb42e..08b1b58f3 100644
--- a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
+++ b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
@@ -6,9 +6,10 @@ LL | const CONST_NOT_OK: Option<HashMap<String, ()>> = None;
|
= help: consider using a set instead
= note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]`
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:8:30
+ --> $DIR/zero_sized_hashmap_values.rs:9:30
|
LL | static STATIC_NOT_OK: Option<HashMap<String, ()>> = None;
| ^^^^^^^^^^^^^^^^^^^
@@ -16,7 +17,7 @@ LL | static STATIC_NOT_OK: Option<HashMap<String, ()>> = None;
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:11:17
+ --> $DIR/zero_sized_hashmap_values.rs:13:17
|
LL | type NotOkMap = HashMap<String, ()>;
| ^^^^^^^^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | type NotOkMap = HashMap<String, ()>;
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:15:11
+ --> $DIR/zero_sized_hashmap_values.rs:18:11
|
LL | NotOk(HashMap<String, ()>),
| ^^^^^^^^^^^^^^^^^^^
@@ -32,7 +33,7 @@ LL | NotOk(HashMap<String, ()>),
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:20:13
+ --> $DIR/zero_sized_hashmap_values.rs:24:13
|
LL | not_ok: HashMap<String, ()>,
| ^^^^^^^^^^^^^^^^^^^
@@ -40,7 +41,7 @@ LL | not_ok: HashMap<String, ()>,
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:22:22
+ --> $DIR/zero_sized_hashmap_values.rs:26:22
|
LL | also_not_ok: Vec<HashMap<usize, ()>>,
| ^^^^^^^^^^^^^^^^^^
@@ -48,7 +49,7 @@ LL | also_not_ok: Vec<HashMap<usize, ()>>,
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:30:30
+ --> $DIR/zero_sized_hashmap_values.rs:35:30
|
LL | fn weird_map(&self, map: HashMap<usize, ()>);
| ^^^^^^^^^^^^^^^^^^
@@ -56,7 +57,7 @@ LL | fn weird_map(&self, map: HashMap<usize, ()>);
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:38:25
+ --> $DIR/zero_sized_hashmap_values.rs:44:25
|
LL | fn not_ok(&self) -> HashMap<String, ()> {
| ^^^^^^^^^^^^^^^^^^^
@@ -64,7 +65,7 @@ LL | fn not_ok(&self) -> HashMap<String, ()> {
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:55:14
+ --> $DIR/zero_sized_hashmap_values.rs:62:14
|
LL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
| ^^^^^^^^^^^^^^^^^^^
@@ -72,7 +73,7 @@ LL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:55:49
+ --> $DIR/zero_sized_hashmap_values.rs:62:49
|
LL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
| ^^^^^^^^^^^^^^^^^^^
@@ -80,7 +81,7 @@ LL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:64:34
+ --> $DIR/zero_sized_hashmap_values.rs:73:34
|
LL | let _: HashMap<String, ()> = HashMap::new();
| ^^^^^^^
@@ -88,7 +89,7 @@ LL | let _: HashMap<String, ()> = HashMap::new();
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:64:12
+ --> $DIR/zero_sized_hashmap_values.rs:73:12
|
LL | let _: HashMap<String, ()> = HashMap::new();
| ^^^^^^^^^^^^^^^^^^^
@@ -96,7 +97,7 @@ LL | let _: HashMap<String, ()> = HashMap::new();
= help: consider using a set instead
error: map with zero-sized value type
- --> $DIR/zero_sized_hashmap_values.rs:67:12
+ --> $DIR/zero_sized_hashmap_values.rs:78:12
|
LL | let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect();
| ^^^^^^^^^^^^^
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index ff1d5cecb..bb1fa6e92 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -24,6 +24,7 @@ walkdir = "2"
glob = "0.3.0"
lazycell = "1.3.0"
anyhow = "1"
+home = "0.5.5"
[target.'cfg(unix)'.dependencies]
libc = "0.2"
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 7c17e92d0..0e1bf0c6c 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -66,6 +66,7 @@ string_enum! {
JsDocTest => "js-doc-test",
MirOpt => "mir-opt",
Assembly => "assembly",
+ CoverageMap => "coverage-map",
RunCoverage => "run-coverage",
}
}
@@ -140,6 +141,22 @@ impl PanicStrategy {
}
}
+#[derive(Clone, Debug, PartialEq, serde::Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum Sanitizer {
+ Address,
+ Cfi,
+ Kcfi,
+ KernelAddress,
+ Leak,
+ Memory,
+ Memtag,
+ Safestack,
+ ShadowCallStack,
+ Thread,
+ Hwaddress,
+}
+
/// Configuration for compiletest
#[derive(Debug, Default, Clone)]
pub struct Config {
@@ -161,6 +178,9 @@ pub struct Config {
/// The rust-demangler executable.
pub rust_demangler_path: Option<PathBuf>,
+ /// The coverage-dump executable.
+ pub coverage_dump_path: Option<PathBuf>,
+
/// The Python executable to use for LLDB and htmldocck.
pub python: String,
@@ -556,6 +576,12 @@ pub struct TargetCfg {
pub(crate) panic: PanicStrategy,
#[serde(default)]
pub(crate) dynamic_linking: bool,
+ #[serde(rename = "supported-sanitizers", default)]
+ pub(crate) sanitizers: Vec<Sanitizer>,
+ #[serde(rename = "supports-xray", default)]
+ pub(crate) xray: bool,
+ #[serde(default = "default_reloc_model")]
+ pub(crate) relocation_model: String,
}
impl TargetCfg {
@@ -568,6 +594,10 @@ fn default_os() -> String {
"none".into()
}
+fn default_reloc_model() -> String {
+ "pic".into()
+}
+
#[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Endian {
@@ -639,6 +669,7 @@ pub const UI_EXTENSIONS: &[&str] = &[
UI_STDERR_32,
UI_STDERR_16,
UI_COVERAGE,
+ UI_COVERAGE_MAP,
];
pub const UI_STDERR: &str = "stderr";
pub const UI_STDOUT: &str = "stdout";
@@ -649,6 +680,7 @@ pub const UI_STDERR_64: &str = "64bit.stderr";
pub const UI_STDERR_32: &str = "32bit.stderr";
pub const UI_STDERR_16: &str = "16bit.stderr";
pub const UI_COVERAGE: &str = "coverage";
+pub const UI_COVERAGE_MAP: &str = "cov-map";
/// Absolute path to the directory where all output for all tests in the given
/// `relative_dir` group should reside. Example:
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 62364ede4..2b7a4387c 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -1,6 +1,5 @@
-use crate::common::{Config, Debugger};
+use crate::common::{Config, Debugger, Sanitizer};
use crate::header::IgnoreDecision;
-use crate::util;
pub(super) fn handle_needs(
cache: &CachedNeedsConditions,
@@ -135,6 +134,11 @@ pub(super) fn handle_needs(
condition: config.target_cfg().dynamic_linking,
ignore_reason: "ignored on targets without dynamic linking",
},
+ Need {
+ name: "needs-relocation-model-pic",
+ condition: config.target_cfg().relocation_model == "pic",
+ ignore_reason: "ignored on targets without PIC relocation model",
+ },
];
let (name, comment) = match ln.split_once([':', ' ']) {
@@ -220,21 +224,22 @@ impl CachedNeedsConditions {
path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file());
let target = &&*config.target;
+ let sanitizers = &config.target_cfg().sanitizers;
Self {
sanitizer_support: std::env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(),
- sanitizer_address: util::ASAN_SUPPORTED_TARGETS.contains(target),
- sanitizer_cfi: util::CFI_SUPPORTED_TARGETS.contains(target),
- sanitizer_kcfi: util::KCFI_SUPPORTED_TARGETS.contains(target),
- sanitizer_kasan: util::KASAN_SUPPORTED_TARGETS.contains(target),
- sanitizer_leak: util::LSAN_SUPPORTED_TARGETS.contains(target),
- sanitizer_memory: util::MSAN_SUPPORTED_TARGETS.contains(target),
- sanitizer_thread: util::TSAN_SUPPORTED_TARGETS.contains(target),
- sanitizer_hwaddress: util::HWASAN_SUPPORTED_TARGETS.contains(target),
- sanitizer_memtag: util::MEMTAG_SUPPORTED_TARGETS.contains(target),
- sanitizer_shadow_call_stack: util::SHADOWCALLSTACK_SUPPORTED_TARGETS.contains(target),
- sanitizer_safestack: util::SAFESTACK_SUPPORTED_TARGETS.contains(target),
+ sanitizer_address: sanitizers.contains(&Sanitizer::Address),
+ sanitizer_cfi: sanitizers.contains(&Sanitizer::Cfi),
+ sanitizer_kcfi: sanitizers.contains(&Sanitizer::Kcfi),
+ sanitizer_kasan: sanitizers.contains(&Sanitizer::KernelAddress),
+ sanitizer_leak: sanitizers.contains(&Sanitizer::Leak),
+ sanitizer_memory: sanitizers.contains(&Sanitizer::Memory),
+ sanitizer_thread: sanitizers.contains(&Sanitizer::Thread),
+ sanitizer_hwaddress: sanitizers.contains(&Sanitizer::Hwaddress),
+ sanitizer_memtag: sanitizers.contains(&Sanitizer::Memtag),
+ sanitizer_shadow_call_stack: sanitizers.contains(&Sanitizer::ShadowCallStack),
+ sanitizer_safestack: sanitizers.contains(&Sanitizer::Safestack),
profiler_support: std::env::var_os("RUSTC_PROFILER_SUPPORT").is_some(),
- xray: util::XRAY_SUPPORTED_TARGETS.contains(target),
+ xray: config.target_cfg().xray,
// For tests using the `needs-rust-lld` directive (e.g. for `-Zgcc-ld=lld`), we need to find
// whether `rust-lld` is present in the compiler under test.
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 362fba116..2fd80b52c 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -53,47 +53,117 @@ fn test_parse_normalization_string() {
assert_eq!(s, r#"normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)."#);
}
-fn config() -> Config {
- let args = &[
- "compiletest",
- "--mode=ui",
- "--suite=ui",
- "--compile-lib-path=",
- "--run-lib-path=",
- "--python=",
- "--jsondocck-path=",
- "--src-base=",
- "--build-base=",
- "--sysroot-base=",
- "--stage-id=stage2-x86_64-unknown-linux-gnu",
- "--cc=c",
- "--cxx=c++",
- "--cflags=",
- "--cxxflags=",
- "--llvm-components=",
- "--android-cross-path=",
- "--target=x86_64-unknown-linux-gnu",
- "--channel=nightly",
- ];
- let mut args: Vec<String> = args.iter().map(ToString::to_string).collect();
- args.push("--rustc-path".to_string());
- // This is a subtle/fragile thing. On rust-lang CI, there is no global
- // `rustc`, and Cargo doesn't offer a convenient way to get the path to
- // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing
- // to the stage0 compiler.
- //
- // Otherwise, if you are running compiletests's tests manually, you
- // probably don't have `RUSTC` set, in which case this falls back to the
- // global rustc. If your global rustc is too far out of sync with stage0,
- // then this may cause confusing errors. Or if for some reason you don't
- // have rustc in PATH, that would also fail.
- args.push(std::env::var("RUSTC").unwrap_or_else(|_| {
- eprintln!(
- "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)"
- );
- "rustc".to_string()
- }));
- crate::parse_config(args)
+#[derive(Default)]
+struct ConfigBuilder {
+ channel: Option<String>,
+ host: Option<String>,
+ target: Option<String>,
+ stage_id: Option<String>,
+ llvm_version: Option<String>,
+ git_hash: bool,
+ system_llvm: bool,
+}
+
+impl ConfigBuilder {
+ fn channel(&mut self, s: &str) -> &mut Self {
+ self.channel = Some(s.to_owned());
+ self
+ }
+
+ fn host(&mut self, s: &str) -> &mut Self {
+ self.host = Some(s.to_owned());
+ self
+ }
+
+ fn target(&mut self, s: &str) -> &mut Self {
+ self.target = Some(s.to_owned());
+ self
+ }
+
+ fn stage_id(&mut self, s: &str) -> &mut Self {
+ self.stage_id = Some(s.to_owned());
+ self
+ }
+
+ fn llvm_version(&mut self, s: &str) -> &mut Self {
+ self.llvm_version = Some(s.to_owned());
+ self
+ }
+
+ fn git_hash(&mut self, b: bool) -> &mut Self {
+ self.git_hash = b;
+ self
+ }
+
+ fn system_llvm(&mut self, s: bool) -> &mut Self {
+ self.system_llvm = s;
+ self
+ }
+
+ fn build(&mut self) -> Config {
+ let args = &[
+ "compiletest",
+ "--mode=ui",
+ "--suite=ui",
+ "--compile-lib-path=",
+ "--run-lib-path=",
+ "--python=",
+ "--jsondocck-path=",
+ "--src-base=",
+ "--build-base=",
+ "--sysroot-base=",
+ "--cc=c",
+ "--cxx=c++",
+ "--cflags=",
+ "--cxxflags=",
+ "--llvm-components=",
+ "--android-cross-path=",
+ "--stage-id",
+ self.stage_id.as_deref().unwrap_or("stage2-x86_64-unknown-linux-gnu"),
+ "--channel",
+ self.channel.as_deref().unwrap_or("nightly"),
+ "--host",
+ self.host.as_deref().unwrap_or("x86_64-unknown-linux-gnu"),
+ "--target",
+ self.target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"),
+ ];
+ let mut args: Vec<String> = args.iter().map(ToString::to_string).collect();
+
+ if let Some(ref llvm_version) = self.llvm_version {
+ args.push("--llvm-version".to_owned());
+ args.push(llvm_version.clone());
+ }
+
+ if self.git_hash {
+ args.push("--git-hash".to_owned());
+ }
+ if self.system_llvm {
+ args.push("--system-llvm".to_owned());
+ }
+
+ args.push("--rustc-path".to_string());
+ // This is a subtle/fragile thing. On rust-lang CI, there is no global
+ // `rustc`, and Cargo doesn't offer a convenient way to get the path to
+ // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing
+ // to the stage0 compiler.
+ //
+ // Otherwise, if you are running compiletests's tests manually, you
+ // probably don't have `RUSTC` set, in which case this falls back to the
+ // global rustc. If your global rustc is too far out of sync with stage0,
+ // then this may cause confusing errors. Or if for some reason you don't
+ // have rustc in PATH, that would also fail.
+ args.push(std::env::var("RUSTC").unwrap_or_else(|_| {
+ eprintln!(
+ "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)"
+ );
+ "rustc".to_string()
+ }));
+ crate::parse_config(args)
+ }
+}
+
+fn cfg() -> ConfigBuilder {
+ ConfigBuilder::default()
}
fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
@@ -115,7 +185,7 @@ fn parse_makefile(config: &Config, contents: &str) -> EarlyProps {
#[test]
fn should_fail() {
- let config = config();
+ let config: Config = cfg().build();
let tn = test::DynTestName(String::new());
let p = Path::new("a.rs");
@@ -127,7 +197,7 @@ fn should_fail() {
#[test]
fn revisions() {
- let config = config();
+ let config: Config = cfg().build();
assert_eq!(parse_rs(&config, "// revisions: a b c").revisions, vec!["a", "b", "c"],);
assert_eq!(
@@ -138,7 +208,7 @@ fn revisions() {
#[test]
fn aux_build() {
- let config = config();
+ let config: Config = cfg().build();
assert_eq!(
parse_rs(
@@ -155,36 +225,31 @@ fn aux_build() {
#[test]
fn no_system_llvm() {
- let mut config = config();
-
- config.system_llvm = false;
+ let config: Config = cfg().system_llvm(false).build();
assert!(!check_ignore(&config, "// no-system-llvm"));
- config.system_llvm = true;
+ let config: Config = cfg().system_llvm(true).build();
assert!(check_ignore(&config, "// no-system-llvm"));
}
#[test]
fn llvm_version() {
- let mut config = config();
-
- config.llvm_version = Some(80102);
+ let config: Config = cfg().llvm_version("8.1.2").build();
assert!(check_ignore(&config, "// min-llvm-version: 9.0"));
- config.llvm_version = Some(90001);
+ let config: Config = cfg().llvm_version("9.0.1").build();
assert!(check_ignore(&config, "// min-llvm-version: 9.2"));
- config.llvm_version = Some(90301);
+ let config: Config = cfg().llvm_version("9.3.1").build();
assert!(!check_ignore(&config, "// min-llvm-version: 9.2"));
- config.llvm_version = Some(100000);
+ let config: Config = cfg().llvm_version("10.0.0").build();
assert!(!check_ignore(&config, "// min-llvm-version: 9.0"));
}
#[test]
fn ignore_target() {
- let mut config = config();
- config.target = "x86_64-unknown-linux-gnu".to_owned();
+ let config: Config = cfg().target("x86_64-unknown-linux-gnu").build();
assert!(check_ignore(&config, "// ignore-x86_64-unknown-linux-gnu"));
assert!(check_ignore(&config, "// ignore-x86_64"));
@@ -200,8 +265,7 @@ fn ignore_target() {
#[test]
fn only_target() {
- let mut config = config();
- config.target = "x86_64-pc-windows-gnu".to_owned();
+ let config: Config = cfg().target("x86_64-pc-windows-gnu").build();
assert!(check_ignore(&config, "// only-x86"));
assert!(check_ignore(&config, "// only-linux"));
@@ -217,8 +281,7 @@ fn only_target() {
#[test]
fn stage() {
- let mut config = config();
- config.stage_id = "stage1-x86_64-unknown-linux-gnu".to_owned();
+ let config: Config = cfg().stage_id("stage1-x86_64-unknown-linux-gnu").build();
assert!(check_ignore(&config, "// ignore-stage1"));
assert!(!check_ignore(&config, "// ignore-stage2"));
@@ -226,18 +289,16 @@ fn stage() {
#[test]
fn cross_compile() {
- let mut config = config();
- config.host = "x86_64-apple-darwin".to_owned();
- config.target = "wasm32-unknown-unknown".to_owned();
+ let config: Config = cfg().host("x86_64-apple-darwin").target("wasm32-unknown-unknown").build();
assert!(check_ignore(&config, "// ignore-cross-compile"));
- config.target = config.host.clone();
+ let config: Config = cfg().host("x86_64-apple-darwin").target("x86_64-apple-darwin").build();
assert!(!check_ignore(&config, "// ignore-cross-compile"));
}
#[test]
fn debugger() {
- let mut config = config();
+ let mut config = cfg().build();
config.debugger = None;
assert!(!check_ignore(&config, "// ignore-cdb"));
@@ -253,27 +314,24 @@ fn debugger() {
#[test]
fn git_hash() {
- let mut config = config();
- config.git_hash = false;
+ let config: Config = cfg().git_hash(false).build();
assert!(check_ignore(&config, "// needs-git-hash"));
- config.git_hash = true;
+ let config: Config = cfg().git_hash(true).build();
assert!(!check_ignore(&config, "// needs-git-hash"));
}
#[test]
fn sanitizers() {
- let mut config = config();
-
// Target that supports all sanitizers:
- config.target = "x86_64-unknown-linux-gnu".to_owned();
+ let config: Config = cfg().target("x86_64-unknown-linux-gnu").build();
assert!(!check_ignore(&config, "// needs-sanitizer-address"));
assert!(!check_ignore(&config, "// needs-sanitizer-leak"));
assert!(!check_ignore(&config, "// needs-sanitizer-memory"));
assert!(!check_ignore(&config, "// needs-sanitizer-thread"));
// Target that doesn't support sanitizers:
- config.target = "wasm32-unknown-emscripten".to_owned();
+ let config: Config = cfg().target("wasm32-unknown-emscripten").build();
assert!(check_ignore(&config, "// needs-sanitizer-address"));
assert!(check_ignore(&config, "// needs-sanitizer-leak"));
assert!(check_ignore(&config, "// needs-sanitizer-memory"));
@@ -291,8 +349,7 @@ fn asm_support() {
("i686-unknown-netbsd", true),
];
for (target, has_asm) in asms {
- let mut config = config();
- config.target = target.to_string();
+ let config = cfg().target(target).build();
assert_eq!(config.has_asm_support(), has_asm);
assert_eq!(check_ignore(&config, "// needs-asm-support"), !has_asm)
}
@@ -300,8 +357,7 @@ fn asm_support() {
#[test]
fn channel() {
- let mut config = config();
- config.channel = "beta".into();
+ let config: Config = cfg().channel("beta").build();
assert!(check_ignore(&config, "// ignore-beta"));
assert!(check_ignore(&config, "// only-nightly"));
@@ -330,7 +386,7 @@ fn test_extract_version_range() {
#[test]
#[should_panic(expected = "Duplicate revision: `rpass1` in line ` rpass1 rpass1`")]
fn test_duplicate_revisions() {
- let config = config();
+ let config: Config = cfg().build();
parse_rs(&config, "// revisions: rpass1 rpass1");
}
@@ -345,8 +401,7 @@ fn ignore_arch() {
("thumbv7m-none-eabi", "thumb"),
];
for (target, arch) in archs {
- let mut config = config();
- config.target = target.to_string();
+ let config: Config = cfg().target(target).build();
assert!(config.matches_arch(arch), "{target} {arch}");
assert!(check_ignore(&config, &format!("// ignore-{arch}")));
}
@@ -361,8 +416,7 @@ fn matches_os() {
("x86_64-unknown-none", "none"),
];
for (target, os) in oss {
- let mut config = config();
- config.target = target.to_string();
+ let config = cfg().target(target).build();
assert!(config.matches_os(os), "{target} {os}");
assert!(check_ignore(&config, &format!("// ignore-{os}")));
}
@@ -376,8 +430,7 @@ fn matches_env() {
("arm-unknown-linux-musleabi", "musl"),
];
for (target, env) in envs {
- let mut config = config();
- config.target = target.to_string();
+ let config: Config = cfg().target(target).build();
assert!(config.matches_env(env), "{target} {env}");
assert!(check_ignore(&config, &format!("// ignore-{env}")));
}
@@ -391,8 +444,7 @@ fn matches_abi() {
("arm-unknown-linux-gnueabi", "eabi"),
];
for (target, abi) in abis {
- let mut config = config();
- config.target = target.to_string();
+ let config: Config = cfg().target(target).build();
assert!(config.matches_abi(abi), "{target} {abi}");
assert!(check_ignore(&config, &format!("// ignore-{abi}")));
}
@@ -408,8 +460,7 @@ fn is_big_endian() {
("powerpc64-unknown-linux-gnu", true),
];
for (target, is_big) in endians {
- let mut config = config();
- config.target = target.to_string();
+ let config = cfg().target(target).build();
assert_eq!(config.is_big_endian(), is_big, "{target} {is_big}");
assert_eq!(check_ignore(&config, "// ignore-endian-big"), is_big);
}
@@ -424,8 +475,7 @@ fn pointer_width() {
("msp430-none-elf", 16),
];
for (target, width) in widths {
- let mut config = config();
- config.target = target.to_string();
+ let config: Config = cfg().target(target).build();
assert_eq!(config.get_pointer_width(), width, "{target} {width}");
assert_eq!(check_ignore(&config, "// ignore-16bit"), width == 16);
assert_eq!(check_ignore(&config, "// ignore-32bit"), width == 32);
@@ -456,8 +506,7 @@ fn wasm_special() {
("wasm64-unknown-unknown", "wasm64", true),
];
for (target, pattern, ignore) in ignores {
- let mut config = config();
- config.target = target.to_string();
+ let config: Config = cfg().target(target).build();
assert_eq!(
check_ignore(&config, &format!("// ignore-{pattern}")),
ignore,
@@ -476,8 +525,7 @@ fn families() {
("wasm32-unknown-emscripten", "unix"),
];
for (target, family) in families {
- let mut config = config();
- config.target = target.to_string();
+ let config: Config = cfg().target(target).build();
assert!(config.matches_family(family));
let other = if family == "windows" { "unix" } else { "windows" };
assert!(!config.matches_family(other));
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 1a765477f..619ff9b32 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -48,6 +48,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
.reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH")
.optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
.optopt("", "rust-demangler-path", "path to rust-demangler to use in tests", "PATH")
+ .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH")
.reqopt("", "python", "path to python to use for doc tests", "PATH")
.optopt("", "jsondocck-path", "path to jsondocck to use for doc tests", "PATH")
.optopt("", "jsondoclint-path", "path to jsondoclint to use for doc tests", "PATH")
@@ -218,6 +219,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
rustc_path: opt_path(matches, "rustc-path"),
rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from),
rust_demangler_path: matches.opt_str("rust-demangler-path").map(PathBuf::from),
+ coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from),
python: matches.opt_str("python").unwrap(),
jsondocck_path: matches.opt_str("jsondocck-path"),
jsondoclint_path: matches.opt_str("jsondoclint-path"),
diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs
index a455a1bad..3f1921cb6 100644
--- a/src/tools/compiletest/src/read2.rs
+++ b/src/tools/compiletest/src/read2.rs
@@ -9,7 +9,16 @@ use std::io::{self, Write};
use std::mem::replace;
use std::process::{Child, Output};
-pub fn read2_abbreviated(mut child: Child, filter_paths_from_len: &[String]) -> io::Result<Output> {
+#[derive(Copy, Clone, Debug)]
+pub enum Truncated {
+ Yes,
+ No,
+}
+
+pub fn read2_abbreviated(
+ mut child: Child,
+ filter_paths_from_len: &[String],
+) -> io::Result<(Output, Truncated)> {
let mut stdout = ProcOutput::new();
let mut stderr = ProcOutput::new();
@@ -24,11 +33,12 @@ pub fn read2_abbreviated(mut child: Child, filter_paths_from_len: &[String]) ->
)?;
let status = child.wait()?;
- Ok(Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() })
+ let truncated =
+ if stdout.truncated() || stderr.truncated() { Truncated::Yes } else { Truncated::No };
+ Ok((Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() }, truncated))
}
-const HEAD_LEN: usize = 160 * 1024;
-const TAIL_LEN: usize = 256 * 1024;
+const MAX_OUT_LEN: usize = 512 * 1024;
// Whenever a path is filtered when counting the length of the output, we need to add some
// placeholder length to ensure a compiler emitting only filtered paths doesn't cause a OOM.
@@ -39,7 +49,7 @@ const FILTERED_PATHS_PLACEHOLDER_LEN: usize = 32;
enum ProcOutput {
Full { bytes: Vec<u8>, filtered_len: usize },
- Abbreviated { head: Vec<u8>, skipped: usize, tail: Box<[u8]> },
+ Abbreviated { head: Vec<u8>, skipped: usize },
}
impl ProcOutput {
@@ -47,6 +57,10 @@ impl ProcOutput {
ProcOutput::Full { bytes: Vec::new(), filtered_len: 0 }
}
+ fn truncated(&self) -> bool {
+ matches!(self, Self::Abbreviated { .. })
+ }
+
fn extend(&mut self, data: &[u8], filter_paths_from_len: &[String]) {
let new_self = match *self {
ProcOutput::Full { ref mut bytes, ref mut filtered_len } => {
@@ -83,24 +97,21 @@ impl ProcOutput {
}
let new_len = bytes.len();
- if (*filtered_len).min(new_len) <= HEAD_LEN + TAIL_LEN {
+ if (*filtered_len).min(new_len) <= MAX_OUT_LEN {
return;
}
let mut head = replace(bytes, Vec::new());
- let mut middle = head.split_off(HEAD_LEN);
- let tail = middle.split_off(middle.len() - TAIL_LEN).into_boxed_slice();
- let skipped = new_len - HEAD_LEN - TAIL_LEN;
- ProcOutput::Abbreviated { head, skipped, tail }
+ // Don't truncate if this as a whole line.
+ // That should make it less likely that we cut a JSON line in half.
+ if head.last() != Some(&('\n' as u8)) {
+ head.truncate(MAX_OUT_LEN);
+ }
+ let skipped = new_len - head.len();
+ ProcOutput::Abbreviated { head, skipped }
}
- ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => {
+ ProcOutput::Abbreviated { ref mut skipped, .. } => {
*skipped += data.len();
- if data.len() <= TAIL_LEN {
- tail[..data.len()].copy_from_slice(data);
- tail.rotate_left(data.len());
- } else {
- tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]);
- }
return;
}
};
@@ -110,18 +121,12 @@ impl ProcOutput {
fn into_bytes(self) -> Vec<u8> {
match self {
ProcOutput::Full { bytes, .. } => bytes,
- ProcOutput::Abbreviated { mut head, mut skipped, tail } => {
- let mut tail = &*tail;
-
- // Skip over '{' at the start of the tail, so we don't later wrongfully consider this as json.
- // See <https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Weird.20CI.20failure/near/321797811>
- while tail.get(0) == Some(&b'{') {
- tail = &tail[1..];
- skipped += 1;
- }
-
- write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap();
- head.extend_from_slice(tail);
+ ProcOutput::Abbreviated { mut head, skipped } => {
+ let head_note =
+ format!("<<<<<< TRUNCATED, SHOWING THE FIRST {} BYTES >>>>>>\n\n", head.len());
+ head.splice(0..0, head_note.into_bytes());
+ write!(&mut head, "\n\n<<<<<< TRUNCATED, DROPPED {} BYTES >>>>>>", skipped)
+ .unwrap();
head
}
}
diff --git a/src/tools/compiletest/src/read2/tests.rs b/src/tools/compiletest/src/read2/tests.rs
index 1ca682a46..5ad2db3cb 100644
--- a/src/tools/compiletest/src/read2/tests.rs
+++ b/src/tools/compiletest/src/read2/tests.rs
@@ -1,4 +1,6 @@
-use crate::read2::{ProcOutput, FILTERED_PATHS_PLACEHOLDER_LEN, HEAD_LEN, TAIL_LEN};
+use std::io::Write;
+
+use crate::read2::{ProcOutput, FILTERED_PATHS_PLACEHOLDER_LEN, MAX_OUT_LEN};
#[test]
fn test_abbreviate_short_string() {
@@ -21,35 +23,13 @@ fn test_abbreviate_short_string_multiple_steps() {
fn test_abbreviate_long_string() {
let mut out = ProcOutput::new();
- let data = vec![b'.'; HEAD_LEN + TAIL_LEN + 16];
+ let data = vec![b'.'; MAX_OUT_LEN + 16];
out.extend(&data, &[]);
- let mut expected = vec![b'.'; HEAD_LEN];
- expected.extend_from_slice(b"\n\n<<<<<< SKIPPED 16 BYTES >>>>>>\n\n");
- expected.extend_from_slice(&vec![b'.'; TAIL_LEN]);
-
- // We first check the length to avoid endless terminal output if the length differs, since
- // `out` is hundreds of KBs in size.
- let out = out.into_bytes();
- assert_eq!(expected.len(), out.len());
- assert_eq!(expected, out);
-}
-
-#[test]
-fn test_abbreviate_long_string_multiple_steps() {
- let mut out = ProcOutput::new();
-
- out.extend(&vec![b'.'; HEAD_LEN], &[]);
- out.extend(&vec![b'.'; TAIL_LEN], &[]);
- // Also test whether the rotation works
- out.extend(&vec![b'!'; 16], &[]);
- out.extend(&vec![b'?'; 16], &[]);
-
- let mut expected = vec![b'.'; HEAD_LEN];
- expected.extend_from_slice(b"\n\n<<<<<< SKIPPED 32 BYTES >>>>>>\n\n");
- expected.extend_from_slice(&vec![b'.'; TAIL_LEN - 32]);
- expected.extend_from_slice(&vec![b'!'; 16]);
- expected.extend_from_slice(&vec![b'?'; 16]);
+ let mut expected = Vec::new();
+ write!(expected, "<<<<<< TRUNCATED, SHOWING THE FIRST {MAX_OUT_LEN} BYTES >>>>>>\n\n").unwrap();
+ expected.extend_from_slice(&[b'.'; MAX_OUT_LEN]);
+ expected.extend_from_slice(b"\n\n<<<<<< TRUNCATED, DROPPED 16 BYTES >>>>>>");
// We first check the length to avoid endless terminal output if the length differs, since
// `out` is hundreds of KBs in size.
@@ -86,9 +66,8 @@ fn test_abbreviate_filters_avoid_abbreviations() {
let mut out = ProcOutput::new();
let filters = &[std::iter::repeat('a').take(64).collect::<String>()];
- let mut expected = vec![b'.'; HEAD_LEN - FILTERED_PATHS_PLACEHOLDER_LEN as usize];
+ let mut expected = vec![b'.'; MAX_OUT_LEN - FILTERED_PATHS_PLACEHOLDER_LEN as usize];
expected.extend_from_slice(filters[0].as_bytes());
- expected.extend_from_slice(&vec![b'.'; TAIL_LEN]);
out.extend(&expected, filters);
@@ -104,14 +83,13 @@ fn test_abbreviate_filters_can_still_cause_abbreviations() {
let mut out = ProcOutput::new();
let filters = &[std::iter::repeat('a').take(64).collect::<String>()];
- let mut input = vec![b'.'; HEAD_LEN];
- input.extend_from_slice(&vec![b'.'; TAIL_LEN]);
+ let mut input = vec![b'.'; MAX_OUT_LEN];
input.extend_from_slice(filters[0].as_bytes());
- let mut expected = vec![b'.'; HEAD_LEN];
- expected.extend_from_slice(b"\n\n<<<<<< SKIPPED 64 BYTES >>>>>>\n\n");
- expected.extend_from_slice(&vec![b'.'; TAIL_LEN - 64]);
- expected.extend_from_slice(&vec![b'a'; 64]);
+ let mut expected = Vec::new();
+ write!(expected, "<<<<<< TRUNCATED, SHOWING THE FIRST {MAX_OUT_LEN} BYTES >>>>>>\n\n").unwrap();
+ expected.extend_from_slice(&[b'.'; MAX_OUT_LEN]);
+ expected.extend_from_slice(b"\n\n<<<<<< TRUNCATED, DROPPED 64 BYTES >>>>>>");
out.extend(&input, filters);
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 4ef79af31..657d074b3 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -6,13 +6,13 @@ use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, RustdocJs
use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc};
use crate::common::{CompareMode, FailMode, PassMode};
use crate::common::{Config, TestPaths};
-use crate::common::{Pretty, RunCoverage, RunPassValgrind};
-use crate::common::{UI_COVERAGE, UI_RUN_STDERR, UI_RUN_STDOUT};
+use crate::common::{CoverageMap, Pretty, RunCoverage, RunPassValgrind};
+use crate::common::{UI_COVERAGE, UI_COVERAGE_MAP, UI_RUN_STDERR, UI_RUN_STDOUT};
use crate::compute_diff::{write_diff, write_filtered_diff};
use crate::errors::{self, Error, ErrorKind};
use crate::header::TestProps;
use crate::json;
-use crate::read2::read2_abbreviated;
+use crate::read2::{read2_abbreviated, Truncated};
use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
use crate::ColorConfig;
use regex::{Captures, Regex};
@@ -254,6 +254,7 @@ impl<'test> TestCx<'test> {
MirOpt => self.run_mir_opt_test(),
Assembly => self.run_assembly_test(),
JsDocTest => self.run_js_doc_test(),
+ CoverageMap => self.run_coverage_map_test(),
RunCoverage => self.run_coverage_test(),
}
}
@@ -467,6 +468,46 @@ impl<'test> TestCx<'test> {
}
}
+ fn run_coverage_map_test(&self) {
+ let Some(coverage_dump_path) = &self.config.coverage_dump_path else {
+ self.fatal("missing --coverage-dump");
+ };
+
+ let proc_res = self.compile_test_and_save_ir();
+ if !proc_res.status.success() {
+ self.fatal_proc_rec("compilation failed!", &proc_res);
+ }
+ drop(proc_res);
+
+ let llvm_ir_path = self.output_base_name().with_extension("ll");
+
+ let mut dump_command = Command::new(coverage_dump_path);
+ dump_command.arg(llvm_ir_path);
+ let proc_res = self.run_command_to_procres(&mut dump_command);
+ if !proc_res.status.success() {
+ self.fatal_proc_rec("coverage-dump failed!", &proc_res);
+ }
+
+ let kind = UI_COVERAGE_MAP;
+
+ let expected_coverage_dump = self.load_expected_output(kind);
+ let actual_coverage_dump = self.normalize_output(&proc_res.stdout, &[]);
+
+ let coverage_dump_errors = self.compare_output(
+ kind,
+ &actual_coverage_dump,
+ &expected_coverage_dump,
+ self.props.compare_output_lines_by_subset,
+ );
+
+ if coverage_dump_errors > 0 {
+ self.fatal_proc_rec(
+ &format!("{coverage_dump_errors} errors occurred comparing coverage output."),
+ &proc_res,
+ );
+ }
+ }
+
fn run_coverage_test(&self) {
let should_run = self.run_if_enabled();
let proc_res = self.compile_test(should_run, Emit::None);
@@ -650,12 +691,17 @@ impl<'test> TestCx<'test> {
let mut cmd = Command::new(tool_path);
configure_cmd_fn(&mut cmd);
- let output = cmd.output().unwrap_or_else(|_| panic!("failed to exec `{cmd:?}`"));
+ self.run_command_to_procres(&mut cmd)
+ }
+
+ fn run_command_to_procres(&self, cmd: &mut Command) -> ProcRes {
+ let output = cmd.output().unwrap_or_else(|e| panic!("failed to exec `{cmd:?}`: {e:?}"));
let proc_res = ProcRes {
status: output.status,
stdout: String::from_utf8(output.stdout).unwrap(),
stderr: String::from_utf8(output.stderr).unwrap(),
+ truncated: Truncated::No,
cmdline: format!("{cmd:?}"),
};
self.dump_output(&proc_res.stdout, &proc_res.stderr);
@@ -1170,12 +1216,12 @@ impl<'test> TestCx<'test> {
.arg(&exe_file)
.arg(&self.config.adb_test_dir)
.status()
- .unwrap_or_else(|_| panic!("failed to exec `{:?}`", adb_path));
+ .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
Command::new(adb_path)
.args(&["forward", "tcp:5039", "tcp:5039"])
.status()
- .unwrap_or_else(|_| panic!("failed to exec `{:?}`", adb_path));
+ .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
let adb_arg = format!(
"export LD_LIBRARY_PATH={}; \
@@ -1192,7 +1238,7 @@ impl<'test> TestCx<'test> {
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.spawn()
- .unwrap_or_else(|_| panic!("failed to exec `{:?}`", adb_path));
+ .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
// Wait for the gdbserver to print out "Listening on port ..."
// at which point we know that it's started and then we can
@@ -1217,7 +1263,7 @@ impl<'test> TestCx<'test> {
let Output { status, stdout, stderr } = Command::new(&gdb_path)
.args(debugger_opts)
.output()
- .unwrap_or_else(|_| panic!("failed to exec `{:?}`", gdb_path));
+ .unwrap_or_else(|e| panic!("failed to exec `{gdb_path:?}`: {e:?}"));
let cmdline = {
let mut gdb = Command::new(&format!("{}-gdb", self.config.target));
gdb.args(debugger_opts);
@@ -1230,6 +1276,7 @@ impl<'test> TestCx<'test> {
status,
stdout: String::from_utf8(stdout).unwrap(),
stderr: String::from_utf8(stderr).unwrap(),
+ truncated: Truncated::No,
cmdline,
};
if adb.kill().is_err() {
@@ -1430,6 +1477,15 @@ impl<'test> TestCx<'test> {
"^core::num::([a-z_]+::)*NonZero.+$",
];
+ // In newer versions of lldb, persistent results (the `$N =` part at the start of
+ // expressions you have evaluated that let you re-use the result) aren't printed, but lots
+ // of rustc's debuginfo tests rely on these, so re-enable this.
+ // See <https://reviews.llvm.org/rG385496385476fc9735da5fa4acabc34654e8b30d>.
+ script_str.push_str("command unalias print\n");
+ script_str.push_str("command alias print expr --\n");
+ script_str.push_str("command unalias p\n");
+ script_str.push_str("command alias p expr --\n");
+
script_str
.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]);
script_str.push_str("type synthetic add -l lldb_lookup.synthetic_lookup -x '.*' ");
@@ -1512,7 +1568,13 @@ impl<'test> TestCx<'test> {
};
self.dump_output(&out, &err);
- ProcRes { status, stdout: out, stderr: err, cmdline: format!("{:?}", cmd) }
+ ProcRes {
+ status,
+ stdout: out,
+ stderr: err,
+ truncated: Truncated::No,
+ cmdline: format!("{:?}", cmd),
+ }
}
fn cleanup_debug_info_options(&self, options: &Vec<String>) -> Vec<String> {
@@ -2173,7 +2235,7 @@ impl<'test> TestCx<'test> {
dylib
}
- fn read2_abbreviated(&self, child: Child) -> Output {
+ fn read2_abbreviated(&self, child: Child) -> (Output, Truncated) {
let mut filter_paths_from_len = Vec::new();
let mut add_path = |path: &Path| {
let path = path.display().to_string();
@@ -2215,17 +2277,18 @@ impl<'test> TestCx<'test> {
add_dylib_path(&mut command, iter::once(lib_path).chain(aux_path));
let mut child = disable_error_reporting(|| command.spawn())
- .unwrap_or_else(|_| panic!("failed to exec `{:?}`", &command));
+ .unwrap_or_else(|e| panic!("failed to exec `{command:?}`: {e:?}"));
if let Some(input) = input {
child.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
}
- let Output { status, stdout, stderr } = self.read2_abbreviated(child);
+ let (Output { status, stdout, stderr }, truncated) = self.read2_abbreviated(child);
let result = ProcRes {
status,
stdout: String::from_utf8_lossy(&stdout).into_owned(),
stderr: String::from_utf8_lossy(&stderr).into_owned(),
+ truncated,
cmdline,
};
@@ -2272,6 +2335,18 @@ impl<'test> TestCx<'test> {
rustc.arg("-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX");
rustc.arg("-Ztranslate-remapped-path-to-local-path=no");
+ // #[cfg(not(bootstrap))]: After beta bump, this should **always** run.
+ if !(self.config.stage_id.starts_with("stage1-") && self.config.suite == "ui-fulldeps") {
+ // Hide Cargo dependency sources from ui tests to make sure the error message doesn't
+ // change depending on whether $CARGO_HOME is remapped or not. If this is not present,
+ // when $CARGO_HOME is remapped the source won't be shown, and when it's not remapped the
+ // source will be shown, causing a blessing hell.
+ rustc.arg("-Z").arg(format!(
+ "ignore-directory-in-diagnostics-source-blocks={}",
+ home::cargo_home().expect("failed to find cargo home").to_str().unwrap()
+ ));
+ }
+
// Optionally prevent default --sysroot if specified in test compile-flags.
if !self.props.compile_flags.iter().any(|flag| flag.starts_with("--sysroot"))
&& !self.config.host_rustcflags.iter().any(|flag| flag == "--sysroot")
@@ -2321,9 +2396,11 @@ impl<'test> TestCx<'test> {
}
}
DebugInfo => { /* debuginfo tests must be unoptimized */ }
- RunCoverage => {
- // Coverage reports are affected by optimization level, and
- // the current snapshots assume no optimization by default.
+ CoverageMap | RunCoverage => {
+ // Coverage mappings and coverage reports are affected by
+ // optimization level, so they ignore the optimize-tests
+ // setting and set an optimization level in their mode's
+ // compile flags (below) or in per-test `compile-flags`.
}
_ => {
rustc.arg("-O");
@@ -2354,14 +2431,7 @@ impl<'test> TestCx<'test> {
// Hide line numbers to reduce churn
rustc.arg("-Zui-testing");
rustc.arg("-Zdeduplicate-diagnostics=no");
- // #[cfg(not(bootstrap)] unconditionally pass flag after beta bump
- // since `ui-fulldeps --stage=1` builds using the stage 0 compiler,
- // which doesn't have this flag.
- if !(self.config.stage_id.starts_with("stage1-")
- && self.config.suite == "ui-fulldeps")
- {
- rustc.arg("-Zwrite-long-types-to-disk=no");
- }
+ rustc.arg("-Zwrite-long-types-to-disk=no");
// FIXME: use this for other modes too, for perf?
rustc.arg("-Cstrip=debuginfo");
}
@@ -2399,8 +2469,22 @@ impl<'test> TestCx<'test> {
rustc.arg(dir_opt);
}
+ CoverageMap => {
+ rustc.arg("-Cinstrument-coverage");
+ // These tests only compile to MIR, so they don't need the
+ // profiler runtime to be present.
+ rustc.arg("-Zno-profiler-runtime");
+ // Coverage mappings are sensitive to MIR optimizations, and
+ // the current snapshots assume `opt-level=2` unless overridden
+ // by `compile-flags`.
+ rustc.arg("-Copt-level=2");
+ }
RunCoverage => {
rustc.arg("-Cinstrument-coverage");
+ // Coverage reports are sometimes sensitive to optimizations,
+ // and the current snapshots assume no optimization unless
+ // overridden by `compile-flags`.
+ rustc.arg("-Copt-level=0");
}
RunPassValgrind | Pretty | DebugInfo | Codegen | Rustdoc | RustdocJson | RunMake
| CodegenUnits | JsDocTest | Assembly => {
@@ -2483,13 +2567,8 @@ impl<'test> TestCx<'test> {
rustc.args(&["-A", "unused"]);
}
- // #[cfg(not(bootstrap)] unconditionally pass flag after beta bump
- // since `ui-fulldeps --stage=1` builds using the stage 0 compiler,
- // which doesn't have this lint.
- if !(self.config.stage_id.starts_with("stage1-") && self.config.suite == "ui-fulldeps") {
- // Allow tests to use internal features.
- rustc.args(&["-A", "internal_features"]);
- }
+ // Allow tests to use internal features.
+ rustc.args(&["-A", "internal_features"]);
if self.props.force_host {
self.maybe_add_external_args(&mut rustc, &self.config.host_rustcflags);
@@ -3552,12 +3631,14 @@ impl<'test> TestCx<'test> {
}
}
- let output = self.read2_abbreviated(cmd.spawn().expect("failed to spawn `make`"));
+ let (output, truncated) =
+ self.read2_abbreviated(cmd.spawn().expect("failed to spawn `make`"));
if !output.status.success() {
let res = ProcRes {
status: output.status,
stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
+ truncated,
cmdline: format!("{:?}", cmd),
};
self.fatal_proc_rec("make failed", &res);
@@ -3634,26 +3715,30 @@ impl<'test> TestCx<'test> {
let expected_stderr = self.load_expected_output(stderr_kind);
let expected_stdout = self.load_expected_output(stdout_kind);
- let normalized_stdout = match output_kind {
+ let mut normalized_stdout =
+ self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
+ match output_kind {
TestOutput::Run if self.config.remote_test_client.is_some() => {
// When tests are run using the remote-test-client, the string
// 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"'
// is printed to stdout by the client and then captured in the ProcRes,
- // so it needs to be removed when comparing the run-pass test execution output
+ // so it needs to be removed when comparing the run-pass test execution output.
static REMOTE_TEST_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(
"^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n"
)
.unwrap()
});
- REMOTE_TEST_RE
- .replace(
- &self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout),
- "",
- )
- .to_string()
+ normalized_stdout = REMOTE_TEST_RE.replace(&normalized_stdout, "").to_string();
+ // When there is a panic, the remote-test-client also prints "died due to signal";
+ // that needs to be removed as well.
+ static SIGNAL_DIED_RE: Lazy<Regex> =
+ Lazy::new(|| Regex::new("^died due to signal [0-9]+\n").unwrap());
+ normalized_stdout = SIGNAL_DIED_RE.replace(&normalized_stdout, "").to_string();
+ // FIXME: it would be much nicer if we could just tell the remote-test-client to not
+ // print these things.
}
- _ => self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout),
+ _ => {}
};
let stderr = if explicit_format {
@@ -3715,6 +3800,15 @@ impl<'test> TestCx<'test> {
let emit_metadata = self.should_emit_metadata(pm);
let proc_res = self.compile_test(should_run, emit_metadata);
self.check_if_test_should_compile(&proc_res, pm);
+ if matches!(proc_res.truncated, Truncated::Yes)
+ && !self.props.dont_check_compiler_stdout
+ && !self.props.dont_check_compiler_stderr
+ {
+ self.fatal_proc_rec(
+ &format!("compiler output got truncated, cannot compare with reference file"),
+ &proc_res,
+ );
+ }
// if the user specified a format in the ui test
// print the output to the stderr file, otherwise extract
@@ -3756,8 +3850,8 @@ impl<'test> TestCx<'test> {
.open(coverage_file_path.as_path())
.expect("could not create or open file");
- if writeln!(file, "{}", self.testpaths.file.display()).is_err() {
- panic!("couldn't write to {}", coverage_file_path.display());
+ if let Err(e) = writeln!(file, "{}", self.testpaths.file.display()) {
+ panic!("couldn't write to {}: {e:?}", coverage_file_path.display());
}
}
} else if self.props.run_rustfix {
@@ -4406,6 +4500,7 @@ pub struct ProcRes {
status: ExitStatus,
stdout: String,
stderr: String,
+ truncated: Truncated,
cmdline: String,
}
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 17bed38b6..8f9425eb0 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -9,103 +9,6 @@ use tracing::*;
#[cfg(test)]
mod tests;
-pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
- "aarch64-apple-darwin",
- "aarch64-apple-ios",
- "aarch64-apple-ios-sim",
- "aarch64-unknown-fuchsia",
- "aarch64-linux-android",
- "aarch64-unknown-linux-gnu",
- "arm-linux-androideabi",
- "armv7-linux-androideabi",
- "i686-linux-android",
- "i686-unknown-linux-gnu",
- "x86_64-apple-darwin",
- "x86_64-apple-ios",
- "x86_64-unknown-fuchsia",
- "x86_64-linux-android",
- "x86_64-unknown-freebsd",
- "x86_64-unknown-linux-gnu",
- "s390x-unknown-linux-gnu",
-];
-
-// FIXME(rcvalle): More targets are likely supported.
-pub const CFI_SUPPORTED_TARGETS: &[&str] = &[
- "aarch64-apple-darwin",
- "aarch64-unknown-fuchsia",
- "aarch64-linux-android",
- "aarch64-unknown-freebsd",
- "aarch64-unknown-linux-gnu",
- "x86_64-apple-darwin",
- "x86_64-unknown-fuchsia",
- "x86_64-pc-solaris",
- "x86_64-unknown-freebsd",
- "x86_64-unknown-illumos",
- "x86_64-unknown-linux-gnu",
- "x86_64-unknown-linux-musl",
- "x86_64-unknown-netbsd",
-];
-
-pub const KCFI_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-none", "x86_64-linux-none"];
-
-pub const KASAN_SUPPORTED_TARGETS: &[&str] = &[
- "aarch64-unknown-none",
- "riscv64gc-unknown-none-elf",
- "riscv64imac-unknown-none-elf",
- "x86_64-unknown-none",
-];
-
-pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[
- // FIXME: currently broken, see #88132
- // "aarch64-apple-darwin",
- "aarch64-unknown-linux-gnu",
- "x86_64-apple-darwin",
- "x86_64-unknown-linux-gnu",
- "s390x-unknown-linux-gnu",
-];
-
-pub const MSAN_SUPPORTED_TARGETS: &[&str] = &[
- "aarch64-unknown-linux-gnu",
- "x86_64-unknown-freebsd",
- "x86_64-unknown-linux-gnu",
- "s390x-unknown-linux-gnu",
-];
-
-pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[
- "aarch64-apple-darwin",
- "aarch64-apple-ios",
- "aarch64-apple-ios-sim",
- "aarch64-unknown-linux-gnu",
- "x86_64-apple-darwin",
- "x86_64-apple-ios",
- "x86_64-unknown-freebsd",
- "x86_64-unknown-linux-gnu",
- "s390x-unknown-linux-gnu",
-];
-
-pub const HWASAN_SUPPORTED_TARGETS: &[&str] =
- &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
-
-pub const MEMTAG_SUPPORTED_TARGETS: &[&str] =
- &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
-
-pub const SHADOWCALLSTACK_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-android"];
-
-pub const XRAY_SUPPORTED_TARGETS: &[&str] = &[
- "aarch64-linux-android",
- "aarch64-unknown-linux-gnu",
- "aarch64-unknown-linux-musl",
- "x86_64-linux-android",
- "x86_64-unknown-freebsd",
- "x86_64-unknown-linux-gnu",
- "x86_64-unknown-linux-musl",
- "x86_64-unknown-netbsd",
- "x86_64-unknown-none-linuxkernel",
- "x86_64-unknown-openbsd",
-];
-
-pub const SAFESTACK_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"];
-
pub fn make_new_path(path: &str) -> String {
assert!(cfg!(windows));
// Windows just uses PATH as the library search path, so we have to
diff --git a/src/tools/coverage-dump/Cargo.toml b/src/tools/coverage-dump/Cargo.toml
new file mode 100644
index 000000000..7f14286b5
--- /dev/null
+++ b/src/tools/coverage-dump/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "coverage-dump"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+anyhow = "1.0.71"
+leb128 = "0.2.5"
+md5 = { package = "md-5" , version = "0.10.5" }
+miniz_oxide = "0.7.1"
+regex = "1.8.4"
+rustc-demangle = "0.1.23"
diff --git a/src/tools/coverage-dump/README.md b/src/tools/coverage-dump/README.md
new file mode 100644
index 000000000..e2625d5ad
--- /dev/null
+++ b/src/tools/coverage-dump/README.md
@@ -0,0 +1,8 @@
+This tool extracts coverage mapping information from an LLVM IR assembly file
+(`.ll`), and prints it in a more human-readable form that can be used for
+snapshot tests.
+
+The output format is mostly arbitrary, so it's OK to change the output as long
+as any affected tests are also re-blessed. However, the output should be
+consistent across different executions on different platforms, so avoid
+printing any information that is platform-specific or non-deterministic.
diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs
new file mode 100644
index 000000000..3a5866dea
--- /dev/null
+++ b/src/tools/coverage-dump/src/covfun.rs
@@ -0,0 +1,296 @@
+use crate::parser::{unescape_llvm_string_contents, Parser};
+use anyhow::{anyhow, Context};
+use regex::Regex;
+use std::collections::HashMap;
+use std::fmt::{self, Debug, Write as _};
+use std::sync::OnceLock;
+
+pub(crate) fn dump_covfun_mappings(
+ llvm_ir: &str,
+ function_names: &HashMap<u64, String>,
+) -> anyhow::Result<()> {
+ // Extract function coverage entries from the LLVM IR assembly, and associate
+ // each entry with its (demangled) name.
+ let mut covfun_entries = llvm_ir
+ .lines()
+ .filter_map(covfun_line_data)
+ .map(|line_data| (function_names.get(&line_data.name_hash).map(String::as_str), line_data))
+ .collect::<Vec<_>>();
+ covfun_entries.sort_by(|a, b| {
+ // Sort entries primarily by name, to help make the order consistent
+ // across platforms and relatively insensitive to changes.
+ // (Sadly we can't use `sort_by_key` because we would need to return references.)
+ Ord::cmp(&a.0, &b.0)
+ .then_with(|| Ord::cmp(&a.1.is_used, &b.1.is_used))
+ .then_with(|| Ord::cmp(a.1.payload.as_slice(), b.1.payload.as_slice()))
+ });
+
+ for (name, line_data) in &covfun_entries {
+ let name = name.unwrap_or("(unknown)");
+ let unused = if line_data.is_used { "" } else { " (unused)" };
+ println!("Function name: {name}{unused}");
+
+ let payload: &[u8] = &line_data.payload;
+ println!("Raw bytes ({len}): 0x{payload:02x?}", len = payload.len());
+
+ let mut parser = Parser::new(payload);
+
+ let num_files = parser.read_uleb128_u32()?;
+ println!("Number of files: {num_files}");
+
+ for i in 0..num_files {
+ let global_file_id = parser.read_uleb128_u32()?;
+ println!("- file {i} => global file {global_file_id}");
+ }
+
+ let num_expressions = parser.read_uleb128_u32()?;
+ println!("Number of expressions: {num_expressions}");
+
+ let mut expression_resolver = ExpressionResolver::new();
+ for i in 0..num_expressions {
+ let lhs = parser.read_simple_term()?;
+ let rhs = parser.read_simple_term()?;
+ println!("- expression {i} operands: lhs = {lhs:?}, rhs = {rhs:?}");
+ expression_resolver.push_operands(lhs, rhs);
+ }
+
+ for i in 0..num_files {
+ let num_mappings = parser.read_uleb128_u32()?;
+ println!("Number of file {i} mappings: {num_mappings}");
+
+ for _ in 0..num_mappings {
+ let (kind, region) = parser.read_mapping_kind_and_region()?;
+ println!("- {kind:?} at {region:?}");
+
+ match kind {
+ // Also print expression mappings in resolved form.
+ MappingKind::Code(term @ CovTerm::Expression { .. })
+ | MappingKind::Gap(term @ CovTerm::Expression { .. }) => {
+ println!(" = {}", expression_resolver.format_term(term));
+ }
+ // If the mapping is a branch region, print both of its arms
+ // in resolved form (even if they aren't expressions).
+ MappingKind::Branch { r#true, r#false } => {
+ println!(" true = {}", expression_resolver.format_term(r#true));
+ println!(" false = {}", expression_resolver.format_term(r#false));
+ }
+ _ => (),
+ }
+ }
+ }
+
+ parser.ensure_empty()?;
+ println!();
+ }
+ Ok(())
+}
+
+struct CovfunLineData {
+ name_hash: u64,
+ is_used: bool,
+ payload: Vec<u8>,
+}
+
+/// Checks a line of LLVM IR assembly to see if it contains an `__llvm_covfun`
+/// entry, and if so extracts relevant data in a `CovfunLineData`.
+fn covfun_line_data(line: &str) -> Option<CovfunLineData> {
+ let re = {
+ // We cheat a little bit and match variable names `@__covrec_[HASH]u`
+ // rather than the section name, because the section name is harder to
+ // extract and differs across Linux/Windows/macOS. We also extract the
+ // symbol name hash from the variable name rather than the data, since
+ // it's easier and both should match.
+ static RE: OnceLock<Regex> = OnceLock::new();
+ RE.get_or_init(|| {
+ Regex::new(
+ r#"^@__covrec_(?<name_hash>[0-9A-Z]+)(?<is_used>u)? = .*\[[0-9]+ x i8\] c"(?<payload>[^"]*)".*$"#,
+ )
+ .unwrap()
+ })
+ };
+
+ let captures = re.captures(line)?;
+ let name_hash = u64::from_str_radix(&captures["name_hash"], 16).unwrap();
+ let is_used = captures.name("is_used").is_some();
+ let payload = unescape_llvm_string_contents(&captures["payload"]);
+
+ Some(CovfunLineData { name_hash, is_used, payload })
+}
+
+// Extra parser methods only needed when parsing `covfun` payloads.
+impl<'a> Parser<'a> {
+ fn read_simple_term(&mut self) -> anyhow::Result<CovTerm> {
+ let raw_term = self.read_uleb128_u32()?;
+ CovTerm::decode(raw_term).context("decoding term")
+ }
+
+ fn read_mapping_kind_and_region(&mut self) -> anyhow::Result<(MappingKind, MappingRegion)> {
+ let mut kind = self.read_raw_mapping_kind()?;
+ let mut region = self.read_raw_mapping_region()?;
+
+ const HIGH_BIT: u32 = 1u32 << 31;
+ if region.end_column & HIGH_BIT != 0 {
+ region.end_column &= !HIGH_BIT;
+ kind = match kind {
+ MappingKind::Code(term) => MappingKind::Gap(term),
+ // LLVM's coverage mapping reader will actually handle this
+ // case without complaint, but the result is almost certainly
+ // a meaningless implementation artifact.
+ _ => return Err(anyhow!("unexpected base kind for gap region: {kind:?}")),
+ }
+ }
+
+ Ok((kind, region))
+ }
+
+ fn read_raw_mapping_kind(&mut self) -> anyhow::Result<MappingKind> {
+ let raw_mapping_kind = self.read_uleb128_u32()?;
+ if let Some(term) = CovTerm::decode(raw_mapping_kind) {
+ return Ok(MappingKind::Code(term));
+ }
+
+ assert_eq!(raw_mapping_kind & 0b11, 0);
+ assert_ne!(raw_mapping_kind, 0);
+
+ let (high, is_expansion) = (raw_mapping_kind >> 3, raw_mapping_kind & 0b100 != 0);
+ if is_expansion {
+ Ok(MappingKind::Expansion(high))
+ } else {
+ match high {
+ 0 => unreachable!("zero kind should have already been handled as a code mapping"),
+ 2 => Ok(MappingKind::Skip),
+ 4 => {
+ let r#true = self.read_simple_term()?;
+ let r#false = self.read_simple_term()?;
+ Ok(MappingKind::Branch { r#true, r#false })
+ }
+ _ => Err(anyhow!("unknown mapping kind: {raw_mapping_kind:#x}")),
+ }
+ }
+ }
+
+ fn read_raw_mapping_region(&mut self) -> anyhow::Result<MappingRegion> {
+ let start_line_offset = self.read_uleb128_u32()?;
+ let start_column = self.read_uleb128_u32()?;
+ let end_line_offset = self.read_uleb128_u32()?;
+ let end_column = self.read_uleb128_u32()?;
+ Ok(MappingRegion { start_line_offset, start_column, end_line_offset, end_column })
+ }
+}
+
+/// Enum that can hold a constant zero value, the ID of an physical coverage
+/// counter, or the ID (and operation) of a coverage-counter expression.
+///
+/// Terms are used as the operands of coverage-counter expressions, as the arms
+/// of branch mappings, and as the value of code/gap mappings.
+#[derive(Clone, Copy, Debug)]
+pub(crate) enum CovTerm {
+ Zero,
+ Counter(u32),
+ Expression(u32, Op),
+}
+
+/// Operator (addition or subtraction) used by an expression.
+#[derive(Clone, Copy, Debug)]
+pub(crate) enum Op {
+ Sub,
+ Add,
+}
+
+impl CovTerm {
+ pub(crate) fn decode(input: u32) -> Option<Self> {
+ let (high, tag) = (input >> 2, input & 0b11);
+ match tag {
+ 0b00 if high == 0 => Some(Self::Zero),
+ 0b01 => Some(Self::Counter(high)),
+ 0b10 => Some(Self::Expression(high, Op::Sub)),
+ 0b11 => Some(Self::Expression(high, Op::Add)),
+ // When reading expression operands or branch arms, the LLVM coverage
+ // mapping reader will always interpret a `0b00` tag as a zero
+ // term, even when the high bits are non-zero.
+ // We treat that case as failure instead, so that this code can be
+ // shared by the full mapping-kind reader as well.
+ _ => None,
+ }
+ }
+}
+
+#[derive(Debug)]
+enum MappingKind {
+ Code(CovTerm),
+ Gap(CovTerm),
+ Expansion(u32),
+ Skip,
+ // Using raw identifiers here makes the dump output a little bit nicer
+ // (via the derived Debug), at the expense of making this tool's source
+ // code a little bit uglier.
+ Branch { r#true: CovTerm, r#false: CovTerm },
+}
+
+struct MappingRegion {
+ /// Offset of this region's start line, relative to the *start line* of
+ /// the *previous mapping* (or 0). Line numbers are 1-based.
+ start_line_offset: u32,
+ /// This region's start column, absolute and 1-based.
+ start_column: u32,
+ /// Offset of this region's end line, relative to the *this mapping's*
+ /// start line. Line numbers are 1-based.
+ end_line_offset: u32,
+ /// This region's end column, absolute, 1-based, and exclusive.
+ ///
+ /// If the highest bit is set, that bit is cleared and the associated
+ /// mapping becomes a gap region mapping.
+ end_column: u32,
+}
+
+impl Debug for MappingRegion {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "(prev + {}, {}) to (start + {}, {})",
+ self.start_line_offset, self.start_column, self.end_line_offset, self.end_column
+ )
+ }
+}
+
+/// Helper type that prints expressions in a "resolved" form, so that
+/// developers reading the dump don't need to resolve expressions by hand.
+struct ExpressionResolver {
+ operands: Vec<(CovTerm, CovTerm)>,
+}
+
+impl ExpressionResolver {
+ fn new() -> Self {
+ Self { operands: Vec::new() }
+ }
+
+ fn push_operands(&mut self, lhs: CovTerm, rhs: CovTerm) {
+ self.operands.push((lhs, rhs));
+ }
+
+ fn format_term(&self, term: CovTerm) -> String {
+ let mut output = String::new();
+ self.write_term(&mut output, term);
+ output
+ }
+
+ fn write_term(&self, output: &mut String, term: CovTerm) {
+ match term {
+ CovTerm::Zero => output.push_str("Zero"),
+ CovTerm::Counter(id) => write!(output, "c{id}").unwrap(),
+ CovTerm::Expression(id, op) => {
+ let (lhs, rhs) = self.operands[id as usize];
+ let op = match op {
+ Op::Sub => "-",
+ Op::Add => "+",
+ };
+
+ output.push('(');
+ self.write_term(output, lhs);
+ write!(output, " {op} ").unwrap();
+ self.write_term(output, rhs);
+ output.push(')');
+ }
+ }
+ }
+}
diff --git a/src/tools/coverage-dump/src/main.rs b/src/tools/coverage-dump/src/main.rs
new file mode 100644
index 000000000..93fed1799
--- /dev/null
+++ b/src/tools/coverage-dump/src/main.rs
@@ -0,0 +1,17 @@
+mod covfun;
+mod parser;
+mod prf_names;
+
+fn main() -> anyhow::Result<()> {
+ use anyhow::Context as _;
+
+ let args = std::env::args().collect::<Vec<_>>();
+
+ let llvm_ir_path = args.get(1).context("LLVM IR file not specified")?;
+ let llvm_ir = std::fs::read_to_string(llvm_ir_path).context("couldn't read LLVM IR file")?;
+
+ let function_names = crate::prf_names::make_function_names_table(&llvm_ir)?;
+ crate::covfun::dump_covfun_mappings(&llvm_ir, &function_names)?;
+
+ Ok(())
+}
diff --git a/src/tools/coverage-dump/src/parser.rs b/src/tools/coverage-dump/src/parser.rs
new file mode 100644
index 000000000..eefac1a4f
--- /dev/null
+++ b/src/tools/coverage-dump/src/parser.rs
@@ -0,0 +1,80 @@
+#[cfg(test)]
+mod tests;
+
+use anyhow::ensure;
+use regex::bytes;
+use std::sync::OnceLock;
+
+/// Given the raw contents of a string literal in LLVM IR assembly, decodes any
+/// backslash escapes and returns a vector containing the resulting byte string.
+pub(crate) fn unescape_llvm_string_contents(contents: &str) -> Vec<u8> {
+ let escape_re = {
+ static RE: OnceLock<bytes::Regex> = OnceLock::new();
+ // LLVM IR supports two string escapes: `\\` and `\xx`.
+ RE.get_or_init(|| bytes::Regex::new(r"\\\\|\\([0-9A-Za-z]{2})").unwrap())
+ };
+
+ fn u8_from_hex_digits(digits: &[u8]) -> u8 {
+ // We know that the input contains exactly 2 hex digits, so these calls
+ // should never fail.
+ assert_eq!(digits.len(), 2);
+ let digits = std::str::from_utf8(digits).unwrap();
+ u8::from_str_radix(digits, 16).unwrap()
+ }
+
+ escape_re
+ .replace_all(contents.as_bytes(), |captures: &bytes::Captures<'_>| {
+ let byte = match captures.get(1) {
+ None => b'\\',
+ Some(hex_digits) => u8_from_hex_digits(hex_digits.as_bytes()),
+ };
+ [byte]
+ })
+ .into_owned()
+}
+
+pub(crate) struct Parser<'a> {
+ rest: &'a [u8],
+}
+
+impl<'a> Parser<'a> {
+ pub(crate) fn new(input: &'a [u8]) -> Self {
+ Self { rest: input }
+ }
+
+ pub(crate) fn ensure_empty(self) -> anyhow::Result<()> {
+ ensure!(self.rest.is_empty(), "unparsed bytes: 0x{:02x?}", self.rest);
+ Ok(())
+ }
+
+ pub(crate) fn read_n_bytes(&mut self, n: usize) -> anyhow::Result<&'a [u8]> {
+ ensure!(n <= self.rest.len());
+
+ let (bytes, rest) = self.rest.split_at(n);
+ self.rest = rest;
+ Ok(bytes)
+ }
+
+ pub(crate) fn read_uleb128_u32(&mut self) -> anyhow::Result<u32> {
+ self.read_uleb128_u64_and_convert()
+ }
+
+ pub(crate) fn read_uleb128_usize(&mut self) -> anyhow::Result<usize> {
+ self.read_uleb128_u64_and_convert()
+ }
+
+ fn read_uleb128_u64_and_convert<T>(&mut self) -> anyhow::Result<T>
+ where
+ T: TryFrom<u64> + 'static,
+ T::Error: std::error::Error + Send + Sync,
+ {
+ let mut temp_rest = self.rest;
+ let raw_value: u64 = leb128::read::unsigned(&mut temp_rest)?;
+ let converted_value = T::try_from(raw_value)?;
+
+ // Only update `self.rest` if the above steps succeeded, so that the
+ // parser position can be used for error reporting if desired.
+ self.rest = temp_rest;
+ Ok(converted_value)
+ }
+}
diff --git a/src/tools/coverage-dump/src/parser/tests.rs b/src/tools/coverage-dump/src/parser/tests.rs
new file mode 100644
index 000000000..a673606b9
--- /dev/null
+++ b/src/tools/coverage-dump/src/parser/tests.rs
@@ -0,0 +1,38 @@
+use super::unescape_llvm_string_contents;
+
+// WARNING: These tests don't necessarily run in CI, and were mainly used to
+// help track down problems when originally developing this tool.
+// (The tool is still tested indirectly by snapshot tests that rely on it.)
+
+// Tests for `unescape_llvm_string_contents`:
+
+#[test]
+fn unescape_empty() {
+ assert_eq!(unescape_llvm_string_contents(""), &[]);
+}
+
+#[test]
+fn unescape_noop() {
+ let input = "The quick brown fox jumps over the lazy dog.";
+ assert_eq!(unescape_llvm_string_contents(input), input.as_bytes());
+}
+
+#[test]
+fn unescape_backslash() {
+ let input = r"\\Hello\\world\\";
+ assert_eq!(unescape_llvm_string_contents(input), r"\Hello\world\".as_bytes());
+}
+
+#[test]
+fn unescape_hex() {
+ let input = r"\01\02\03\04\0a\0b\0C\0D\fd\fE\FF";
+ let expected: &[u8] = &[0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d, 0xfd, 0xfe, 0xff];
+ assert_eq!(unescape_llvm_string_contents(input), expected);
+}
+
+#[test]
+fn unescape_mixed() {
+ let input = r"\\01.\5c\5c";
+ let expected: &[u8] = br"\01.\\";
+ assert_eq!(unescape_llvm_string_contents(input), expected);
+}
diff --git a/src/tools/coverage-dump/src/prf_names.rs b/src/tools/coverage-dump/src/prf_names.rs
new file mode 100644
index 000000000..d3f7b819e
--- /dev/null
+++ b/src/tools/coverage-dump/src/prf_names.rs
@@ -0,0 +1,87 @@
+use crate::parser::{unescape_llvm_string_contents, Parser};
+use anyhow::{anyhow, ensure};
+use regex::Regex;
+use std::collections::HashMap;
+use std::sync::OnceLock;
+
+/// Scans through the contents of an LLVM IR assembly file to find `__llvm_prf_names`
+/// entries, decodes them, and creates a table that maps name hash values to
+/// (demangled) function names.
+pub(crate) fn make_function_names_table(llvm_ir: &str) -> anyhow::Result<HashMap<u64, String>> {
+ fn prf_names_payload(line: &str) -> Option<&str> {
+ let re = {
+ // We cheat a little bit and match the variable name `@__llvm_prf_nm`
+ // rather than the section name, because the section name is harder
+ // to extract and differs across Linux/Windows/macOS.
+ static RE: OnceLock<Regex> = OnceLock::new();
+ RE.get_or_init(|| {
+ Regex::new(r#"^@__llvm_prf_nm =.*\[[0-9]+ x i8\] c"([^"]*)".*$"#).unwrap()
+ })
+ };
+
+ let payload = re.captures(line)?.get(1).unwrap().as_str();
+ Some(payload)
+ }
+
+ /// LLVM's profiler/coverage metadata often uses an MD5 hash truncated to
+ /// 64 bits as a way to associate data stored in different tables/sections.
+ fn truncated_md5(bytes: &[u8]) -> u64 {
+ use md5::{Digest, Md5};
+ let mut hasher = Md5::new();
+ hasher.update(bytes);
+ let hash: [u8; 8] = hasher.finalize().as_slice()[..8].try_into().unwrap();
+ // The truncated hash is explicitly little-endian, regardless of host
+ // or target platform. (See `MD5Result::low` in LLVM's `MD5.h`.)
+ u64::from_le_bytes(hash)
+ }
+
+ fn demangle_if_able(symbol_name_bytes: &[u8]) -> anyhow::Result<String> {
+ // In practice, raw symbol names should always be ASCII.
+ let symbol_name_str = std::str::from_utf8(symbol_name_bytes)?;
+ match rustc_demangle::try_demangle(symbol_name_str) {
+ Ok(d) => Ok(format!("{d:#}")),
+ // If demangling failed, don't treat it as an error. This lets us
+ // run the dump tool against non-Rust coverage maps produced by
+ // `clang`, for testing purposes.
+ Err(_) => Ok(format!("(couldn't demangle) {symbol_name_str}")),
+ }
+ }
+
+ let mut map = HashMap::new();
+
+ for payload in llvm_ir.lines().filter_map(prf_names_payload).map(unescape_llvm_string_contents)
+ {
+ let mut parser = Parser::new(&payload);
+ let uncompressed_len = parser.read_uleb128_usize()?;
+ let compressed_len = parser.read_uleb128_usize()?;
+
+ let uncompressed_bytes_vec;
+ let uncompressed_bytes: &[u8] = if compressed_len == 0 {
+ // The symbol name bytes are uncompressed, so read them directly.
+ parser.read_n_bytes(uncompressed_len)?
+ } else {
+ // The symbol name bytes are compressed, so read and decompress them.
+ let compressed_bytes = parser.read_n_bytes(compressed_len)?;
+
+ uncompressed_bytes_vec = miniz_oxide::inflate::decompress_to_vec_zlib_with_limit(
+ compressed_bytes,
+ uncompressed_len,
+ )
+ .map_err(|e| anyhow!("{e:?}"))?;
+ ensure!(uncompressed_bytes_vec.len() == uncompressed_len);
+
+ &uncompressed_bytes_vec
+ };
+
+ // Symbol names in the payload are separated by `0x01` bytes.
+ for raw_name in uncompressed_bytes.split(|&b| b == 0x01) {
+ let hash = truncated_md5(raw_name);
+ let demangled = demangle_if_able(raw_name)?;
+ map.insert(hash, demangled);
+ }
+
+ parser.ensure_empty()?;
+ }
+
+ Ok(map)
+}
diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml
index 23e88844b..9821677a1 100644
--- a/src/tools/generate-windows-sys/Cargo.toml
+++ b/src/tools/generate-windows-sys/Cargo.toml
@@ -4,4 +4,4 @@ version = "0.1.0"
edition = "2021"
[dependencies.windows-bindgen]
-version = "0.49"
+version = "0.51.1"
diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs
index 91d981462..dff2c5e46 100644
--- a/src/tools/generate-windows-sys/src/main.rs
+++ b/src/tools/generate-windows-sys/src/main.rs
@@ -1,5 +1,7 @@
+use std::env;
+use std::error::Error;
use std::fs;
-use std::io::{self, Write};
+use std::io::{self, Read, Seek, Write};
use std::path::PathBuf;
/// This is printed to the file before the rest of the contents.
@@ -11,25 +13,20 @@ const PRELUDE: &str = r#"// This file is autogenerated.
// ignore-tidy-filelength
"#;
-fn main() -> io::Result<()> {
+fn main() -> Result<(), Box<dyn Error>> {
let mut path: PathBuf =
- std::env::args_os().nth(1).expect("a path to the rust repository is required").into();
- path.push("library/std/src/sys/windows/c/windows_sys.lst");
+ env::args_os().nth(1).expect("a path to the rust repository is required").into();
+ path.push("library/std/src/sys/windows/c");
+ env::set_current_dir(&path)?;
- // Load the list of APIs
- let buffer = fs::read_to_string(&path)?;
- let names: Vec<&str> = buffer
- .lines()
- .filter_map(|line| {
- let line = line.trim();
- if line.is_empty() || line.starts_with("//") { None } else { Some(line) }
- })
- .collect();
+ let info = windows_bindgen::bindgen(["--etc", "windows_sys.lst"])?;
+ println!("{info}");
- // Write the bindings to windows-sys.rs
- let bindings = windows_bindgen::standalone_std(&names);
- path.set_extension("rs");
- let mut f = std::fs::File::create(&path)?;
+ // add some gunk to the output file.
+ let mut f = fs::File::options().read(true).write(true).open("windows_sys.rs")?;
+ let mut bindings = String::new();
+ f.read_to_string(&mut bindings)?;
+ f.seek(io::SeekFrom::Start(0))?;
f.write_all(PRELUDE.as_bytes())?;
f.write_all(bindings.as_bytes())?;
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index 45a9c93ee..9bd04e11c 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -12,7 +12,7 @@ pub(crate) enum Kind {
Enum,
Variant,
Function,
- Typedef,
+ TypeAlias,
OpaqueTy,
Constant,
Trait,
@@ -45,7 +45,7 @@ impl Kind {
Trait => true,
TraitAlias => true,
Impl => true,
- Typedef => true,
+ TypeAlias => true,
Constant => true,
Static => true,
Macro => true,
@@ -98,7 +98,7 @@ impl Kind {
Kind::Union => false,
Kind::Enum => false,
Kind::Variant => false,
- Kind::Typedef => false,
+ Kind::TypeAlias => false,
Kind::OpaqueTy => false,
Kind::Constant => false,
Kind::Trait => false,
@@ -131,7 +131,7 @@ impl Kind {
matches!(self, Kind::Trait | Kind::TraitAlias)
}
pub fn is_type(self) -> bool {
- matches!(self, Kind::Struct | Kind::Enum | Kind::Union | Kind::Typedef)
+ matches!(self, Kind::Struct | Kind::Enum | Kind::Union | Kind::TypeAlias)
}
pub fn from_item(i: &Item) -> Self {
@@ -148,7 +148,7 @@ impl Kind {
ItemEnum::Trait(_) => Trait,
ItemEnum::TraitAlias(_) => TraitAlias,
ItemEnum::Impl(_) => Impl,
- ItemEnum::Typedef(_) => Typedef,
+ ItemEnum::TypeAlias(_) => TypeAlias,
ItemEnum::OpaqueTy(_) => OpaqueTy,
ItemEnum::Constant(_) => Constant,
ItemEnum::Static(_) => Static,
@@ -186,7 +186,7 @@ impl Kind {
ItemKind::StructField => StructField,
ItemKind::Trait => Trait,
ItemKind::TraitAlias => TraitAlias,
- ItemKind::Typedef => Typedef,
+ ItemKind::TypeAlias => TypeAlias,
ItemKind::Union => Union,
ItemKind::Variant => Variant,
}
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index bf8a64acf..592e97310 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -5,7 +5,7 @@ use rustdoc_json_types::{
Constant, Crate, DynTrait, Enum, FnDecl, Function, FunctionPointer, GenericArg, GenericArgs,
GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, ItemSummary, Module,
OpaqueTy, Path, Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias,
- Type, TypeBinding, TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate,
+ Type, TypeAlias, TypeBinding, TypeBindingKind, Union, Variant, VariantKind, WherePredicate,
};
use serde_json::Value;
@@ -37,7 +37,7 @@ pub struct Validator<'a> {
enum PathKind {
Trait,
- /// Structs, Enums, Unions and Typedefs.
+ /// Structs, Enums, Unions and TypeAliases.
///
/// This doesn't include trait's because traits are not types.
Type,
@@ -99,7 +99,7 @@ impl<'a> Validator<'a> {
ItemEnum::Trait(x) => self.check_trait(x, id),
ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
ItemEnum::Impl(x) => self.check_impl(x, id),
- ItemEnum::Typedef(x) => self.check_typedef(x),
+ ItemEnum::TypeAlias(x) => self.check_type_alias(x),
ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
ItemEnum::Constant(x) => self.check_constant(x),
ItemEnum::Static(x) => self.check_static(x),
@@ -221,7 +221,7 @@ impl<'a> Validator<'a> {
}
}
- fn check_typedef(&mut self, x: &'a Typedef) {
+ fn check_type_alias(&mut self, x: &'a TypeAlias) {
self.check_generics(&x.generics);
self.check_type(&x.type_);
}
@@ -450,7 +450,7 @@ impl<'a> Validator<'a> {
}
fn add_type_id(&mut self, id: &'a Id) {
- self.add_id_checked(id, Kind::is_type, "Type (Struct, Enum, Union or Typedef)");
+ self.add_id_checked(id, Kind::is_type, "Type (Struct, Enum, Union or TypeAlias)");
}
/// Add an Id that appeared in a trait
diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml
index 3f7dba81c..f1c3dd6aa 100644
--- a/src/tools/opt-dist/Cargo.toml
+++ b/src/tools/opt-dist/Cargo.toml
@@ -21,3 +21,5 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
glob = "0.3"
tempfile = "3.5"
+derive_builder = "0.12"
+clap = { version = "4", features = ["derive"] }
diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs
new file mode 100644
index 000000000..ff782a168
--- /dev/null
+++ b/src/tools/opt-dist/src/environment.rs
@@ -0,0 +1,108 @@
+use camino::Utf8PathBuf;
+use derive_builder::Builder;
+
+#[derive(Builder)]
+pub struct Environment {
+ host_triple: String,
+ python_binary: String,
+ /// The rustc checkout, where the compiler source is located.
+ checkout_dir: Utf8PathBuf,
+ /// The main directory where the build occurs. Stage0 rustc and cargo have to be available in
+ /// this directory before `opt-dist` is started.
+ build_dir: Utf8PathBuf,
+ /// Directory where the optimization artifacts (PGO/BOLT profiles, etc.)
+ /// will be stored.
+ artifact_dir: Utf8PathBuf,
+ /// Path to the host LLVM used to compile LLVM in `src/llvm-project`.
+ host_llvm_dir: Utf8PathBuf,
+ /// List of test paths that should be skipped when testing the optimized artifacts.
+ skipped_tests: Vec<String>,
+ /// Directory containing a pre-built rustc-perf checkout.
+ #[builder(default)]
+ prebuilt_rustc_perf: Option<Utf8PathBuf>,
+ use_bolt: bool,
+ shared_llvm: bool,
+}
+
+impl Environment {
+ pub fn host_triple(&self) -> &str {
+ &self.host_triple
+ }
+
+ pub fn python_binary(&self) -> &str {
+ &self.python_binary
+ }
+
+ pub fn checkout_path(&self) -> Utf8PathBuf {
+ self.checkout_dir.clone()
+ }
+
+ pub fn build_root(&self) -> Utf8PathBuf {
+ self.build_dir.clone()
+ }
+
+ pub fn build_artifacts(&self) -> Utf8PathBuf {
+ self.build_root().join("build").join(&self.host_triple)
+ }
+
+ pub fn artifact_dir(&self) -> Utf8PathBuf {
+ self.artifact_dir.clone()
+ }
+
+ pub fn cargo_stage_0(&self) -> Utf8PathBuf {
+ self.build_artifacts()
+ .join("stage0")
+ .join("bin")
+ .join(format!("cargo{}", executable_extension()))
+ }
+
+ pub fn rustc_stage_0(&self) -> Utf8PathBuf {
+ self.build_artifacts()
+ .join("stage0")
+ .join("bin")
+ .join(format!("rustc{}", executable_extension()))
+ }
+
+ pub fn rustc_stage_2(&self) -> Utf8PathBuf {
+ self.build_artifacts()
+ .join("stage2")
+ .join("bin")
+ .join(format!("rustc{}", executable_extension()))
+ }
+
+ pub fn prebuilt_rustc_perf(&self) -> Option<Utf8PathBuf> {
+ self.prebuilt_rustc_perf.clone()
+ }
+
+ /// Path to the built rustc-perf benchmark suite.
+ pub fn rustc_perf_dir(&self) -> Utf8PathBuf {
+ self.artifact_dir.join("rustc-perf")
+ }
+
+ pub fn host_llvm_dir(&self) -> Utf8PathBuf {
+ self.host_llvm_dir.clone()
+ }
+
+ pub fn use_bolt(&self) -> bool {
+ self.use_bolt
+ }
+
+ pub fn supports_shared_llvm(&self) -> bool {
+ self.shared_llvm
+ }
+
+ pub fn skipped_tests(&self) -> &[String] {
+ &self.skipped_tests
+ }
+}
+
+/// What is the extension of binary executables on this platform?
+#[cfg(target_family = "unix")]
+pub fn executable_extension() -> &'static str {
+ ""
+}
+
+#[cfg(target_family = "windows")]
+pub fn executable_extension() -> &'static str {
+ ".exe"
+}
diff --git a/src/tools/opt-dist/src/environment/linux.rs b/src/tools/opt-dist/src/environment/linux.rs
deleted file mode 100644
index 58b7e6d23..000000000
--- a/src/tools/opt-dist/src/environment/linux.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-use crate::environment::Environment;
-use crate::exec::cmd;
-use crate::utils::io::copy_directory;
-use camino::{Utf8Path, Utf8PathBuf};
-
-pub(super) struct LinuxEnvironment;
-
-impl Environment for LinuxEnvironment {
- fn python_binary(&self) -> &'static str {
- "python3"
- }
-
- fn checkout_path(&self) -> Utf8PathBuf {
- Utf8PathBuf::from("/checkout")
- }
-
- fn host_llvm_dir(&self) -> Utf8PathBuf {
- Utf8PathBuf::from("/rustroot")
- }
-
- fn opt_artifacts(&self) -> Utf8PathBuf {
- Utf8PathBuf::from("/tmp/tmp-multistage/opt-artifacts")
- }
-
- fn build_root(&self) -> Utf8PathBuf {
- self.checkout_path().join("obj")
- }
-
- fn prepare_rustc_perf(&self) -> anyhow::Result<()> {
- // /tmp/rustc-perf comes from the x64 dist Dockerfile
- copy_directory(Utf8Path::new("/tmp/rustc-perf"), &self.rustc_perf_dir())?;
- cmd(&[self.cargo_stage_0().as_str(), "build", "-p", "collector"])
- .workdir(&self.rustc_perf_dir())
- .env("RUSTC", &self.rustc_stage_0().into_string())
- .env("RUSTC_BOOTSTRAP", "1")
- .run()?;
- Ok(())
- }
-
- fn supports_bolt(&self) -> bool {
- true
- }
-
- fn supports_shared_llvm(&self) -> bool {
- true
- }
-
- fn executable_extension(&self) -> &'static str {
- ""
- }
-
- fn skipped_tests(&self) -> &'static [&'static str] {
- &[
- // Fails because of linker errors, as of June 2023.
- "tests/ui/process/nofile-limit.rs",
- ]
- }
-}
diff --git a/src/tools/opt-dist/src/environment/mod.rs b/src/tools/opt-dist/src/environment/mod.rs
deleted file mode 100644
index a8650fad0..000000000
--- a/src/tools/opt-dist/src/environment/mod.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use camino::Utf8PathBuf;
-
-#[cfg(target_family = "unix")]
-mod linux;
-#[cfg(target_family = "windows")]
-mod windows;
-
-pub trait Environment {
- fn host_triple(&self) -> String {
- std::env::var("PGO_HOST").expect("PGO_HOST environment variable missing")
- }
-
- fn python_binary(&self) -> &'static str;
-
- /// The rustc checkout, where the compiler source is located.
- fn checkout_path(&self) -> Utf8PathBuf;
-
- /// Path to the host LLVM used to compile LLVM in `src/llvm-project`.
- fn host_llvm_dir(&self) -> Utf8PathBuf;
-
- /// Directory where the optimization artifacts (PGO/BOLT profiles, etc.)
- /// will be stored.
- fn opt_artifacts(&self) -> Utf8PathBuf;
-
- /// The main directory where the build occurs.
- fn build_root(&self) -> Utf8PathBuf;
-
- fn build_artifacts(&self) -> Utf8PathBuf {
- self.build_root().join("build").join(self.host_triple())
- }
-
- fn cargo_stage_0(&self) -> Utf8PathBuf {
- self.build_artifacts()
- .join("stage0")
- .join("bin")
- .join(format!("cargo{}", self.executable_extension()))
- }
-
- fn rustc_stage_0(&self) -> Utf8PathBuf {
- self.build_artifacts()
- .join("stage0")
- .join("bin")
- .join(format!("rustc{}", self.executable_extension()))
- }
-
- fn rustc_stage_2(&self) -> Utf8PathBuf {
- self.build_artifacts()
- .join("stage2")
- .join("bin")
- .join(format!("rustc{}", self.executable_extension()))
- }
-
- /// Path to the built rustc-perf benchmark suite.
- fn rustc_perf_dir(&self) -> Utf8PathBuf {
- self.opt_artifacts().join("rustc-perf")
- }
-
- /// Download and/or compile rustc-perf.
- fn prepare_rustc_perf(&self) -> anyhow::Result<()>;
-
- fn supports_bolt(&self) -> bool;
-
- fn supports_shared_llvm(&self) -> bool;
-
- /// What is the extension of binary executables in this environment?
- fn executable_extension(&self) -> &'static str;
-
- /// List of test paths that should be skipped when testing the optimized artifacts.
- fn skipped_tests(&self) -> &'static [&'static str];
-}
-
-pub fn create_environment() -> Box<dyn Environment> {
- #[cfg(target_family = "unix")]
- return Box::new(linux::LinuxEnvironment);
- #[cfg(target_family = "windows")]
- return Box::new(windows::WindowsEnvironment::new());
-}
diff --git a/src/tools/opt-dist/src/environment/windows.rs b/src/tools/opt-dist/src/environment/windows.rs
deleted file mode 100644
index 8a9733d64..000000000
--- a/src/tools/opt-dist/src/environment/windows.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-use crate::environment::Environment;
-use crate::exec::cmd;
-use crate::utils::io::move_directory;
-use camino::Utf8PathBuf;
-use std::io::Cursor;
-use zip::ZipArchive;
-
-pub(super) struct WindowsEnvironment {
- checkout_dir: Utf8PathBuf,
-}
-
-impl WindowsEnvironment {
- pub fn new() -> Self {
- Self { checkout_dir: std::env::current_dir().unwrap().try_into().unwrap() }
- }
-}
-
-impl Environment for WindowsEnvironment {
- fn python_binary(&self) -> &'static str {
- "python"
- }
-
- fn checkout_path(&self) -> Utf8PathBuf {
- self.checkout_dir.clone()
- }
-
- fn host_llvm_dir(&self) -> Utf8PathBuf {
- self.checkout_path().join("citools").join("clang-rust")
- }
-
- fn opt_artifacts(&self) -> Utf8PathBuf {
- self.checkout_path().join("opt-artifacts")
- }
-
- fn build_root(&self) -> Utf8PathBuf {
- self.checkout_path()
- }
-
- fn prepare_rustc_perf(&self) -> anyhow::Result<()> {
- // FIXME: add some mechanism for synchronization of this commit SHA with
- // Linux (which builds rustc-perf in a Dockerfile)
- // rustc-perf version from 2023-05-30
- const PERF_COMMIT: &str = "8b2ac3042e1ff2c0074455a0a3618adef97156b1";
-
- let url = format!("https://github.com/rust-lang/rustc-perf/archive/{PERF_COMMIT}.zip");
- let response = reqwest::blocking::get(url)?.error_for_status()?.bytes()?.to_vec();
-
- let mut archive = ZipArchive::new(Cursor::new(response))?;
- archive.extract(self.rustc_perf_dir())?;
- move_directory(
- &self.rustc_perf_dir().join(format!("rustc-perf-{PERF_COMMIT}")),
- &self.rustc_perf_dir(),
- )?;
-
- cmd(&[self.cargo_stage_0().as_str(), "build", "-p", "collector"])
- .workdir(&self.rustc_perf_dir())
- .env("RUSTC", &self.rustc_stage_0().into_string())
- .env("RUSTC_BOOTSTRAP", "1")
- .run()?;
-
- Ok(())
- }
-
- fn supports_bolt(&self) -> bool {
- false
- }
-
- fn supports_shared_llvm(&self) -> bool {
- false
- }
-
- fn executable_extension(&self) -> &'static str {
- ".exe"
- }
-
- fn skipped_tests(&self) -> &'static [&'static str] {
- &[
- // Fails as of June 2023.
- "tests\\codegen\\vec-shrink-panik.rs",
- ]
- }
-}
diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs
index 4765dceb5..04e018452 100644
--- a/src/tools/opt-dist/src/exec.rs
+++ b/src/tools/opt-dist/src/exec.rs
@@ -96,7 +96,7 @@ pub struct Bootstrap {
}
impl Bootstrap {
- pub fn build(env: &dyn Environment) -> Self {
+ pub fn build(env: &Environment) -> Self {
let metrics_path = env.build_root().join("build").join("metrics.json");
let cmd = cmd(&[
env.python_binary(),
@@ -114,7 +114,7 @@ impl Bootstrap {
Self { cmd, metrics_path }
}
- pub fn dist(env: &dyn Environment, dist_args: &[String]) -> Self {
+ pub fn dist(env: &Environment, dist_args: &[String]) -> Self {
let metrics_path = env.build_root().join("build").join("metrics.json");
let cmd = cmd(&dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>())
.env("RUST_BACKTRACE", "full");
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index 8ab19674d..978e2dfa4 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -1,17 +1,22 @@
use crate::bolt::{bolt_optimize, with_bolt_instrumented};
use anyhow::Context;
+use camino::{Utf8Path, Utf8PathBuf};
+use clap::Parser;
use log::LevelFilter;
+use std::io::Cursor;
+use std::time::Duration;
use utils::io;
+use zip::ZipArchive;
-use crate::environment::{create_environment, Environment};
-use crate::exec::Bootstrap;
+use crate::environment::{Environment, EnvironmentBuilder};
+use crate::exec::{cmd, Bootstrap};
use crate::tests::run_tests;
use crate::timer::Timer;
use crate::training::{gather_llvm_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles};
-use crate::utils::io::reset_directory;
+use crate::utils::io::{copy_directory, move_directory, reset_directory};
use crate::utils::{
clear_llvm_files, format_env_variables, print_binary_sizes, print_free_disk_space,
- with_log_group,
+ retry_action, with_log_group,
};
mod bolt;
@@ -23,24 +28,169 @@ mod timer;
mod training;
mod utils;
+#[derive(clap::Parser, Debug)]
+struct Args {
+ #[clap(subcommand)]
+ env: EnvironmentCmd,
+}
+
+#[derive(clap::Parser, Clone, Debug)]
+struct SharedArgs {
+ // Arguments passed to `x` to perform the final (dist) build.
+ build_args: Vec<String>,
+}
+
+#[derive(clap::Parser, Clone, Debug)]
+enum EnvironmentCmd {
+ /// Perform a custom local PGO/BOLT optimized build.
+ Local {
+ /// Target triple of the host.
+ #[arg(long)]
+ target_triple: String,
+
+ /// Checkout directory of `rustc`.
+ #[arg(long)]
+ checkout_dir: Utf8PathBuf,
+
+ /// Host LLVM installation directory.
+ #[arg(long)]
+ llvm_dir: Utf8PathBuf,
+
+ /// Python binary to use in bootstrap invocations.
+ #[arg(long, default_value = "python3")]
+ python: String,
+
+ /// Directory where artifacts (like PGO profiles or rustc-perf) of this workflow
+ /// will be stored.
+ #[arg(long, default_value = "opt-artifacts")]
+ artifact_dir: Utf8PathBuf,
+
+ /// Is LLVM for `rustc` built in shared library mode?
+ #[arg(long, default_value_t = true)]
+ llvm_shared: bool,
+
+ /// Should BOLT optimization be used? If yes, host LLVM must have BOLT binaries
+ /// (`llvm-bolt` and `merge-fdata`) available.
+ #[arg(long, default_value_t = false)]
+ use_bolt: bool,
+
+ /// Tests that should be skipped when testing the optimized compiler.
+ #[arg(long)]
+ skipped_tests: Vec<String>,
+
+ #[clap(flatten)]
+ shared: SharedArgs,
+ },
+ /// Perform an optimized build on Linux CI, from inside Docker.
+ LinuxCi {
+ #[clap(flatten)]
+ shared: SharedArgs,
+ },
+ /// Perform an optimized build on Windows CI, directly inside Github Actions.
+ WindowsCi {
+ #[clap(flatten)]
+ shared: SharedArgs,
+ },
+}
+
fn is_try_build() -> bool {
std::env::var("DIST_TRY_BUILD").unwrap_or_else(|_| "0".to_string()) != "0"
}
+fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)> {
+ let (env, args) = match args.env {
+ EnvironmentCmd::Local {
+ target_triple,
+ checkout_dir,
+ llvm_dir,
+ python,
+ artifact_dir,
+ llvm_shared,
+ use_bolt,
+ skipped_tests,
+ shared,
+ } => {
+ let env = EnvironmentBuilder::default()
+ .host_triple(target_triple)
+ .python_binary(python)
+ .checkout_dir(checkout_dir.clone())
+ .host_llvm_dir(llvm_dir)
+ .artifact_dir(artifact_dir)
+ .build_dir(checkout_dir)
+ .shared_llvm(llvm_shared)
+ .use_bolt(use_bolt)
+ .skipped_tests(skipped_tests)
+ .build()?;
+
+ (env, shared.build_args)
+ }
+ EnvironmentCmd::LinuxCi { shared } => {
+ let target_triple =
+ std::env::var("PGO_HOST").expect("PGO_HOST environment variable missing");
+
+ let checkout_dir = Utf8PathBuf::from("/checkout");
+ let env = EnvironmentBuilder::default()
+ .host_triple(target_triple)
+ .python_binary("python3".to_string())
+ .checkout_dir(checkout_dir.clone())
+ .host_llvm_dir(Utf8PathBuf::from("/rustroot"))
+ .artifact_dir(Utf8PathBuf::from("/tmp/tmp-multistage/opt-artifacts"))
+ .build_dir(checkout_dir.join("obj"))
+ // /tmp/rustc-perf comes from the x64 dist Dockerfile
+ .prebuilt_rustc_perf(Some(Utf8PathBuf::from("/tmp/rustc-perf")))
+ .shared_llvm(true)
+ .use_bolt(true)
+ .skipped_tests(vec![
+ // Fails because of linker errors, as of June 2023.
+ "tests/ui/process/nofile-limit.rs".to_string(),
+ ])
+ .build()?;
+
+ (env, shared.build_args)
+ }
+ EnvironmentCmd::WindowsCi { shared } => {
+ let target_triple =
+ std::env::var("PGO_HOST").expect("PGO_HOST environment variable missing");
+
+ let checkout_dir: Utf8PathBuf = std::env::current_dir()?.try_into()?;
+ let env = EnvironmentBuilder::default()
+ .host_triple(target_triple)
+ .python_binary("python".to_string())
+ .checkout_dir(checkout_dir.clone())
+ .host_llvm_dir(checkout_dir.join("citools").join("clang-rust"))
+ .artifact_dir(checkout_dir.join("opt-artifacts"))
+ .build_dir(checkout_dir)
+ .shared_llvm(false)
+ .use_bolt(false)
+ .skipped_tests(vec![
+ // Fails as of June 2023.
+ "tests\\codegen\\vec-shrink-panik.rs".to_string(),
+ ])
+ .build()?;
+
+ (env, shared.build_args)
+ }
+ };
+ Ok((env, args))
+}
+
fn execute_pipeline(
- env: &dyn Environment,
+ env: &Environment,
timer: &mut Timer,
dist_args: Vec<String>,
) -> anyhow::Result<()> {
- reset_directory(&env.opt_artifacts())?;
+ reset_directory(&env.artifact_dir())?;
- with_log_group("Building rustc-perf", || env.prepare_rustc_perf())?;
+ with_log_group("Building rustc-perf", || match env.prebuilt_rustc_perf() {
+ Some(dir) => copy_rustc_perf(env, &dir),
+ None => download_rustc_perf(env),
+ })?;
// Stage 1: Build PGO instrumented rustc
// We use a normal build of LLVM, because gathering PGO profiles for LLVM and `rustc` at the
// same time can cause issues, because the host and in-tree LLVM versions can diverge.
let rustc_pgo_profile = timer.section("Stage 1 (Rustc PGO)", |stage| {
- let rustc_profile_dir_root = env.opt_artifacts().join("rustc-pgo");
+ let rustc_profile_dir_root = env.artifact_dir().join("rustc-pgo");
stage.section("Build PGO instrumented rustc and LLVM", |section| {
let mut builder = Bootstrap::build(env).rustc_pgo_instrument(&rustc_profile_dir_root);
@@ -74,7 +224,7 @@ fn execute_pipeline(
// Remove the previous, uninstrumented build of LLVM.
clear_llvm_files(env)?;
- let llvm_profile_dir_root = env.opt_artifacts().join("llvm-pgo");
+ let llvm_profile_dir_root = env.artifact_dir().join("llvm-pgo");
stage.section("Build PGO instrumented LLVM", |section| {
Bootstrap::build(env)
@@ -95,7 +245,7 @@ fn execute_pipeline(
Ok(profile)
})?;
- let llvm_bolt_profile = if env.supports_bolt() {
+ let llvm_bolt_profile = if env.use_bolt() {
// Stage 3: Build BOLT instrumented LLVM
// We build a PGO optimized LLVM in this step, then instrument it with BOLT and gather BOLT profiles.
// Note that we don't remove LLVM artifacts after this step, so that they are reused in the final dist build.
@@ -171,8 +321,9 @@ fn main() -> anyhow::Result<()> {
.parse_default_env()
.init();
- let mut build_args: Vec<String> = std::env::args().skip(1).collect();
- println!("Running optimized build pipeline with args `{}`", build_args.join(" "));
+ let args = Args::parse();
+
+ println!("Running optimized build pipeline with args `{:?}`", args);
with_log_group("Environment values", || {
println!("Environment values\n{}", format_env_variables());
@@ -184,6 +335,8 @@ fn main() -> anyhow::Result<()> {
}
});
+ let (env, mut build_args) = create_environment(args).context("Cannot create environment")?;
+
// Skip components that are not needed for try builds to speed them up
if is_try_build() {
log::info!("Skipping building of unimportant components for a try build");
@@ -202,14 +355,58 @@ fn main() -> anyhow::Result<()> {
}
let mut timer = Timer::new();
- let env = create_environment();
- let result = execute_pipeline(env.as_ref(), &mut timer, build_args);
+ let result = execute_pipeline(&env, &mut timer, build_args);
log::info!("Timer results\n{}", timer.format_stats());
print_free_disk_space()?;
result.context("Optimized build pipeline has failed")?;
- print_binary_sizes(env.as_ref())?;
+ print_binary_sizes(&env)?;
+
+ Ok(())
+}
+
+// Copy rustc-perf from the given path into the environment and build it.
+fn copy_rustc_perf(env: &Environment, dir: &Utf8Path) -> anyhow::Result<()> {
+ copy_directory(dir, &env.rustc_perf_dir())?;
+ build_rustc_perf(env)
+}
+
+// Download and build rustc-perf into the given environment.
+fn download_rustc_perf(env: &Environment) -> anyhow::Result<()> {
+ reset_directory(&env.rustc_perf_dir())?;
+
+ // FIXME: add some mechanism for synchronization of this commit SHA with
+ // Linux (which builds rustc-perf in a Dockerfile)
+ // rustc-perf version from 2023-05-30
+ const PERF_COMMIT: &str = "8b2ac3042e1ff2c0074455a0a3618adef97156b1";
+
+ let url = format!("https://ci-mirrors.rust-lang.org/rustc/rustc-perf-{PERF_COMMIT}.zip");
+ let client = reqwest::blocking::Client::builder()
+ .timeout(Duration::from_secs(60 * 2))
+ .connect_timeout(Duration::from_secs(60 * 2))
+ .build()?;
+ let response = retry_action(
+ || Ok(client.get(&url).send()?.error_for_status()?.bytes()?.to_vec()),
+ "Download rustc-perf archive",
+ 5,
+ )?;
+
+ let mut archive = ZipArchive::new(Cursor::new(response))?;
+ archive.extract(env.rustc_perf_dir())?;
+ move_directory(
+ &env.rustc_perf_dir().join(format!("rustc-perf-{PERF_COMMIT}")),
+ &env.rustc_perf_dir(),
+ )?;
+
+ build_rustc_perf(env)
+}
+fn build_rustc_perf(env: &Environment) -> anyhow::Result<()> {
+ cmd(&[env.cargo_stage_0().as_str(), "build", "-p", "collector"])
+ .workdir(&env.rustc_perf_dir())
+ .env("RUSTC", &env.rustc_stage_0().into_string())
+ .env("RUSTC_BOOTSTRAP", "1")
+ .run()?;
Ok(())
}
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 3dd1a3223..31aabca09 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -1,11 +1,11 @@
-use crate::environment::Environment;
+use crate::environment::{executable_extension, Environment};
use crate::exec::cmd;
use crate::utils::io::{copy_directory, find_file_in_dir, unpack_archive};
use anyhow::Context;
use camino::{Utf8Path, Utf8PathBuf};
/// Run tests on optimized dist artifacts.
-pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> {
+pub fn run_tests(env: &Environment) -> anyhow::Result<()> {
// After `dist` is executed, we extract its archived components into a sysroot directory,
// and then use that extracted rustc as a stage0 compiler.
// Then we run a subset of tests using that compiler, to have a basic smoke test which checks
@@ -33,8 +33,8 @@ pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> {
// We need to manually copy libstd to the extracted rustc sysroot
copy_directory(
- &libstd_dir.join("lib").join("rustlib").join(&host_triple).join("lib"),
- &rustc_dir.join("lib").join("rustlib").join(&host_triple).join("lib"),
+ &libstd_dir.join("lib").join("rustlib").join(host_triple).join("lib"),
+ &rustc_dir.join("lib").join("rustlib").join(host_triple).join("lib"),
)?;
// Extract sources - they aren't in the `rustc-nightly-{host}` tarball, so we need to manually copy libstd
@@ -45,9 +45,9 @@ pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> {
&rustc_dir.join("lib").join("rustlib").join("src"),
)?;
- let rustc_path = rustc_dir.join("bin").join(format!("rustc{}", env.executable_extension()));
+ let rustc_path = rustc_dir.join("bin").join(format!("rustc{}", executable_extension()));
assert!(rustc_path.is_file());
- let cargo_path = cargo_dir.join("bin").join(format!("cargo{}", env.executable_extension()));
+ let cargo_path = cargo_dir.join("bin").join(format!("cargo{}", executable_extension()));
assert!(cargo_path.is_file());
// Specify path to a LLVM config so that LLVM is not rebuilt.
@@ -56,7 +56,7 @@ pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> {
.build_artifacts()
.join("llvm")
.join("bin")
- .join(format!("llvm-config{}", env.executable_extension()));
+ .join(format!("llvm-config{}", executable_extension()));
assert!(llvm_config.is_file());
let config_content = format!(
@@ -109,6 +109,6 @@ fn find_dist_version(directory: &Utf8Path) -> anyhow::Result<String> {
.unwrap()
.to_string();
let (version, _) =
- archive.strip_prefix("reproducible-artifacts-").unwrap().split_once("-").unwrap();
+ archive.strip_prefix("reproducible-artifacts-").unwrap().split_once('-').unwrap();
Ok(version.to_string())
}
diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs
index 59c73fbd6..274f4cea0 100644
--- a/src/tools/opt-dist/src/training.rs
+++ b/src/tools/opt-dist/src/training.rs
@@ -1,4 +1,4 @@
-use crate::environment::Environment;
+use crate::environment::{executable_extension, Environment};
use crate::exec::{cmd, CmdBuilder};
use crate::utils::io::{count_files, delete_directory};
use crate::utils::with_log_group;
@@ -30,7 +30,7 @@ const RUSTC_PGO_CRATES: &[&str] = &[
const LLVM_BOLT_CRATES: &[&str] = LLVM_PGO_CRATES;
fn init_compiler_benchmarks(
- env: &dyn Environment,
+ env: &Environment,
profiles: &[&str],
scenarios: &[&str],
crates: &[&str],
@@ -75,7 +75,7 @@ enum LlvmProfdata {
}
fn merge_llvm_profiles(
- env: &dyn Environment,
+ env: &Environment,
merged_path: &Utf8Path,
profile_dir: &Utf8Path,
profdata: LlvmProfdata,
@@ -86,7 +86,7 @@ fn merge_llvm_profiles(
.build_artifacts()
.join("llvm")
.join("build")
- .join(format!("bin/llvm-profdata{}", env.executable_extension())),
+ .join(format!("bin/llvm-profdata{}", executable_extension())),
};
cmd(&[llvm_profdata.as_str(), "merge", "-o", merged_path.as_str(), profile_dir.as_str()])
@@ -116,7 +116,7 @@ fn log_profile_stats(
pub struct LlvmPGOProfile(pub Utf8PathBuf);
pub fn gather_llvm_profiles(
- env: &dyn Environment,
+ env: &Environment,
profile_root: &Utf8Path,
) -> anyhow::Result<LlvmPGOProfile> {
log::info!("Running benchmarks with PGO instrumented LLVM");
@@ -127,7 +127,7 @@ pub fn gather_llvm_profiles(
.context("Cannot gather LLVM PGO profiles")
})?;
- let merged_profile = env.opt_artifacts().join("llvm-pgo.profdata");
+ let merged_profile = env.artifact_dir().join("llvm-pgo.profdata");
log::info!("Merging LLVM PGO profiles to {merged_profile}");
merge_llvm_profiles(env, &merged_profile, profile_root, LlvmProfdata::Host)?;
@@ -143,7 +143,7 @@ pub fn gather_llvm_profiles(
pub struct RustcPGOProfile(pub Utf8PathBuf);
pub fn gather_rustc_profiles(
- env: &dyn Environment,
+ env: &Environment,
profile_root: &Utf8Path,
) -> anyhow::Result<RustcPGOProfile> {
log::info!("Running benchmarks with PGO instrumented rustc");
@@ -163,7 +163,7 @@ pub fn gather_rustc_profiles(
.context("Cannot gather rustc PGO profiles")
})?;
- let merged_profile = env.opt_artifacts().join("rustc-pgo.profdata");
+ let merged_profile = env.artifact_dir().join("rustc-pgo.profdata");
log::info!("Merging Rustc PGO profiles to {merged_profile}");
merge_llvm_profiles(env, &merged_profile, profile_root, LlvmProfdata::Target)?;
@@ -178,7 +178,7 @@ pub fn gather_rustc_profiles(
pub struct LlvmBoltProfile(pub Utf8PathBuf);
-pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBoltProfile> {
+pub fn gather_llvm_bolt_profiles(env: &Environment) -> anyhow::Result<LlvmBoltProfile> {
log::info!("Running benchmarks with BOLT instrumented LLVM");
with_log_group("Running benchmarks", || {
@@ -187,12 +187,12 @@ pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBo
.context("Cannot gather LLVM BOLT profiles")
})?;
- let merged_profile = env.opt_artifacts().join("llvm-bolt.profdata");
+ let merged_profile = env.artifact_dir().join("llvm-bolt.profdata");
let profile_root = Utf8PathBuf::from("/tmp/prof.fdata");
log::info!("Merging LLVM BOLT profiles to {merged_profile}");
let profiles: Vec<_> =
- glob::glob(&format!("{profile_root}*"))?.into_iter().collect::<Result<Vec<_>, _>>()?;
+ glob::glob(&format!("{profile_root}*"))?.collect::<Result<Vec<_>, _>>()?;
let mut merge_args = vec!["merge-fdata"];
merge_args.extend(profiles.iter().map(|p| p.to_str().unwrap()));
diff --git a/src/tools/opt-dist/src/utils/io.rs b/src/tools/opt-dist/src/utils/io.rs
index 8bd516fa3..d6bd5cb85 100644
--- a/src/tools/opt-dist/src/utils/io.rs
+++ b/src/tools/opt-dist/src/utils/io.rs
@@ -7,7 +7,7 @@ use std::path::Path;
/// Delete and re-create the directory.
pub fn reset_directory(path: &Utf8Path) -> anyhow::Result<()> {
log::info!("Resetting directory {path}");
- let _ = std::fs::remove_dir(path);
+ let _ = std::fs::remove_dir_all(path);
std::fs::create_dir_all(path)?;
Ok(())
}
@@ -63,7 +63,6 @@ pub fn get_files_from_dir(
let path = format!("{dir}/*{}", suffix.unwrap_or(""));
Ok(glob::glob(&path)?
- .into_iter()
.map(|p| p.map(|p| Utf8PathBuf::from_path_buf(p).unwrap()))
.collect::<Result<Vec<_>, _>>()?)
}
@@ -74,9 +73,8 @@ pub fn find_file_in_dir(
prefix: &str,
suffix: &str,
) -> anyhow::Result<Utf8PathBuf> {
- let files = glob::glob(&format!("{directory}/{prefix}*{suffix}"))?
- .into_iter()
- .collect::<Result<Vec<_>, _>>()?;
+ let files =
+ glob::glob(&format!("{directory}/{prefix}*{suffix}"))?.collect::<Result<Vec<_>, _>>()?;
match files.len() {
0 => Err(anyhow::anyhow!("No file with prefix {prefix} found in {directory}")),
1 => Ok(Utf8PathBuf::from_path_buf(files[0].clone()).unwrap()),
diff --git a/src/tools/opt-dist/src/utils/mod.rs b/src/tools/opt-dist/src/utils/mod.rs
index 9a3df15e3..6fc96592a 100644
--- a/src/tools/opt-dist/src/utils/mod.rs
+++ b/src/tools/opt-dist/src/utils/mod.rs
@@ -3,6 +3,7 @@ pub mod io;
use crate::environment::Environment;
use crate::utils::io::{delete_directory, get_files_from_dir};
use humansize::{format_size, BINARY};
+use std::time::Duration;
use sysinfo::{DiskExt, RefreshKind, System, SystemExt};
pub fn format_env_variables() -> String {
@@ -25,7 +26,7 @@ pub fn print_free_disk_space() -> anyhow::Result<()> {
Ok(())
}
-pub fn print_binary_sizes(env: &dyn Environment) -> anyhow::Result<()> {
+pub fn print_binary_sizes(env: &Environment) -> anyhow::Result<()> {
use std::fmt::Write;
let root = env.build_artifacts().join("stage2");
@@ -47,7 +48,7 @@ pub fn print_binary_sizes(env: &dyn Environment) -> anyhow::Result<()> {
Ok(())
}
-pub fn clear_llvm_files(env: &dyn Environment) -> anyhow::Result<()> {
+pub fn clear_llvm_files(env: &Environment) -> anyhow::Result<()> {
// Bootstrap currently doesn't support rebuilding LLVM when PGO options
// change (or any other llvm-related options); so just clear out the relevant
// directories ourselves.
@@ -70,6 +71,24 @@ pub fn with_log_group<F: FnOnce() -> R, R>(group: &str, func: F) -> R {
}
}
+#[allow(unused)]
+pub fn retry_action<F: Fn() -> anyhow::Result<R>, R>(
+ action: F,
+ name: &str,
+ count: u64,
+) -> anyhow::Result<R> {
+ for attempt in 0..count {
+ match action() {
+ Ok(result) => return Ok(result),
+ Err(error) => {
+ log::error!("Failed to perform action `{name}`, attempt #{attempt}: {error:?}");
+ std::thread::sleep(Duration::from_secs(5));
+ }
+ }
+ }
+ Err(anyhow::anyhow!("Failed to perform action `{name}` after {count} retries"))
+}
+
fn is_in_ci() -> bool {
std::env::var("GITHUB_ACTIONS").is_ok()
}
diff --git a/src/tools/rust-analyzer/.cargo/config.toml b/src/tools/rust-analyzer/.cargo/config.toml
index 24745d1c8..c9ad78039 100644
--- a/src/tools/rust-analyzer/.cargo/config.toml
+++ b/src/tools/rust-analyzer/.cargo/config.toml
@@ -8,4 +8,4 @@ lint = "clippy --all-targets -- -Aclippy::collapsible_if -Aclippy::needless_pass
linker = "rust-lld"
[env]
-CARGO_WORKSPACE_DIR = { value = "", relative = true } \ No newline at end of file
+CARGO_WORKSPACE_DIR = { value = "", relative = true }
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index a2b263cf2..bd6554bf8 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -381,14 +381,14 @@ dependencies = [
[[package]]
name = "filetime"
-version = "0.2.19"
+version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9"
+checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall",
- "windows-sys 0.42.0",
+ "redox_syscall 0.3.5",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -541,6 +541,7 @@ dependencies = [
"mbe",
"once_cell",
"profile",
+ "ra-ap-rustc_parse_format",
"rustc-hash",
"smallvec",
"stdx",
@@ -854,7 +855,6 @@ version = "0.0.0"
dependencies = [
"dashmap",
"hashbrown 0.12.3",
- "once_cell",
"rustc-hash",
"triomphe",
]
@@ -999,23 +999,23 @@ checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
[[package]]
name = "lsp-server"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3711e4d6f491dc9edc0f1df80e204f38206775ac92c1241e89b79229a850bc00"
+version = "0.7.4"
dependencies = [
"crossbeam-channel",
"log",
+ "lsp-types",
"serde",
"serde_json",
]
[[package]]
name = "lsp-server"
-version = "0.7.2"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b52dccdf3302eefab8c8a1273047f0a3c3dca4b527c8458d00c09484c8371928"
dependencies = [
"crossbeam-channel",
"log",
- "lsp-types",
"serde",
"serde_json",
]
@@ -1149,20 +1149,21 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[package]]
name = "notify"
-version = "5.1.0"
+version = "6.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58ea850aa68a06e48fdb069c0ec44d0d64c8dbffa49bf3b6f7f0a901fdea1ba9"
+checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.3.2",
"crossbeam-channel",
"filetime",
"fsevent-sys",
"inotify",
"kqueue",
"libc",
+ "log",
"mio",
"walkdir",
- "windows-sys 0.42.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -1251,7 +1252,7 @@ dependencies = [
"cfg-if",
"instant",
"libc",
- "redox_syscall",
+ "redox_syscall 0.2.16",
"smallvec",
"winapi",
]
@@ -1264,7 +1265,7 @@ checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall",
+ "redox_syscall 0.2.16",
"smallvec",
"windows-sys 0.42.0",
]
@@ -1482,16 +1483,36 @@ dependencies = [
]
[[package]]
+name = "ra-ap-rustc_index"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07b5fa61d34da18e148dc3a81f654488ea07f40938d8aefb17f8b64bb78c6120"
+dependencies = [
+ "arrayvec",
+ "smallvec",
+]
+
+[[package]]
name = "ra-ap-rustc_lexer"
-version = "0.1.0"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1c145702ed3f237918e512685185dc8a4d0edc3a5326c63d20361d8ba9b45b3"
+checksum = "f2e2f6b48422e4eed5218277ab7cc9733e60dd8f3167f4f36a49a0cafe4dc195"
dependencies = [
- "unic-emoji-char",
+ "unicode-properties",
"unicode-xid",
]
[[package]]
+name = "ra-ap-rustc_parse_format"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3c7369ad01cc79f9e3513c9f6a6326f6b980100e4862a7ac71b9991c88108bb"
+dependencies = [
+ "ra-ap-rustc_index",
+ "ra-ap-rustc_lexer",
+]
+
+[[package]]
name = "rayon"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1523,6 +1544,15 @@ dependencies = [
]
[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
name = "rowan"
version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1545,7 +1575,6 @@ dependencies = [
"crossbeam-channel",
"dissimilar",
"expect-test",
- "filetime",
"flycheck",
"hir",
"hir-def",
@@ -1555,7 +1584,7 @@ dependencies = [
"ide-ssr",
"itertools",
"load-cargo",
- "lsp-server 0.7.1",
+ "lsp-server 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lsp-types",
"mbe",
"mimalloc",
@@ -2057,47 +2086,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f"
[[package]]
-name = "unic-char-property"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
-dependencies = [
- "unic-char-range",
-]
-
-[[package]]
-name = "unic-char-range"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
-
-[[package]]
-name = "unic-common"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
-
-[[package]]
-name = "unic-emoji-char"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d"
-dependencies = [
- "unic-char-property",
- "unic-char-range",
- "unic-ucd-version",
-]
-
-[[package]]
-name = "unic-ucd-version"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
-dependencies = [
- "unic-common",
-]
-
-[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2128,6 +2116,12 @@ dependencies = [
]
[[package]]
+name = "unicode-properties"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7f91c8b21fbbaa18853c3d0801c78f4fc94cdb976699bb03e832e75f7fd22f0"
+
+[[package]]
name = "unicode-segmentation"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index f6a50bfa6..cab88fc18 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -86,7 +86,7 @@ proc-macro-test = { path = "./crates/proc-macro-test" }
# In-tree crates that are published separately and follow semver. See lib/README.md
line-index = { version = "0.1.0-pre.1" }
la-arena = { version = "0.3.1" }
-lsp-server = { version = "0.7.1" }
+lsp-server = { version = "0.7.4" }
# non-local crates
smallvec = { version = "1.10.0", features = [
@@ -103,4 +103,9 @@ triomphe = { version = "0.1.8", default-features = false, features = ["std"] }
# can't upgrade due to dashmap depending on 0.12.3 currently
hashbrown = { version = "0.12.3", features = ["inline-more"], default-features = false }
-rustc_lexer = { version = "0.1.0", package = "ra-ap-rustc_lexer" }
+rustc_lexer = { version = "0.10.0", package = "ra-ap-rustc_lexer" }
+rustc_parse_format = { version = "0.10.0", package = "ra-ap-rustc_parse_format", default-features = false }
+
+# Upstream broke this for us so we can't update it
+rustc_abi = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_abi", default-features = false }
+rustc_index = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
diff --git a/src/tools/rust-analyzer/crates/base-db/src/fixture.rs b/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
index 323ee4260..3f5ccb621 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
@@ -130,6 +130,7 @@ impl ChangeFixture {
let mut default_crate_root: Option<FileId> = None;
let mut default_target_data_layout: Option<String> = None;
let mut default_cfg = CfgOptions::default();
+ let mut default_env = Env::new_for_test_fixture();
let mut file_set = FileSet::default();
let mut current_source_root_kind = SourceRootKind::Local;
@@ -178,8 +179,8 @@ impl ChangeFixture {
meta.edition,
Some(crate_name.clone().into()),
version,
- meta.cfg,
- Default::default(),
+ meta.cfg.clone(),
+ Some(meta.cfg),
meta.env,
false,
origin,
@@ -199,7 +200,8 @@ impl ChangeFixture {
} else if meta.path == "/main.rs" || meta.path == "/lib.rs" {
assert!(default_crate_root.is_none());
default_crate_root = Some(file_id);
- default_cfg = meta.cfg;
+ default_cfg.extend(meta.cfg.into_iter());
+ default_env.extend(meta.env.iter().map(|(x, y)| (x.to_owned(), y.to_owned())));
default_target_data_layout = meta.target_data_layout;
}
@@ -218,9 +220,9 @@ impl ChangeFixture {
Edition::CURRENT,
Some(CrateName::new("test").unwrap().into()),
None,
- default_cfg,
- Default::default(),
- Env::new_for_test_fixture(),
+ default_cfg.clone(),
+ Some(default_cfg),
+ default_env,
false,
CrateOrigin::Local { repo: None, name: None },
default_target_data_layout
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index c47799f13..b75c7079b 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -686,6 +686,12 @@ impl fmt::Display for Edition {
}
}
+impl Extend<(String, String)> for Env {
+ fn extend<T: IntoIterator<Item = (String, String)>>(&mut self, iter: T) {
+ self.entries.extend(iter);
+ }
+}
+
impl FromIterator<(String, String)> for Env {
fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self {
Env { entries: FromIterator::from_iter(iter) }
diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs
index 183b9b7d2..0aeb0b050 100644
--- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs
@@ -86,6 +86,32 @@ impl CfgOptions {
}
}
+impl Extend<CfgAtom> for CfgOptions {
+ fn extend<T: IntoIterator<Item = CfgAtom>>(&mut self, iter: T) {
+ iter.into_iter().for_each(|cfg_flag| _ = self.enabled.insert(cfg_flag));
+ }
+}
+
+impl IntoIterator for CfgOptions {
+ type Item = <FxHashSet<CfgAtom> as IntoIterator>::Item;
+
+ type IntoIter = <FxHashSet<CfgAtom> as IntoIterator>::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ <FxHashSet<CfgAtom> as IntoIterator>::into_iter(self.enabled)
+ }
+}
+
+impl<'a> IntoIterator for &'a CfgOptions {
+ type Item = <&'a FxHashSet<CfgAtom> as IntoIterator>::Item;
+
+ type IntoIter = <&'a FxHashSet<CfgAtom> as IntoIterator>::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ <&FxHashSet<CfgAtom> as IntoIterator>::into_iter(&self.enabled)
+ }
+}
+
#[derive(Default, Clone, Debug, PartialEq, Eq)]
pub struct CfgDiff {
// Invariants: No duplicates, no atom that's both in `enable` and `disable`.
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
index fbb943ccb..2de719af9 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
@@ -5,7 +5,9 @@
#![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
use std::{
+ ffi::OsString,
fmt, io,
+ path::PathBuf,
process::{ChildStderr, ChildStdout, Command, Stdio},
time::Duration,
};
@@ -168,7 +170,7 @@ struct FlycheckActor {
/// doesn't provide a way to read sub-process output without blocking, so we
/// have to wrap sub-processes output handling in a thread and pass messages
/// back over a channel.
- cargo_handle: Option<CargoHandle>,
+ command_handle: Option<CommandHandle>,
}
enum Event {
@@ -184,7 +186,7 @@ impl FlycheckActor {
workspace_root: AbsPathBuf,
) -> FlycheckActor {
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
- FlycheckActor { id, sender, config, root: workspace_root, cargo_handle: None }
+ FlycheckActor { id, sender, config, root: workspace_root, command_handle: None }
}
fn report_progress(&self, progress: Progress) {
@@ -192,7 +194,7 @@ impl FlycheckActor {
}
fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> {
- let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
+ let check_chan = self.command_handle.as_ref().map(|cargo| &cargo.receiver);
if let Ok(msg) = inbox.try_recv() {
// give restarts a preference so check outputs don't block a restart or stop
return Some(Event::RequestStateChange(msg));
@@ -221,21 +223,19 @@ impl FlycheckActor {
}
let command = self.check_command();
+ let formatted_command = format!("{:?}", command);
+
tracing::debug!(?command, "will restart flycheck");
- match CargoHandle::spawn(command) {
- Ok(cargo_handle) => {
- tracing::debug!(
- command = ?self.check_command(),
- "did restart flycheck"
- );
- self.cargo_handle = Some(cargo_handle);
+ match CommandHandle::spawn(command) {
+ Ok(command_handle) => {
+ tracing::debug!(command = formatted_command, "did restart flycheck");
+ self.command_handle = Some(command_handle);
self.report_progress(Progress::DidStart);
}
Err(error) => {
self.report_progress(Progress::DidFailToRestart(format!(
- "Failed to run the following command: {:?} error={}",
- self.check_command(),
- error
+ "Failed to run the following command: {} error={}",
+ formatted_command, error
)));
}
}
@@ -244,12 +244,14 @@ impl FlycheckActor {
tracing::debug!(flycheck_id = self.id, "flycheck finished");
// Watcher finished
- let cargo_handle = self.cargo_handle.take().unwrap();
- let res = cargo_handle.join();
+ let command_handle = self.command_handle.take().unwrap();
+ let formatted_handle = format!("{:?}", command_handle);
+
+ let res = command_handle.join();
if res.is_err() {
tracing::error!(
- "Flycheck failed to run the following command: {:?}",
- self.check_command()
+ "Flycheck failed to run the following command: {}",
+ formatted_handle
);
}
self.report_progress(Progress::DidFinish(res));
@@ -284,12 +286,12 @@ impl FlycheckActor {
}
fn cancel_check_process(&mut self) {
- if let Some(cargo_handle) = self.cargo_handle.take() {
+ if let Some(command_handle) = self.command_handle.take() {
tracing::debug!(
- command = ?self.check_command(),
+ command = ?command_handle,
"did cancel flycheck"
);
- cargo_handle.cancel();
+ command_handle.cancel();
self.report_progress(Progress::DidCancel);
}
}
@@ -391,19 +393,36 @@ impl Drop for JodGroupChild {
}
/// A handle to a cargo process used for fly-checking.
-struct CargoHandle {
+struct CommandHandle {
/// The handle to the actual cargo process. As we cannot cancel directly from with
/// a read syscall dropping and therefore terminating the process is our best option.
child: JodGroupChild,
thread: stdx::thread::JoinHandle<io::Result<(bool, String)>>,
receiver: Receiver<CargoMessage>,
+ program: OsString,
+ arguments: Vec<OsString>,
+ current_dir: Option<PathBuf>,
}
-impl CargoHandle {
- fn spawn(mut command: Command) -> std::io::Result<CargoHandle> {
+impl fmt::Debug for CommandHandle {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("CommandHandle")
+ .field("program", &self.program)
+ .field("arguments", &self.arguments)
+ .field("current_dir", &self.current_dir)
+ .finish()
+ }
+}
+
+impl CommandHandle {
+ fn spawn(mut command: Command) -> std::io::Result<CommandHandle> {
command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null());
let mut child = command.group_spawn().map(JodGroupChild)?;
+ let program = command.get_program().into();
+ let arguments = command.get_args().map(|arg| arg.into()).collect::<Vec<OsString>>();
+ let current_dir = command.get_current_dir().map(|arg| arg.to_path_buf());
+
let stdout = child.0.inner().stdout.take().unwrap();
let stderr = child.0.inner().stderr.take().unwrap();
@@ -413,7 +432,7 @@ impl CargoHandle {
.name("CargoHandle".to_owned())
.spawn(move || actor.run())
.expect("failed to spawn thread");
- Ok(CargoHandle { child, thread, receiver })
+ Ok(CommandHandle { program, arguments, current_dir, child, thread, receiver })
}
fn cancel(mut self) {
diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
index 30307deb7..8cf61ee04 100644
--- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
@@ -31,8 +31,10 @@ smallvec.workspace = true
hashbrown.workspace = true
triomphe.workspace = true
-rustc_abi = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_abi", default-features = false }
-rustc_index = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
+rustc_abi.workspace = true
+rustc_index.workspace = true
+rustc_parse_format.workspace = true
+
# local deps
stdx.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
index fae071118..c6454eb9e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
@@ -5,7 +5,7 @@ pub mod builtin;
#[cfg(test)]
mod tests;
-use std::{hash::Hash, ops};
+use std::{hash::Hash, ops, slice::Iter as SliceIter};
use base_db::CrateId;
use cfg::{CfgExpr, CfgOptions};
@@ -14,12 +14,11 @@ use hir_expand::{
attrs::{collect_attrs, Attr, AttrId, RawAttrs},
HirFileId, InFile,
};
-use itertools::Itertools;
use la_arena::{ArenaMap, Idx, RawIdx};
use mbe::DelimiterKind;
use syntax::{
- ast::{self, HasAttrs, IsString},
- AstPtr, AstToken, SmolStr, TextRange, TextSize,
+ ast::{self, HasAttrs},
+ AstPtr, SmolStr,
};
use triomphe::Arc;
@@ -33,26 +32,6 @@ use crate::{
LocalFieldId, Lookup, MacroId, VariantId,
};
-/// Holds documentation
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Documentation(String);
-
-impl Documentation {
- pub fn new(s: String) -> Self {
- Documentation(s)
- }
-
- pub fn as_str(&self) -> &str {
- &self.0
- }
-}
-
-impl From<Documentation> for String {
- fn from(Documentation(string): Documentation) -> Self {
- string
- }
-}
-
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Attrs(RawAttrs);
@@ -221,33 +200,6 @@ impl Attrs {
self.by_key("lang").string_value().and_then(|it| LangItem::from_str(it))
}
- pub fn docs(&self) -> Option<Documentation> {
- let docs = self.by_key("doc").attrs().filter_map(|attr| attr.string_value());
- let indent = doc_indent(self);
- let mut buf = String::new();
- for doc in docs {
- // str::lines doesn't yield anything for the empty string
- if !doc.is_empty() {
- buf.extend(Itertools::intersperse(
- doc.lines().map(|line| {
- line.char_indices()
- .nth(indent)
- .map_or(line, |(offset, _)| &line[offset..])
- .trim_end()
- }),
- "\n",
- ));
- }
- buf.push('\n');
- }
- buf.pop();
- if buf.is_empty() {
- None
- } else {
- Some(Documentation(buf))
- }
- }
-
pub fn has_doc_hidden(&self) -> bool {
self.by_key("doc").tt_values().any(|tt| {
tt.delimiter.kind == DelimiterKind::Parenthesis &&
@@ -299,7 +251,6 @@ impl Attrs {
}
}
-use std::slice::Iter as SliceIter;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum DocAtom {
/// eg. `#[doc(hidden)]`
@@ -313,7 +264,6 @@ pub enum DocAtom {
// Adapted from `CfgExpr` parsing code
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-// #[cfg_attr(test, derive(derive_arbitrary::Arbitrary))]
pub enum DocExpr {
Invalid,
/// eg. `#[doc(hidden)]`, `#[doc(alias = "x")]`
@@ -431,12 +381,10 @@ impl AttrsWithOwner {
.item_tree(db)
.raw_attrs(AttrOwner::ModItem(definition_tree_id.value.into()))
.clone(),
- ModuleOrigin::BlockExpr { block } => RawAttrs::from_attrs_owner(
- db.upcast(),
- InFile::new(block.file_id, block.to_node(db.upcast()))
- .as_ref()
- .map(|it| it as &dyn ast::HasAttrs),
- ),
+ ModuleOrigin::BlockExpr { id, .. } => {
+ let tree = db.block_item_tree_query(id);
+ tree.raw_attrs(AttrOwner::TopLevel).clone()
+ }
}
}
AttrDefId::FieldId(it) => {
@@ -576,62 +524,6 @@ impl AttrsWithOwner {
AttrSourceMap::new(owner.as_ref().map(|node| node as &dyn HasAttrs))
}
-
- pub fn docs_with_rangemap(
- &self,
- db: &dyn DefDatabase,
- ) -> Option<(Documentation, DocsRangeMap)> {
- let docs =
- self.by_key("doc").attrs().filter_map(|attr| attr.string_value().map(|s| (s, attr.id)));
- let indent = doc_indent(self);
- let mut buf = String::new();
- let mut mapping = Vec::new();
- for (doc, idx) in docs {
- if !doc.is_empty() {
- let mut base_offset = 0;
- for raw_line in doc.split('\n') {
- let line = raw_line.trim_end();
- let line_len = line.len();
- let (offset, line) = match line.char_indices().nth(indent) {
- Some((offset, _)) => (offset, &line[offset..]),
- None => (0, line),
- };
- let buf_offset = buf.len();
- buf.push_str(line);
- mapping.push((
- TextRange::new(buf_offset.try_into().ok()?, buf.len().try_into().ok()?),
- idx,
- TextRange::at(
- (base_offset + offset).try_into().ok()?,
- line_len.try_into().ok()?,
- ),
- ));
- buf.push('\n');
- base_offset += raw_line.len() + 1;
- }
- } else {
- buf.push('\n');
- }
- }
- buf.pop();
- if buf.is_empty() {
- None
- } else {
- Some((Documentation(buf), DocsRangeMap { mapping, source_map: self.source_map(db) }))
- }
- }
-}
-
-fn doc_indent(attrs: &Attrs) -> usize {
- attrs
- .by_key("doc")
- .attrs()
- .filter_map(|attr| attr.string_value())
- .flat_map(|s| s.lines())
- .filter(|line| !line.chars().all(|c| c.is_whitespace()))
- .map(|line| line.chars().take_while(|c| c.is_whitespace()).count())
- .min()
- .unwrap_or(0)
}
#[derive(Debug)]
@@ -675,7 +567,7 @@ impl AttrSourceMap {
self.source_of_id(attr.id)
}
- fn source_of_id(&self, id: AttrId) -> InFile<&Either<ast::Attr, ast::Comment>> {
+ pub fn source_of_id(&self, id: AttrId) -> InFile<&Either<ast::Attr, ast::Comment>> {
let ast_idx = id.ast_index();
let file_id = match self.mod_def_site_file_id {
Some((file_id, def_site_cut)) if def_site_cut <= ast_idx => file_id,
@@ -689,69 +581,6 @@ impl AttrSourceMap {
}
}
-/// A struct to map text ranges from [`Documentation`] back to TextRanges in the syntax tree.
-#[derive(Debug)]
-pub struct DocsRangeMap {
- source_map: AttrSourceMap,
- // (docstring-line-range, attr_index, attr-string-range)
- // a mapping from the text range of a line of the [`Documentation`] to the attribute index and
- // the original (untrimmed) syntax doc line
- mapping: Vec<(TextRange, AttrId, TextRange)>,
-}
-
-impl DocsRangeMap {
- /// Maps a [`TextRange`] relative to the documentation string back to its AST range
- pub fn map(&self, range: TextRange) -> Option<InFile<TextRange>> {
- let found = self.mapping.binary_search_by(|(probe, ..)| probe.ordering(range)).ok()?;
- let (line_docs_range, idx, original_line_src_range) = self.mapping[found];
- if !line_docs_range.contains_range(range) {
- return None;
- }
-
- let relative_range = range - line_docs_range.start();
-
- let InFile { file_id, value: source } = self.source_map.source_of_id(idx);
- match source {
- Either::Left(attr) => {
- let string = get_doc_string_in_attr(attr)?;
- let text_range = string.open_quote_text_range()?;
- let range = TextRange::at(
- text_range.end() + original_line_src_range.start() + relative_range.start(),
- string.syntax().text_range().len().min(range.len()),
- );
- Some(InFile { file_id, value: range })
- }
- Either::Right(comment) => {
- let text_range = comment.syntax().text_range();
- let range = TextRange::at(
- text_range.start()
- + TextSize::try_from(comment.prefix().len()).ok()?
- + original_line_src_range.start()
- + relative_range.start(),
- text_range.len().min(range.len()),
- );
- Some(InFile { file_id, value: range })
- }
- }
- }
-}
-
-fn get_doc_string_in_attr(it: &ast::Attr) -> Option<ast::String> {
- match it.expr() {
- // #[doc = lit]
- Some(ast::Expr::Literal(lit)) => match lit.kind() {
- ast::LiteralKind::String(it) => Some(it),
- _ => None,
- },
- // #[cfg_attr(..., doc = "", ...)]
- None => {
- // FIXME: See highlight injection for what to do here
- None
- }
- _ => None,
- }
-}
-
#[derive(Debug, Clone, Copy)]
pub struct AttrQuery<'attr> {
attrs: &'attr Attrs,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
index cead64a33..152f05b2c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
@@ -8,7 +8,8 @@
//! name resolution, and `BUILTIN_ATTRIBUTES` is almost entirely unchanged from the original, to
//! ease updating.
-use once_cell::sync::OnceCell;
+use std::sync::OnceLock;
+
use rustc_hash::FxHashMap;
/// Ignored attribute namespaces used by tools.
@@ -29,7 +30,7 @@ pub struct AttributeTemplate {
}
pub fn find_builtin_attr_idx(name: &str) -> Option<usize> {
- static BUILTIN_LOOKUP_TABLE: OnceCell<FxHashMap<&'static str, usize>> = OnceCell::new();
+ static BUILTIN_LOOKUP_TABLE: OnceLock<FxHashMap<&'static str, usize>> = OnceLock::new();
BUILTIN_LOOKUP_TABLE
.get_or_init(|| {
INERT_ATTRIBUTES.iter().map(|attr| attr.name).enumerate().map(|(a, b)| (b, a)).collect()
@@ -239,7 +240,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
template!(List: "address, kcfi, memory, thread"), DuplicatesOk,
experimental!(no_sanitize)
),
- gated!(no_coverage, Normal, template!(Word), WarnFollowing, experimental!(no_coverage)),
+ gated!(coverage, Normal, template!(Word, List: "on|off"), WarnFollowing, experimental!(coverage)),
ungated!(
doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
index f8d492d0e..c0baf6011 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
@@ -65,6 +65,8 @@ pub type LabelSource = InFile<LabelPtr>;
pub type FieldPtr = AstPtr<ast::RecordExprField>;
pub type FieldSource = InFile<FieldPtr>;
+pub type PatFieldPtr = AstPtr<ast::RecordPatField>;
+pub type PatFieldSource = InFile<PatFieldPtr>;
/// An item body together with the mapping from syntax nodes to HIR expression
/// IDs. This is needed to go from e.g. a position in a file to the HIR
@@ -90,8 +92,8 @@ pub struct BodySourceMap {
/// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
/// Instead, we use id of expression (`92`) to identify the field.
- field_map: FxHashMap<FieldSource, ExprId>,
field_map_back: FxHashMap<ExprId, FieldSource>,
+ pat_field_map_back: FxHashMap<PatId, PatFieldSource>,
expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
@@ -164,9 +166,10 @@ impl Body {
};
let module = def.module(db);
let expander = Expander::new(db, file_id, module);
- let (mut body, source_map) =
+ let (mut body, mut source_map) =
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
body.shrink_to_fit();
+ source_map.shrink_to_fit();
(Arc::new(body), Arc::new(source_map))
}
@@ -375,9 +378,8 @@ impl BodySourceMap {
self.field_map_back[&expr].clone()
}
- pub fn node_field(&self, node: InFile<&ast::RecordExprField>) -> Option<ExprId> {
- let src = node.map(AstPtr::new);
- self.field_map.get(&src).cloned()
+ pub fn pat_field_syntax(&self, pat: PatId) -> PatFieldSource {
+ self.pat_field_map_back[&pat].clone()
}
pub fn macro_expansion_expr(&self, node: InFile<&ast::MacroExpr>) -> Option<ExprId> {
@@ -389,4 +391,29 @@ impl BodySourceMap {
pub fn diagnostics(&self) -> &[BodyDiagnostic] {
&self.diagnostics
}
+
+ fn shrink_to_fit(&mut self) {
+ let Self {
+ expr_map,
+ expr_map_back,
+ pat_map,
+ pat_map_back,
+ label_map,
+ label_map_back,
+ field_map_back,
+ pat_field_map_back,
+ expansions,
+ diagnostics,
+ } = self;
+ expr_map.shrink_to_fit();
+ expr_map_back.shrink_to_fit();
+ pat_map.shrink_to_fit();
+ pat_map_back.shrink_to_fit();
+ label_map.shrink_to_fit();
+ label_map_back.shrink_to_fit();
+ field_map_back.shrink_to_fit();
+ pat_field_map_back.shrink_to_fit();
+ expansions.shrink_to_fit();
+ diagnostics.shrink_to_fit();
+ }
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
index 3853a6ab3..cc02df80a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
@@ -25,13 +25,20 @@ use triomphe::Arc;
use crate::{
body::{Body, BodyDiagnostic, BodySourceMap, ExprPtr, LabelPtr, PatPtr},
+ builtin_type::BuiltinUint,
data::adt::StructKind,
db::DefDatabase,
expander::Expander,
hir::{
- dummy_expr_id, Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy,
- ClosureKind, Expr, ExprId, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
- Pat, PatId, RecordFieldPat, RecordLitField, Statement,
+ dummy_expr_id,
+ format_args::{
+ self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind,
+ FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions,
+ FormatPlaceholder, FormatSign, FormatTrait,
+ },
+ Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind,
+ Expr, ExprId, InlineAsm, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
+ OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
},
item_scope::BuiltinShadowMode,
lang_item::LangItem,
@@ -42,6 +49,8 @@ use crate::{
AdtId, BlockId, BlockLoc, ConstBlockLoc, DefWithBodyId, ModuleDefId, UnresolvedMacro,
};
+type FxIndexSet<K> = indexmap::IndexSet<K, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
+
pub(super) fn lower(
db: &dyn DefDatabase,
owner: DefWithBodyId,
@@ -437,7 +446,6 @@ impl ExprCollector<'_> {
None => self.missing_expr(),
};
let src = self.expander.to_source(AstPtr::new(&field));
- self.source_map.field_map.insert(src.clone(), expr);
self.source_map.field_map_back.insert(expr, src);
Some(RecordLitField { name, expr })
})
@@ -505,6 +513,9 @@ impl ExprCollector<'_> {
let mut args = Vec::new();
let mut arg_types = Vec::new();
if let Some(pl) = e.param_list() {
+ let num_params = pl.params().count();
+ args.reserve_exact(num_params);
+ arg_types.reserve_exact(num_params);
for param in pl.params() {
let pat = this.collect_pat_top(param.pat());
let type_ref =
@@ -576,11 +587,6 @@ impl ExprCollector<'_> {
syntax_ptr,
)
}
- ast::Expr::BoxExpr(e) => {
- let expr = self.collect_expr_opt(e.expr());
- self.alloc_expr(Expr::Box { expr }, syntax_ptr)
- }
-
ast::Expr::ArrayExpr(e) => {
let kind = e.kind();
@@ -650,6 +656,16 @@ impl ExprCollector<'_> {
}
}
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
+ ast::Expr::AsmExpr(e) => {
+ let e = self.collect_expr_opt(e.expr());
+ self.alloc_expr(Expr::InlineAsm(InlineAsm { e }), syntax_ptr)
+ }
+ ast::Expr::OffsetOfExpr(e) => {
+ let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
+ let fields = e.fields().map(|it| it.as_name()).collect();
+ self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
+ }
+ ast::Expr::FormatArgsExpr(f) => self.collect_format_args(f, syntax_ptr),
})
}
@@ -660,6 +676,7 @@ impl ExprCollector<'_> {
let result_expr_id = self.alloc_expr(Expr::Missing, syntax_ptr);
let prev_binding_owner = self.current_binding_owner.take();
self.current_binding_owner = Some(result_expr_id);
+
(result_expr_id, prev_binding_owner)
}
@@ -741,7 +758,27 @@ impl ExprCollector<'_> {
fn collect_while_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::WhileExpr) -> ExprId {
let label = e.label().map(|label| self.collect_label(label));
let body = self.collect_labelled_block_opt(label, e.loop_body());
- let condition = self.collect_expr_opt(e.condition());
+
+ // Labels can also be used in the condition expression, like this:
+ // ```
+ // fn main() {
+ // let mut optional = Some(0);
+ // 'my_label: while let Some(a) = match optional {
+ // None => break 'my_label,
+ // Some(val) => Some(val),
+ // } {
+ // println!("{}", a);
+ // optional = None;
+ // }
+ // }
+ // ```
+ let condition = match label {
+ Some(label) => {
+ self.with_labeled_rib(label, |this| this.collect_expr_opt(e.condition()))
+ }
+ None => self.collect_expr_opt(e.condition()),
+ };
+
let break_expr =
self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr.clone());
let if_expr = self.alloc_expr(
@@ -1100,7 +1137,9 @@ impl ExprCollector<'_> {
ast::Stmt::ExprStmt(es) => matches!(es.expr(), Some(ast::Expr::MacroExpr(_))),
_ => false,
});
- statement_has_item || matches!(block.tail_expr(), Some(ast::Expr::MacroExpr(_)))
+ statement_has_item
+ || matches!(block.tail_expr(), Some(ast::Expr::MacroExpr(_)))
+ || (block.may_carry_attributes() && block.attrs().next().is_some())
};
let block_id = if block_has_items {
@@ -1290,23 +1329,21 @@ impl ExprCollector<'_> {
ast::Pat::RecordPat(p) => {
let path =
p.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
- let args = p
- .record_pat_field_list()
- .expect("every struct should have a field list")
+ let record_pat_field_list =
+ &p.record_pat_field_list().expect("every struct should have a field list");
+ let args = record_pat_field_list
.fields()
.filter_map(|f| {
let ast_pat = f.pat()?;
let pat = self.collect_pat(ast_pat, binding_list);
let name = f.field_name()?.as_name();
+ let src = self.expander.to_source(AstPtr::new(&f));
+ self.source_map.pat_field_map_back.insert(pat, src);
Some(RecordFieldPat { name, pat })
})
.collect();
- let ellipsis = p
- .record_pat_field_list()
- .expect("every struct should have a field list")
- .rest_pat()
- .is_some();
+ let ellipsis = record_pat_field_list.rest_pat().is_some();
Pat::Record { path, args, ellipsis }
}
@@ -1526,6 +1563,401 @@ impl ExprCollector<'_> {
}
}
// endregion: labels
+
+ // region: format
+ fn expand_macros_to_string(&mut self, expr: ast::Expr) -> Option<(ast::String, bool)> {
+ let m = match expr {
+ ast::Expr::MacroExpr(m) => m,
+ ast::Expr::Literal(l) => {
+ return match l.kind() {
+ ast::LiteralKind::String(s) => Some((s, true)),
+ _ => None,
+ }
+ }
+ _ => return None,
+ };
+ let e = m.macro_call()?;
+ let macro_ptr = AstPtr::new(&e);
+ let (exp, _) = self.collect_macro_call(e, macro_ptr, true, |this, expansion| {
+ expansion.and_then(|it| this.expand_macros_to_string(it))
+ })?;
+ Some((exp, false))
+ }
+
+ fn collect_format_args(
+ &mut self,
+ f: ast::FormatArgsExpr,
+ syntax_ptr: AstPtr<ast::Expr>,
+ ) -> ExprId {
+ let mut args = FormatArgumentsCollector::new();
+ f.args().for_each(|arg| {
+ args.add(FormatArgument {
+ kind: match arg.name() {
+ Some(name) => FormatArgumentKind::Named(name.as_name()),
+ None => FormatArgumentKind::Normal,
+ },
+ expr: self.collect_expr_opt(arg.expr()),
+ });
+ });
+ let template = f.template();
+ let fmt_snippet = template.as_ref().map(ToString::to_string);
+ let fmt = match template.and_then(|it| self.expand_macros_to_string(it)) {
+ Some((s, is_direct_literal)) => {
+ format_args::parse(&s, fmt_snippet, args, is_direct_literal, |name| {
+ self.alloc_expr_desugared(Expr::Path(Path::from(name)))
+ })
+ }
+ None => FormatArgs { template: Default::default(), arguments: args.finish() },
+ };
+
+ // Create a list of all _unique_ (argument, format trait) combinations.
+ // E.g. "{0} {0:x} {0} {1}" -> [(0, Display), (0, LowerHex), (1, Display)]
+ let mut argmap = FxIndexSet::default();
+ for piece in fmt.template.iter() {
+ let FormatArgsPiece::Placeholder(placeholder) = piece else { continue };
+ if let Ok(index) = placeholder.argument.index {
+ argmap.insert((index, ArgumentType::Format(placeholder.format_trait)));
+ }
+ }
+
+ let lit_pieces =
+ fmt.template
+ .iter()
+ .enumerate()
+ .filter_map(|(i, piece)| {
+ match piece {
+ FormatArgsPiece::Literal(s) => Some(
+ self.alloc_expr_desugared(Expr::Literal(Literal::String(s.clone()))),
+ ),
+ &FormatArgsPiece::Placeholder(_) => {
+ // Inject empty string before placeholders when not already preceded by a literal piece.
+ if i == 0
+ || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_))
+ {
+ Some(self.alloc_expr_desugared(Expr::Literal(Literal::String(
+ "".into(),
+ ))))
+ } else {
+ None
+ }
+ }
+ }
+ })
+ .collect();
+ let lit_pieces = self.alloc_expr_desugared(Expr::Array(Array::ElementList {
+ elements: lit_pieces,
+ is_assignee_expr: false,
+ }));
+ let lit_pieces = self.alloc_expr_desugared(Expr::Ref {
+ expr: lit_pieces,
+ rawness: Rawness::Ref,
+ mutability: Mutability::Shared,
+ });
+ let format_options = {
+ // Generate:
+ // &[format_spec_0, format_spec_1, format_spec_2]
+ let elements = fmt
+ .template
+ .iter()
+ .filter_map(|piece| {
+ let FormatArgsPiece::Placeholder(placeholder) = piece else { return None };
+ Some(self.make_format_spec(placeholder, &mut argmap))
+ })
+ .collect();
+ let array = self.alloc_expr_desugared(Expr::Array(Array::ElementList {
+ elements,
+ is_assignee_expr: false,
+ }));
+ self.alloc_expr_desugared(Expr::Ref {
+ expr: array,
+ rawness: Rawness::Ref,
+ mutability: Mutability::Shared,
+ })
+ };
+ let arguments = &*fmt.arguments.arguments;
+
+ let args = if arguments.is_empty() {
+ let expr = self.alloc_expr_desugared(Expr::Array(Array::ElementList {
+ elements: Box::default(),
+ is_assignee_expr: false,
+ }));
+ self.alloc_expr_desugared(Expr::Ref {
+ expr,
+ rawness: Rawness::Ref,
+ mutability: Mutability::Shared,
+ })
+ } else {
+ // Generate:
+ // &match (&arg0, &arg1, &…) {
+ // args => [
+ // <core::fmt::Argument>::new_display(args.0),
+ // <core::fmt::Argument>::new_lower_hex(args.1),
+ // <core::fmt::Argument>::new_debug(args.0),
+ // …
+ // ]
+ // }
+ let args = argmap
+ .iter()
+ .map(|&(arg_index, ty)| {
+ let arg = self.alloc_expr_desugared(Expr::Ref {
+ expr: arguments[arg_index].expr,
+ rawness: Rawness::Ref,
+ mutability: Mutability::Shared,
+ });
+ self.make_argument(arg, ty)
+ })
+ .collect();
+ let array = self.alloc_expr_desugared(Expr::Array(Array::ElementList {
+ elements: args,
+ is_assignee_expr: false,
+ }));
+ self.alloc_expr_desugared(Expr::Ref {
+ expr: array,
+ rawness: Rawness::Ref,
+ mutability: Mutability::Shared,
+ })
+ };
+
+ // Generate:
+ // <core::fmt::Arguments>::new_v1_formatted(
+ // lit_pieces,
+ // args,
+ // format_options,
+ // unsafe { ::core::fmt::UnsafeArg::new() }
+ // )
+
+ let Some(new_v1_formatted) =
+ LangItem::FormatArguments.ty_rel_path(self.db, self.krate, name![new_v1_formatted])
+ else {
+ return self.missing_expr();
+ };
+ let Some(unsafe_arg_new) =
+ LangItem::FormatUnsafeArg.ty_rel_path(self.db, self.krate, name![new])
+ else {
+ return self.missing_expr();
+ };
+ let new_v1_formatted = self.alloc_expr_desugared(Expr::Path(new_v1_formatted));
+
+ let unsafe_arg_new = self.alloc_expr_desugared(Expr::Path(unsafe_arg_new));
+ let unsafe_arg_new = self.alloc_expr_desugared(Expr::Call {
+ callee: unsafe_arg_new,
+ args: Box::default(),
+ is_assignee_expr: false,
+ });
+ let unsafe_arg_new = self.alloc_expr_desugared(Expr::Unsafe {
+ id: None,
+ statements: Box::default(),
+ tail: Some(unsafe_arg_new),
+ });
+
+ self.alloc_expr(
+ Expr::Call {
+ callee: new_v1_formatted,
+ args: Box::new([lit_pieces, args, format_options, unsafe_arg_new]),
+ is_assignee_expr: false,
+ },
+ syntax_ptr,
+ )
+ }
+
+ /// Generate a hir expression for a format_args placeholder specification.
+ ///
+ /// Generates
+ ///
+ /// ```text
+ /// <core::fmt::rt::Placeholder::new(
+ /// …usize, // position
+ /// '…', // fill
+ /// <core::fmt::rt::Alignment>::…, // alignment
+ /// …u32, // flags
+ /// <core::fmt::rt::Count::…>, // width
+ /// <core::fmt::rt::Count::…>, // precision
+ /// )
+ /// ```
+ fn make_format_spec(
+ &mut self,
+ placeholder: &FormatPlaceholder,
+ argmap: &mut FxIndexSet<(usize, ArgumentType)>,
+ ) -> ExprId {
+ let position = match placeholder.argument.index {
+ Ok(arg_index) => {
+ let (i, _) =
+ argmap.insert_full((arg_index, ArgumentType::Format(placeholder.format_trait)));
+ self.alloc_expr_desugared(Expr::Literal(Literal::Uint(
+ i as u128,
+ Some(BuiltinUint::Usize),
+ )))
+ }
+ Err(_) => self.missing_expr(),
+ };
+ let &FormatOptions {
+ ref width,
+ ref precision,
+ alignment,
+ fill,
+ sign,
+ alternate,
+ zero_pad,
+ debug_hex,
+ } = &placeholder.format_options;
+ let fill = self.alloc_expr_desugared(Expr::Literal(Literal::Char(fill.unwrap_or(' '))));
+
+ let align = {
+ let align = LangItem::FormatAlignment.ty_rel_path(
+ self.db,
+ self.krate,
+ match alignment {
+ Some(FormatAlignment::Left) => name![Left],
+ Some(FormatAlignment::Right) => name![Right],
+ Some(FormatAlignment::Center) => name![Center],
+ None => name![Unknown],
+ },
+ );
+ match align {
+ Some(path) => self.alloc_expr_desugared(Expr::Path(path)),
+ None => self.missing_expr(),
+ }
+ };
+ // This needs to match `Flag` in library/core/src/fmt/rt.rs.
+ let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32)
+ | ((sign == Some(FormatSign::Minus)) as u32) << 1
+ | (alternate as u32) << 2
+ | (zero_pad as u32) << 3
+ | ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4
+ | ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5;
+ let flags = self.alloc_expr_desugared(Expr::Literal(Literal::Uint(
+ flags as u128,
+ Some(BuiltinUint::U32),
+ )));
+ let precision = self.make_count(&precision, argmap);
+ let width = self.make_count(&width, argmap);
+
+ let format_placeholder_new = {
+ let format_placeholder_new =
+ LangItem::FormatPlaceholder.ty_rel_path(self.db, self.krate, name![new]);
+ match format_placeholder_new {
+ Some(path) => self.alloc_expr_desugared(Expr::Path(path)),
+ None => self.missing_expr(),
+ }
+ };
+
+ self.alloc_expr_desugared(Expr::Call {
+ callee: format_placeholder_new,
+ args: Box::new([position, fill, align, flags, precision, width]),
+ is_assignee_expr: false,
+ })
+ }
+
+ /// Generate a hir expression for a format_args Count.
+ ///
+ /// Generates:
+ ///
+ /// ```text
+ /// <core::fmt::rt::Count>::Is(…)
+ /// ```
+ ///
+ /// or
+ ///
+ /// ```text
+ /// <core::fmt::rt::Count>::Param(…)
+ /// ```
+ ///
+ /// or
+ ///
+ /// ```text
+ /// <core::fmt::rt::Count>::Implied
+ /// ```
+ fn make_count(
+ &mut self,
+ count: &Option<FormatCount>,
+ argmap: &mut FxIndexSet<(usize, ArgumentType)>,
+ ) -> ExprId {
+ match count {
+ Some(FormatCount::Literal(n)) => {
+ match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Is]) {
+ Some(count_is) => {
+ let count_is = self.alloc_expr_desugared(Expr::Path(count_is));
+ let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint(
+ *n as u128,
+ Some(BuiltinUint::Usize),
+ )));
+ self.alloc_expr_desugared(Expr::Call {
+ callee: count_is,
+ args: Box::new([args]),
+ is_assignee_expr: false,
+ })
+ }
+ None => self.missing_expr(),
+ }
+ }
+ Some(FormatCount::Argument(arg)) => {
+ if let Ok(arg_index) = arg.index {
+ let (i, _) = argmap.insert_full((arg_index, ArgumentType::Usize));
+
+ match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Param]) {
+ Some(count_param) => {
+ let count_param = self.alloc_expr_desugared(Expr::Path(count_param));
+ let args = self.alloc_expr_desugared(Expr::Literal(Literal::Uint(
+ i as u128,
+ Some(BuiltinUint::Usize),
+ )));
+ self.alloc_expr_desugared(Expr::Call {
+ callee: count_param,
+ args: Box::new([args]),
+ is_assignee_expr: false,
+ })
+ }
+ None => self.missing_expr(),
+ }
+ } else {
+ self.missing_expr()
+ }
+ }
+ None => match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Implied]) {
+ Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)),
+ None => self.missing_expr(),
+ },
+ }
+ }
+
+ /// Generate a hir expression representing an argument to a format_args invocation.
+ ///
+ /// Generates:
+ ///
+ /// ```text
+ /// <core::fmt::Argument>::new_…(arg)
+ /// ```
+ fn make_argument(&mut self, arg: ExprId, ty: ArgumentType) -> ExprId {
+ use ArgumentType::*;
+ use FormatTrait::*;
+ match LangItem::FormatArgument.ty_rel_path(
+ self.db,
+ self.krate,
+ match ty {
+ Format(Display) => name![new_display],
+ Format(Debug) => name![new_debug],
+ Format(LowerExp) => name![new_lower_exp],
+ Format(UpperExp) => name![new_upper_exp],
+ Format(Octal) => name![new_octal],
+ Format(Pointer) => name![new_pointer],
+ Format(Binary) => name![new_binary],
+ Format(LowerHex) => name![new_lower_hex],
+ Format(UpperHex) => name![new_upper_hex],
+ Usize => name![from_usize],
+ },
+ ) {
+ Some(new_fn) => {
+ let new_fn = self.alloc_expr_desugared(Expr::Path(new_fn));
+ self.alloc_expr_desugared(Expr::Call {
+ callee: new_fn,
+ args: Box::new([arg]),
+ is_assignee_expr: false,
+ })
+ }
+ None => self.missing_expr(),
+ }
+ }
+ // endregion: format
}
fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)> {
@@ -1601,3 +2033,9 @@ fn comma_follows_token(t: Option<syntax::SyntaxToken>) -> bool {
(|| syntax::algo::skip_trivia_token(t?.next_token()?, syntax::Direction::Next))()
.map_or(false, |it| it.kind() == syntax::T![,])
}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+enum ArgumentType {
+ Format(FormatTrait),
+ Usize,
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
index 5d71abe37..fad4d7a4d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
@@ -2,7 +2,7 @@
use std::fmt::{self, Write};
-use hir_expand::db::ExpandDatabase;
+use itertools::Itertools;
use syntax::ast::HasName;
use crate::{
@@ -51,8 +51,7 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
}
};
- let mut p =
- Printer { db: db.upcast(), body, buf: header, indent_level: 0, needs_indent: false };
+ let mut p = Printer { db, body, buf: header, indent_level: 0, needs_indent: false };
if let DefWithBodyId::FunctionId(it) = owner {
p.buf.push('(');
body.params.iter().zip(&db.function_data(it).params).for_each(|(&param, ty)| {
@@ -76,8 +75,7 @@ pub(super) fn print_expr_hir(
_owner: DefWithBodyId,
expr: ExprId,
) -> String {
- let mut p =
- Printer { db: db.upcast(), body, buf: String::new(), indent_level: 0, needs_indent: false };
+ let mut p = Printer { db, body, buf: String::new(), indent_level: 0, needs_indent: false };
p.print_expr(expr);
p.buf
}
@@ -98,7 +96,7 @@ macro_rules! wln {
}
struct Printer<'a> {
- db: &'a dyn ExpandDatabase,
+ db: &'a dyn DefDatabase,
body: &'a Body,
buf: String,
indent_level: usize,
@@ -142,9 +140,14 @@ impl Printer<'_> {
}
fn newline(&mut self) {
- match self.buf.chars().rev().find(|ch| *ch != ' ') {
- Some('\n') | None => {}
- _ => writeln!(self).unwrap(),
+ match self.buf.chars().rev().find_position(|ch| *ch != ' ') {
+ Some((_, '\n')) | None => {}
+ Some((idx, _)) => {
+ if idx != 0 {
+ self.buf.drain(self.buf.len() - idx..);
+ }
+ writeln!(self).unwrap()
+ }
}
}
@@ -154,6 +157,19 @@ impl Printer<'_> {
match expr {
Expr::Missing => w!(self, "�"),
Expr::Underscore => w!(self, "_"),
+ Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
+ Expr::OffsetOf(offset_of) => {
+ w!(self, "builtin#offset_of(");
+ self.print_type_ref(&offset_of.container);
+ w!(
+ self,
+ ", {})",
+ offset_of
+ .fields
+ .iter()
+ .format_with(".", |field, f| f(&field.display(self.db.upcast())))
+ );
+ }
Expr::Path(path) => self.print_path(path),
Expr::If { condition, then_branch, else_branch } => {
w!(self, "if ");
@@ -173,7 +189,7 @@ impl Printer<'_> {
}
Expr::Loop { body, label } => {
if let Some(lbl) = label {
- w!(self, "{}: ", self.body[*lbl].name.display(self.db));
+ w!(self, "{}: ", self.body[*lbl].name.display(self.db.upcast()));
}
w!(self, "loop ");
self.print_expr(*body);
@@ -193,7 +209,7 @@ impl Printer<'_> {
}
Expr::MethodCall { receiver, method_name, args, generic_args } => {
self.print_expr(*receiver);
- w!(self, ".{}", method_name.display(self.db));
+ w!(self, ".{}", method_name.display(self.db.upcast()));
if let Some(args) = generic_args {
w!(self, "::<");
print_generic_args(self.db, args, self).unwrap();
@@ -231,13 +247,13 @@ impl Printer<'_> {
Expr::Continue { label } => {
w!(self, "continue");
if let Some(lbl) = label {
- w!(self, " {}", self.body[*lbl].name.display(self.db));
+ w!(self, " {}", self.body[*lbl].name.display(self.db.upcast()));
}
}
Expr::Break { expr, label } => {
w!(self, "break");
if let Some(lbl) = label {
- w!(self, " {}", self.body[*lbl].name.display(self.db));
+ w!(self, " {}", self.body[*lbl].name.display(self.db.upcast()));
}
if let Some(expr) = expr {
self.whitespace();
@@ -276,7 +292,7 @@ impl Printer<'_> {
w!(self, "{{");
self.indented(|p| {
for field in &**fields {
- w!(p, "{}: ", field.name.display(self.db));
+ w!(p, "{}: ", field.name.display(self.db.upcast()));
p.print_expr(field.expr);
wln!(p, ",");
}
@@ -293,7 +309,7 @@ impl Printer<'_> {
}
Expr::Field { expr, name } => {
self.print_expr(*expr);
- w!(self, ".{}", name.display(self.db));
+ w!(self, ".{}", name.display(self.db.upcast()));
}
Expr::Await { expr } => {
self.print_expr(*expr);
@@ -431,7 +447,8 @@ impl Printer<'_> {
}
Expr::Literal(lit) => self.print_literal(lit),
Expr::Block { id: _, statements, tail, label } => {
- let label = label.map(|lbl| format!("{}: ", self.body[lbl].name.display(self.db)));
+ let label =
+ label.map(|lbl| format!("{}: ", self.body[lbl].name.display(self.db.upcast())));
self.print_block(label.as_deref(), statements, tail);
}
Expr::Unsafe { id: _, statements, tail } => {
@@ -507,7 +524,7 @@ impl Printer<'_> {
w!(self, " {{");
self.indented(|p| {
for arg in args.iter() {
- w!(p, "{}: ", arg.name.display(self.db));
+ w!(p, "{}: ", arg.name.display(self.db.upcast()));
p.print_pat(arg.pat);
wln!(p, ",");
}
@@ -666,6 +683,6 @@ impl Printer<'_> {
BindingAnnotation::Ref => "ref ",
BindingAnnotation::RefMut => "ref mut ",
};
- w!(self, "{}{}", mode, name.display(self.db));
+ w!(self, "{}{}", mode, name.display(self.db.upcast()));
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs
index d55820116..1658757d2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs
@@ -1,13 +1,13 @@
mod block;
use base_db::{fixture::WithFixture, SourceDatabase};
-use expect_test::Expect;
+use expect_test::{expect, Expect};
use crate::{test_db::TestDB, ModuleDefId};
use super::*;
-fn lower(ra_fixture: &str) -> Arc<Body> {
+fn lower(ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) {
let db = TestDB::with_files(ra_fixture);
let krate = db.crate_graph().iter().next().unwrap();
@@ -21,8 +21,10 @@ fn lower(ra_fixture: &str) -> Arc<Body> {
}
}
}
+ let fn_def = fn_def.unwrap().into();
- db.body(fn_def.unwrap().into())
+ let body = db.body(fn_def);
+ (db, body, fn_def)
}
fn def_map_at(ra_fixture: &str) -> String {
@@ -138,3 +140,84 @@ mod m {
"#,
);
}
+
+#[test]
+fn desugar_builtin_format_args() {
+ // Regression test for a path resolution bug introduced with inner item handling.
+ let (db, body, def) = lower(
+ r#"
+//- minicore: fmt
+fn main() {
+ let are = "are";
+ let count = 10;
+ builtin#format_args("hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!");
+}
+"#,
+ );
+
+ expect![[r#"
+ fn main() {
+ let are = "are";
+ let count = 10;
+ builtin#lang(Arguments::new_v1_formatted)(
+ &[
+ "\"hello ", " ", " friends, we ", " ", "", "\"",
+ ],
+ &[
+ builtin#lang(Argument::new_display)(
+ &count,
+ ), builtin#lang(Argument::new_display)(
+ &"fancy",
+ ), builtin#lang(Argument::new_debug)(
+ &are,
+ ), builtin#lang(Argument::new_display)(
+ &"!",
+ ),
+ ],
+ &[
+ builtin#lang(Placeholder::new)(
+ 0usize,
+ ' ',
+ builtin#lang(Alignment::Unknown),
+ 8u32,
+ builtin#lang(Count::Implied),
+ builtin#lang(Count::Is)(
+ 2usize,
+ ),
+ ), builtin#lang(Placeholder::new)(
+ 1usize,
+ ' ',
+ builtin#lang(Alignment::Unknown),
+ 0u32,
+ builtin#lang(Count::Implied),
+ builtin#lang(Count::Implied),
+ ), builtin#lang(Placeholder::new)(
+ 2usize,
+ ' ',
+ builtin#lang(Alignment::Unknown),
+ 0u32,
+ builtin#lang(Count::Implied),
+ builtin#lang(Count::Implied),
+ ), builtin#lang(Placeholder::new)(
+ 1usize,
+ ' ',
+ builtin#lang(Alignment::Unknown),
+ 0u32,
+ builtin#lang(Count::Implied),
+ builtin#lang(Count::Implied),
+ ), builtin#lang(Placeholder::new)(
+ 3usize,
+ ' ',
+ builtin#lang(Alignment::Unknown),
+ 0u32,
+ builtin#lang(Count::Implied),
+ builtin#lang(Count::Implied),
+ ),
+ ],
+ unsafe {
+ builtin#lang(UnsafeArg::new)()
+ },
+ );
+ }"#]]
+ .assert_eq(&body.pretty_print(&db, def))
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs
index 4e015a7fb..44eeed9e3 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs
@@ -38,9 +38,9 @@ fn outer() {
"#,
expect![[r#"
block scope
- CrateStruct: t
- PlainStruct: t v
- SelfStruct: t
+ CrateStruct: ti
+ PlainStruct: ti vi
+ SelfStruct: ti
Struct: v
SuperStruct: _
@@ -66,7 +66,7 @@ fn outer() {
"#,
expect![[r#"
block scope
- imported: t v
+ imported: ti vi
name: v
crate
@@ -92,9 +92,9 @@ fn outer() {
"#,
expect![[r#"
block scope
- inner1: t
+ inner1: ti
inner2: v
- outer: v
+ outer: vi
block scope
inner: v
@@ -121,7 +121,7 @@ struct Struct {}
"#,
expect![[r#"
block scope
- Struct: t
+ Struct: ti
crate
Struct: t
@@ -153,7 +153,7 @@ fn outer() {
"#,
expect![[r#"
block scope
- ResolveMe: t
+ ResolveMe: ti
block scope
m2: t
@@ -214,7 +214,7 @@ fn f() {
"#,
expect![[r#"
block scope
- ResolveMe: t
+ ResolveMe: ti
block scope
h: v
@@ -292,7 +292,7 @@ pub mod cov_mark {
nested: v
crate
- cov_mark: t
+ cov_mark: ti
f: v
"#]],
);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 91db68058..68defa385 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -487,7 +487,7 @@ impl ExternCrateDeclData {
db.crate_def_map(loc.container.krate())
.extern_prelude()
.find(|&(prelude_name, ..)| *prelude_name == name)
- .map(|(_, root)| root.krate())
+ .map(|(_, (root, _))| root.krate())
};
Arc::new(Self {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
index c8df3f3f9..224f7328f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
@@ -447,6 +447,7 @@ impl VariantData {
}
}
+ // FIXME: Linear lookup
pub fn field(&self, name: &Name) -> Option<LocalFieldId> {
self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None })
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index e34a6768f..31c1a7130 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -82,6 +82,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
#[salsa::invoke(ItemTree::file_item_tree_query)]
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
+ #[salsa::invoke(ItemTree::block_item_tree_query)]
+ fn block_item_tree_query(&self, block_id: BlockId) -> Arc<ItemTree>;
+
#[salsa::invoke(crate_def_map_wait)]
#[salsa::transparent]
fn crate_def_map(&self, krate: CrateId) -> Arc<DefMap>;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
index df2af4c89..b9c5ff727 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
@@ -11,7 +11,7 @@ use crate::{
nameres::DefMap,
path::{ModPath, PathKind},
visibility::Visibility,
- ModuleDefId, ModuleId,
+ CrateRootModuleId, ModuleDefId, ModuleId,
};
/// Find a path that can be used to refer to a certain item. This can depend on
@@ -37,6 +37,20 @@ pub fn find_path_prefixed(
find_path_inner(db, item, from, Some(prefix_kind), prefer_no_std)
}
+#[derive(Copy, Clone, Debug)]
+enum Stability {
+ Unstable,
+ Stable,
+}
+use Stability::*;
+
+fn zip_stability(a: Stability, b: Stability) -> Stability {
+ match (a, b) {
+ (Stable, Stable) => Stable,
+ _ => Unstable,
+ }
+}
+
const MAX_PATH_LEN: usize = 15;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -81,7 +95,7 @@ fn find_path_inner(
}
let def_map = from.def_map(db);
- let crate_root = def_map.crate_root().into();
+ let crate_root = def_map.crate_root();
// - if the item is a module, jump straight to module search
if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
let mut visited_modules = FxHashSet::default();
@@ -95,7 +109,8 @@ fn find_path_inner(
MAX_PATH_LEN,
prefixed,
prefer_no_std || db.crate_supports_no_std(crate_root.krate),
- );
+ )
+ .map(|(item, _)| item);
}
// - if the item is already in scope, return the name under which it is
@@ -143,19 +158,20 @@ fn find_path_inner(
prefer_no_std || db.crate_supports_no_std(crate_root.krate),
scope_name,
)
+ .map(|(item, _)| item)
}
fn find_path_for_module(
db: &dyn DefDatabase,
def_map: &DefMap,
visited_modules: &mut FxHashSet<ModuleId>,
- crate_root: ModuleId,
+ crate_root: CrateRootModuleId,
from: ModuleId,
module_id: ModuleId,
max_len: usize,
prefixed: Option<PrefixKind>,
prefer_no_std: bool,
-) -> Option<ModPath> {
+) -> Option<(ModPath, Stability)> {
if max_len == 0 {
return None;
}
@@ -165,25 +181,25 @@ fn find_path_for_module(
let scope_name = find_in_scope(db, def_map, from, ItemInNs::Types(module_id.into()));
if prefixed.is_none() {
if let Some(scope_name) = scope_name {
- return Some(ModPath::from_segments(PathKind::Plain, Some(scope_name)));
+ return Some((ModPath::from_segments(PathKind::Plain, Some(scope_name)), Stable));
}
}
// - if the item is the crate root, return `crate`
if module_id == crate_root {
- return Some(ModPath::from_segments(PathKind::Crate, None));
+ return Some((ModPath::from_segments(PathKind::Crate, None), Stable));
}
// - if relative paths are fine, check if we are searching for a parent
if prefixed.filter(PrefixKind::is_absolute).is_none() {
if let modpath @ Some(_) = find_self_super(def_map, module_id, from) {
- return modpath;
+ return modpath.zip(Some(Stable));
}
}
// - if the item is the crate root of a dependency crate, return the name from the extern prelude
let root_def_map = crate_root.def_map(db);
- for (name, def_id) in root_def_map.extern_prelude() {
+ for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude() {
if module_id == def_id {
let name = scope_name.unwrap_or_else(|| name.clone());
@@ -192,7 +208,7 @@ fn find_path_for_module(
def_map[local_id]
.scope
.type_(&name)
- .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id))
+ .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into()))
})
.is_some();
let kind = if name_already_occupied_in_type_ns {
@@ -201,14 +217,14 @@ fn find_path_for_module(
} else {
PathKind::Plain
};
- return Some(ModPath::from_segments(kind, Some(name)));
+ return Some((ModPath::from_segments(kind, Some(name)), Stable));
}
}
if let value @ Some(_) =
find_in_prelude(db, &root_def_map, &def_map, ItemInNs::Types(module_id.into()), from)
{
- return value;
+ return value.zip(Some(Stable));
}
calculate_best_path(
db,
@@ -224,6 +240,7 @@ fn find_path_for_module(
)
}
+// FIXME: Do we still need this now that we record import origins, and hence aliases?
fn find_in_scope(
db: &dyn DefDatabase,
def_map: &DefMap,
@@ -244,7 +261,7 @@ fn find_in_prelude(
item: ItemInNs,
from: ModuleId,
) -> Option<ModPath> {
- let prelude_module = root_def_map.prelude()?;
+ let (prelude_module, _) = root_def_map.prelude()?;
// Preludes in block DefMaps are ignored, only the crate DefMap is searched
let prelude_def_map = prelude_module.def_map(db);
let prelude_scope = &prelude_def_map[prelude_module.local_id].scope;
@@ -293,18 +310,26 @@ fn calculate_best_path(
db: &dyn DefDatabase,
def_map: &DefMap,
visited_modules: &mut FxHashSet<ModuleId>,
- crate_root: ModuleId,
+ crate_root: CrateRootModuleId,
max_len: usize,
item: ItemInNs,
from: ModuleId,
mut prefixed: Option<PrefixKind>,
prefer_no_std: bool,
scope_name: Option<Name>,
-) -> Option<ModPath> {
+) -> Option<(ModPath, Stability)> {
if max_len <= 1 {
return None;
}
let mut best_path = None;
+ let update_best_path =
+ |best_path: &mut Option<_>, new_path: (ModPath, Stability)| match best_path {
+ Some((old_path, old_stability)) => {
+ *old_path = new_path.0;
+ *old_stability = zip_stability(*old_stability, new_path.1);
+ }
+ None => *best_path = Some(new_path),
+ };
// Recursive case:
// - otherwise, look for modules containing (reexporting) it and import it from one of those
if item.krate(db) == Some(from.krate) {
@@ -327,14 +352,14 @@ fn calculate_best_path(
prefixed,
prefer_no_std,
) {
- path.push_segment(name);
+ path.0.push_segment(name);
- let new_path = match best_path {
+ let new_path = match best_path.take() {
Some(best_path) => select_best_path(best_path, path, prefer_no_std),
None => path,
};
- best_path_len = new_path.len();
- best_path = Some(new_path);
+ best_path_len = new_path.0.len();
+ update_best_path(&mut best_path, new_path);
}
}
} else {
@@ -346,9 +371,14 @@ fn calculate_best_path(
let extern_paths = crate_graph[from.krate].dependencies.iter().filter_map(|dep| {
let import_map = db.import_map(dep.crate_id);
import_map.import_info_for(item).and_then(|info| {
+ if info.is_doc_hidden {
+ // the item or import is `#[doc(hidden)]`, so skip it as it is in an external crate
+ return None;
+ }
+
// Determine best path for containing module and append last segment from `info`.
// FIXME: we should guide this to look up the path locally, or from the same crate again?
- let mut path = find_path_for_module(
+ let (mut path, path_stability) = find_path_for_module(
db,
def_map,
visited_modules,
@@ -361,16 +391,19 @@ fn calculate_best_path(
)?;
cov_mark::hit!(partially_imported);
path.push_segment(info.name.clone());
- Some(path)
+ Some((
+ path,
+ zip_stability(path_stability, if info.is_unstable { Unstable } else { Stable }),
+ ))
})
});
for path in extern_paths {
- let new_path = match best_path {
+ let new_path = match best_path.take() {
Some(best_path) => select_best_path(best_path, path, prefer_no_std),
None => path,
};
- best_path = Some(new_path);
+ update_best_path(&mut best_path, new_path);
}
}
if let Some(module) = item.module(db) {
@@ -381,15 +414,24 @@ fn calculate_best_path(
}
match prefixed.map(PrefixKind::prefix) {
Some(prefix) => best_path.or_else(|| {
- scope_name.map(|scope_name| ModPath::from_segments(prefix, Some(scope_name)))
+ scope_name.map(|scope_name| (ModPath::from_segments(prefix, Some(scope_name)), Stable))
}),
None => best_path,
}
}
-fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -> ModPath {
+fn select_best_path(
+ old_path: (ModPath, Stability),
+ new_path: (ModPath, Stability),
+ prefer_no_std: bool,
+) -> (ModPath, Stability) {
+ match (old_path.1, new_path.1) {
+ (Stable, Unstable) => return old_path,
+ (Unstable, Stable) => return new_path,
+ _ => {}
+ }
const STD_CRATES: [Name; 3] = [known::std, known::core, known::alloc];
- match (old_path.segments().first(), new_path.segments().first()) {
+ match (old_path.0.segments().first(), new_path.0.segments().first()) {
(Some(old), Some(new)) if STD_CRATES.contains(old) && STD_CRATES.contains(new) => {
let rank = match prefer_no_std {
false => |name: &Name| match name {
@@ -410,7 +452,7 @@ fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -
match nrank.cmp(&orank) {
Ordering::Less => old_path,
Ordering::Equal => {
- if new_path.len() < old_path.len() {
+ if new_path.0.len() < old_path.0.len() {
new_path
} else {
old_path
@@ -420,7 +462,7 @@ fn select_best_path(old_path: ModPath, new_path: ModPath, prefer_no_std: bool) -
}
}
_ => {
- if new_path.len() < old_path.len() {
+ if new_path.0.len() < old_path.0.len() {
new_path
} else {
old_path
@@ -1293,4 +1335,90 @@ pub mod prelude {
"None",
);
}
+
+ #[test]
+ fn different_crate_renamed_through_dep() {
+ check_found_path(
+ r#"
+//- /main.rs crate:main deps:intermediate
+$0
+//- /intermediate.rs crate:intermediate deps:std
+pub extern crate std as std_renamed;
+//- /std.rs crate:std
+pub struct S;
+ "#,
+ "intermediate::std_renamed::S",
+ "intermediate::std_renamed::S",
+ "intermediate::std_renamed::S",
+ "intermediate::std_renamed::S",
+ );
+ }
+
+ #[test]
+ fn different_crate_doc_hidden() {
+ check_found_path(
+ r#"
+//- /main.rs crate:main deps:intermediate
+$0
+//- /intermediate.rs crate:intermediate deps:std
+#[doc(hidden)]
+pub extern crate std;
+pub extern crate std as longer;
+//- /std.rs crate:std
+pub struct S;
+ "#,
+ "intermediate::longer::S",
+ "intermediate::longer::S",
+ "intermediate::longer::S",
+ "intermediate::longer::S",
+ );
+ }
+
+ #[test]
+ fn respect_doc_hidden() {
+ check_found_path(
+ r#"
+//- /main.rs crate:main deps:std,lazy_static
+$0
+//- /lazy_static.rs crate:lazy_static deps:core
+#[doc(hidden)]
+pub use core::ops::Deref as __Deref;
+//- /std.rs crate:std deps:core
+pub use core::ops;
+//- /core.rs crate:core
+pub mod ops {
+ pub trait Deref {}
+}
+ "#,
+ "std::ops::Deref",
+ "std::ops::Deref",
+ "std::ops::Deref",
+ "std::ops::Deref",
+ );
+ }
+
+ #[test]
+ fn respect_unstable_modules() {
+ check_found_path(
+ r#"
+//- /main.rs crate:main deps:std,core
+#![no_std]
+extern crate std;
+$0
+//- /longer.rs crate:std deps:core
+pub mod error {
+ pub use core::error::Error;
+}
+//- /core.rs crate:core
+pub mod error {
+ #![unstable(feature = "error_in_core", issue = "103765")]
+ pub trait Error {}
+}
+"#,
+ "std::error::Error",
+ "std::error::Error",
+ "std::error::Error",
+ "std::error::Error",
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
index d7d44e413..1e2535a8a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
@@ -21,10 +21,11 @@ use crate::{
db::DefDatabase,
dyn_map::{keys, DynMap},
expander::Expander,
+ item_tree::{AttrOwner, ItemTree},
lower::LowerCtx,
nameres::{DefMap, MacroSubNs},
src::{HasChildSource, HasSource},
- type_ref::{LifetimeRef, TypeBound, TypeRef},
+ type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
AdtId, ConstParamId, GenericDefId, HasModule, LifetimeParamId, LocalLifetimeParamId,
LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
};
@@ -48,7 +49,7 @@ pub struct LifetimeParamData {
pub struct ConstParamData {
pub name: Name,
pub ty: Interned<TypeRef>,
- pub has_default: bool,
+ pub default: Option<ConstRef>,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
@@ -75,7 +76,7 @@ impl TypeOrConstParamData {
pub fn has_default(&self) -> bool {
match self {
TypeOrConstParamData::TypeParamData(it) => it.default.is_some(),
- TypeOrConstParamData::ConstParamData(it) => it.has_default,
+ TypeOrConstParamData::ConstParamData(it) => it.default.is_some(),
}
}
@@ -154,12 +155,58 @@ impl GenericParams {
def: GenericDefId,
) -> Interned<GenericParams> {
let _p = profile::span("generic_params_query");
+
+ let krate = def.module(db).krate;
+ let cfg_options = db.crate_graph();
+ let cfg_options = &cfg_options[krate].cfg_options;
+
+ // Returns the generic parameters that are enabled under the current `#[cfg]` options
+ let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
+ let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
+
+ // In the common case, no parameters will by disabled by `#[cfg]` attributes.
+ // Therefore, make a first pass to check if all parameters are enabled and, if so,
+ // clone the `Interned<GenericParams>` instead of recreating an identical copy.
+ let all_type_or_consts_enabled =
+ params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
+ let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));
+
+ if all_type_or_consts_enabled && all_lifetimes_enabled {
+ params.clone()
+ } else {
+ Interned::new(GenericParams {
+ type_or_consts: all_type_or_consts_enabled
+ .then(|| params.type_or_consts.clone())
+ .unwrap_or_else(|| {
+ params
+ .type_or_consts
+ .iter()
+ .filter_map(|(idx, param)| {
+ enabled(idx.into()).then(|| param.clone())
+ })
+ .collect()
+ }),
+ lifetimes: all_lifetimes_enabled
+ .then(|| params.lifetimes.clone())
+ .unwrap_or_else(|| {
+ params
+ .lifetimes
+ .iter()
+ .filter_map(|(idx, param)| {
+ enabled(idx.into()).then(|| param.clone())
+ })
+ .collect()
+ }),
+ where_predicates: params.where_predicates.clone(),
+ })
+ }
+ };
macro_rules! id_to_generics {
($id:ident) => {{
let id = $id.lookup(db).id;
let tree = id.item_tree(db);
let item = &tree[id.value];
- item.generic_params.clone()
+ enabled_params(&item.generic_params, &tree)
}};
}
@@ -169,7 +216,8 @@ impl GenericParams {
let tree = loc.id.item_tree(db);
let item = &tree[loc.id.value];
- let mut generic_params = GenericParams::clone(&item.explicit_generic_params);
+ let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
+ let mut generic_params = GenericParams::clone(&enabled_params);
let module = loc.container.module(db);
let func_data = db.function_data(id);
@@ -198,9 +246,14 @@ impl GenericParams {
}
}
- pub(crate) fn fill(&mut self, lower_ctx: &LowerCtx<'_>, node: &dyn HasGenericParams) {
+ pub(crate) fn fill(
+ &mut self,
+ lower_ctx: &LowerCtx<'_>,
+ node: &dyn HasGenericParams,
+ add_param_attrs: impl FnMut(AttrOwner, ast::GenericParam),
+ ) {
if let Some(params) = node.generic_param_list() {
- self.fill_params(lower_ctx, params)
+ self.fill_params(lower_ctx, params, add_param_attrs)
}
if let Some(where_clause) = node.where_clause() {
self.fill_where_predicates(lower_ctx, where_clause);
@@ -218,7 +271,12 @@ impl GenericParams {
}
}
- fn fill_params(&mut self, lower_ctx: &LowerCtx<'_>, params: ast::GenericParamList) {
+ fn fill_params(
+ &mut self,
+ lower_ctx: &LowerCtx<'_>,
+ params: ast::GenericParamList,
+ mut add_param_attrs: impl FnMut(AttrOwner, ast::GenericParam),
+ ) {
for type_or_const_param in params.type_or_const_params() {
match type_or_const_param {
ast::TypeOrConstParam::Type(type_param) => {
@@ -232,13 +290,14 @@ impl GenericParams {
default,
provenance: TypeParamProvenance::TypeParamList,
};
- self.type_or_consts.alloc(param.into());
+ let idx = self.type_or_consts.alloc(param.into());
let type_ref = TypeRef::Path(name.into());
self.fill_bounds(
lower_ctx,
type_param.type_bound_list(),
Either::Left(type_ref),
);
+ add_param_attrs(idx.into(), ast::GenericParam::TypeParam(type_param));
}
ast::TypeOrConstParam::Const(const_param) => {
let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
@@ -248,9 +307,10 @@ impl GenericParams {
let param = ConstParamData {
name,
ty: Interned::new(ty),
- has_default: const_param.default_val().is_some(),
+ default: ConstRef::from_const_param(lower_ctx, &const_param),
};
- self.type_or_consts.alloc(param.into());
+ let idx = self.type_or_consts.alloc(param.into());
+ add_param_attrs(idx.into(), ast::GenericParam::ConstParam(const_param));
}
}
}
@@ -258,13 +318,14 @@ impl GenericParams {
let name =
lifetime_param.lifetime().map_or_else(Name::missing, |lt| Name::new_lifetime(&lt));
let param = LifetimeParamData { name: name.clone() };
- self.lifetimes.alloc(param);
+ let idx = self.lifetimes.alloc(param);
let lifetime_ref = LifetimeRef::new_name(name);
self.fill_bounds(
lower_ctx,
lifetime_param.type_bound_list(),
Either::Right(lifetime_ref),
);
+ add_param_attrs(idx.into(), ast::GenericParam::LifetimeParam(lifetime_param));
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
index 6591c92ac..591ee77c7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir.rs
@@ -13,6 +13,7 @@
//! See also a neighboring `body` module.
pub mod type_ref;
+pub mod format_args;
use std::fmt;
@@ -117,7 +118,6 @@ impl From<ast::LiteralKind> for Literal {
fn from(ast_lit_kind: ast::LiteralKind) -> Self {
use ast::LiteralKind;
match ast_lit_kind {
- // FIXME: these should have actual values filled in, but unsure on perf impact
LiteralKind::IntNumber(lit) => {
if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
Literal::Float(
@@ -281,6 +281,19 @@ pub enum Expr {
Array(Array),
Literal(Literal),
Underscore,
+ OffsetOf(OffsetOf),
+ InlineAsm(InlineAsm),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct OffsetOf {
+ pub container: Interned<TypeRef>,
+ pub fields: Box<[Name]>,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct InlineAsm {
+ pub e: ExprId,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -341,7 +354,8 @@ impl Expr {
pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
match self {
Expr::Missing => {}
- Expr::Path(_) => {}
+ Expr::Path(_) | Expr::OffsetOf(_) => {}
+ Expr::InlineAsm(it) => f(it.e),
Expr::If { condition, then_branch, else_branch } => {
f(*condition);
f(*then_branch);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
new file mode 100644
index 000000000..75025a984
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs
@@ -0,0 +1,502 @@
+//! Parses `format_args` input.
+use std::mem;
+
+use hir_expand::name::Name;
+use rustc_parse_format as parse;
+use syntax::{
+ ast::{self, IsString},
+ AstToken, SmolStr, TextRange,
+};
+
+use crate::hir::ExprId;
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct FormatArgs {
+ pub template: Box<[FormatArgsPiece]>,
+ pub arguments: FormatArguments,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct FormatArguments {
+ pub arguments: Box<[FormatArgument]>,
+ pub num_unnamed_args: usize,
+ pub num_explicit_args: usize,
+ pub names: Box<[(Name, usize)]>,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum FormatArgsPiece {
+ Literal(Box<str>),
+ Placeholder(FormatPlaceholder),
+}
+
+#[derive(Copy, Debug, Clone, PartialEq, Eq)]
+pub struct FormatPlaceholder {
+ /// Index into [`FormatArgs::arguments`].
+ pub argument: FormatArgPosition,
+ /// The span inside the format string for the full `{…}` placeholder.
+ pub span: Option<TextRange>,
+ /// `{}`, `{:?}`, or `{:x}`, etc.
+ pub format_trait: FormatTrait,
+ /// `{}` or `{:.5}` or `{:-^20}`, etc.
+ pub format_options: FormatOptions,
+}
+
+#[derive(Copy, Debug, Clone, PartialEq, Eq)]
+pub struct FormatArgPosition {
+ /// Which argument this position refers to (Ok),
+ /// or would've referred to if it existed (Err).
+ pub index: Result<usize, usize>,
+ /// What kind of position this is. See [`FormatArgPositionKind`].
+ pub kind: FormatArgPositionKind,
+ /// The span of the name or number.
+ pub span: Option<TextRange>,
+}
+
+#[derive(Copy, Debug, Clone, PartialEq, Eq)]
+pub enum FormatArgPositionKind {
+ /// `{}` or `{:.*}`
+ Implicit,
+ /// `{1}` or `{:1$}` or `{:.1$}`
+ Number,
+ /// `{a}` or `{:a$}` or `{:.a$}`
+ Named,
+}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+pub enum FormatTrait {
+ /// `{}`
+ Display,
+ /// `{:?}`
+ Debug,
+ /// `{:e}`
+ LowerExp,
+ /// `{:E}`
+ UpperExp,
+ /// `{:o}`
+ Octal,
+ /// `{:p}`
+ Pointer,
+ /// `{:b}`
+ Binary,
+ /// `{:x}`
+ LowerHex,
+ /// `{:X}`
+ UpperHex,
+}
+
+#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
+pub struct FormatOptions {
+ /// The width. E.g. `{:5}` or `{:width$}`.
+ pub width: Option<FormatCount>,
+ /// The precision. E.g. `{:.5}` or `{:.precision$}`.
+ pub precision: Option<FormatCount>,
+ /// The alignment. E.g. `{:>}` or `{:<}` or `{:^}`.
+ pub alignment: Option<FormatAlignment>,
+ /// The fill character. E.g. the `.` in `{:.>10}`.
+ pub fill: Option<char>,
+ /// The `+` or `-` flag.
+ pub sign: Option<FormatSign>,
+ /// The `#` flag.
+ pub alternate: bool,
+ /// The `0` flag. E.g. the `0` in `{:02x}`.
+ pub zero_pad: bool,
+ /// The `x` or `X` flag (for `Debug` only). E.g. the `x` in `{:x?}`.
+ pub debug_hex: Option<FormatDebugHex>,
+}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum FormatSign {
+ /// The `+` flag.
+ Plus,
+ /// The `-` flag.
+ Minus,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum FormatDebugHex {
+ /// The `x` flag in `{:x?}`.
+ Lower,
+ /// The `X` flag in `{:X?}`.
+ Upper,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum FormatAlignment {
+ /// `{:<}`
+ Left,
+ /// `{:>}`
+ Right,
+ /// `{:^}`
+ Center,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum FormatCount {
+ /// `{:5}` or `{:.5}`
+ Literal(usize),
+ /// `{:.*}`, `{:.5$}`, or `{:a$}`, etc.
+ Argument(FormatArgPosition),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct FormatArgument {
+ pub kind: FormatArgumentKind,
+ pub expr: ExprId,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub enum FormatArgumentKind {
+ /// `format_args(…, arg)`
+ Normal,
+ /// `format_args(…, arg = 1)`
+ Named(Name),
+ /// `format_args("… {arg} …")`
+ Captured(Name),
+}
+
+// Only used in parse_args and report_invalid_references,
+// to indicate how a referred argument was used.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+enum PositionUsedAs {
+ Placeholder(Option<TextRange>),
+ Precision,
+ Width,
+}
+use PositionUsedAs::*;
+
+pub(crate) fn parse(
+ s: &ast::String,
+ fmt_snippet: Option<String>,
+ mut args: FormatArgumentsCollector,
+ is_direct_literal: bool,
+ mut synth: impl FnMut(Name) -> ExprId,
+) -> FormatArgs {
+ let text = s.text();
+ let str_style = match s.quote_offsets() {
+ Some(offsets) => {
+ let raw = u32::from(offsets.quotes.0.len()) - 1;
+ (raw != 0).then_some(raw as usize)
+ }
+ None => None,
+ };
+ let mut parser =
+ parse::Parser::new(text, str_style, fmt_snippet, false, parse::ParseMode::Format);
+
+ let mut pieces = Vec::new();
+ while let Some(piece) = parser.next() {
+ if !parser.errors.is_empty() {
+ break;
+ } else {
+ pieces.push(piece);
+ }
+ }
+ let is_source_literal = parser.is_source_literal;
+ if !parser.errors.is_empty() {
+ // FIXME: Diagnose
+ return FormatArgs { template: Default::default(), arguments: args.finish() };
+ }
+
+ let to_span = |inner_span: parse::InnerSpan| {
+ is_source_literal.then(|| {
+ TextRange::new(inner_span.start.try_into().unwrap(), inner_span.end.try_into().unwrap())
+ })
+ };
+
+ let mut used = vec![false; args.explicit_args().len()];
+ let mut invalid_refs = Vec::new();
+ let mut numeric_refences_to_named_arg = Vec::new();
+
+ enum ArgRef<'a> {
+ Index(usize),
+ Name(&'a str, Option<TextRange>),
+ }
+ let mut lookup_arg = |arg: ArgRef<'_>,
+ span: Option<TextRange>,
+ used_as: PositionUsedAs,
+ kind: FormatArgPositionKind|
+ -> FormatArgPosition {
+ let index = match arg {
+ ArgRef::Index(index) => {
+ if let Some(arg) = args.by_index(index) {
+ used[index] = true;
+ if arg.kind.ident().is_some() {
+ // This was a named argument, but it was used as a positional argument.
+ numeric_refences_to_named_arg.push((index, span, used_as));
+ }
+ Ok(index)
+ } else {
+ // Doesn't exist as an explicit argument.
+ invalid_refs.push((index, span, used_as, kind));
+ Err(index)
+ }
+ }
+ ArgRef::Name(name, _span) => {
+ let name = Name::new_text_dont_use(SmolStr::new(name));
+ if let Some((index, _)) = args.by_name(&name) {
+ // Name found in `args`, so we resolve it to its index.
+ if index < args.explicit_args().len() {
+ // Mark it as used, if it was an explicit argument.
+ used[index] = true;
+ }
+ Ok(index)
+ } else {
+ // Name not found in `args`, so we add it as an implicitly captured argument.
+ if !is_direct_literal {
+ // For the moment capturing variables from format strings expanded from macros is
+ // disabled (see RFC #2795)
+ // FIXME: Diagnose
+ }
+ Ok(args.add(FormatArgument {
+ kind: FormatArgumentKind::Captured(name.clone()),
+ // FIXME: This is problematic, we might want to synthesize a dummy
+ // expression proper and/or desugar these.
+ expr: synth(name),
+ }))
+ }
+ }
+ };
+ FormatArgPosition { index, kind, span }
+ };
+
+ let mut template = Vec::new();
+ let mut unfinished_literal = String::new();
+ let mut placeholder_index = 0;
+
+ for piece in pieces {
+ match piece {
+ parse::Piece::String(s) => {
+ unfinished_literal.push_str(s);
+ }
+ parse::Piece::NextArgument(arg) => {
+ let parse::Argument { position, position_span, format } = *arg;
+ if !unfinished_literal.is_empty() {
+ template.push(FormatArgsPiece::Literal(
+ mem::take(&mut unfinished_literal).into_boxed_str(),
+ ));
+ }
+
+ let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s));
+ placeholder_index += 1;
+
+ let position_span = to_span(position_span);
+ let argument = match position {
+ parse::ArgumentImplicitlyIs(i) => lookup_arg(
+ ArgRef::Index(i),
+ position_span,
+ Placeholder(span),
+ FormatArgPositionKind::Implicit,
+ ),
+ parse::ArgumentIs(i) => lookup_arg(
+ ArgRef::Index(i),
+ position_span,
+ Placeholder(span),
+ FormatArgPositionKind::Number,
+ ),
+ parse::ArgumentNamed(name) => lookup_arg(
+ ArgRef::Name(name, position_span),
+ position_span,
+ Placeholder(span),
+ FormatArgPositionKind::Named,
+ ),
+ };
+
+ let alignment = match format.align {
+ parse::AlignUnknown => None,
+ parse::AlignLeft => Some(FormatAlignment::Left),
+ parse::AlignRight => Some(FormatAlignment::Right),
+ parse::AlignCenter => Some(FormatAlignment::Center),
+ };
+
+ let format_trait = match format.ty {
+ "" => FormatTrait::Display,
+ "?" => FormatTrait::Debug,
+ "e" => FormatTrait::LowerExp,
+ "E" => FormatTrait::UpperExp,
+ "o" => FormatTrait::Octal,
+ "p" => FormatTrait::Pointer,
+ "b" => FormatTrait::Binary,
+ "x" => FormatTrait::LowerHex,
+ "X" => FormatTrait::UpperHex,
+ _ => {
+ // FIXME: Diagnose
+ FormatTrait::Display
+ }
+ };
+
+ let precision_span = format.precision_span.and_then(to_span);
+ let precision = match format.precision {
+ parse::CountIs(n) => Some(FormatCount::Literal(n)),
+ parse::CountIsName(name, name_span) => Some(FormatCount::Argument(lookup_arg(
+ ArgRef::Name(name, to_span(name_span)),
+ precision_span,
+ Precision,
+ FormatArgPositionKind::Named,
+ ))),
+ parse::CountIsParam(i) => Some(FormatCount::Argument(lookup_arg(
+ ArgRef::Index(i),
+ precision_span,
+ Precision,
+ FormatArgPositionKind::Number,
+ ))),
+ parse::CountIsStar(i) => Some(FormatCount::Argument(lookup_arg(
+ ArgRef::Index(i),
+ precision_span,
+ Precision,
+ FormatArgPositionKind::Implicit,
+ ))),
+ parse::CountImplied => None,
+ };
+
+ let width_span = format.width_span.and_then(to_span);
+ let width = match format.width {
+ parse::CountIs(n) => Some(FormatCount::Literal(n)),
+ parse::CountIsName(name, name_span) => Some(FormatCount::Argument(lookup_arg(
+ ArgRef::Name(name, to_span(name_span)),
+ width_span,
+ Width,
+ FormatArgPositionKind::Named,
+ ))),
+ parse::CountIsParam(i) => Some(FormatCount::Argument(lookup_arg(
+ ArgRef::Index(i),
+ width_span,
+ Width,
+ FormatArgPositionKind::Number,
+ ))),
+ parse::CountIsStar(_) => unreachable!(),
+ parse::CountImplied => None,
+ };
+
+ template.push(FormatArgsPiece::Placeholder(FormatPlaceholder {
+ argument,
+ span,
+ format_trait,
+ format_options: FormatOptions {
+ fill: format.fill,
+ alignment,
+ sign: format.sign.map(|s| match s {
+ parse::Sign::Plus => FormatSign::Plus,
+ parse::Sign::Minus => FormatSign::Minus,
+ }),
+ alternate: format.alternate,
+ zero_pad: format.zero_pad,
+ debug_hex: format.debug_hex.map(|s| match s {
+ parse::DebugHex::Lower => FormatDebugHex::Lower,
+ parse::DebugHex::Upper => FormatDebugHex::Upper,
+ }),
+ precision,
+ width,
+ },
+ }));
+ }
+ }
+ }
+
+ if !unfinished_literal.is_empty() {
+ template.push(FormatArgsPiece::Literal(unfinished_literal.into_boxed_str()));
+ }
+
+ if !invalid_refs.is_empty() {
+ // FIXME: Diagnose
+ }
+
+ let unused = used
+ .iter()
+ .enumerate()
+ .filter(|&(_, used)| !used)
+ .map(|(i, _)| {
+ let named = matches!(args.explicit_args()[i].kind, FormatArgumentKind::Named(_));
+ (args.explicit_args()[i].expr, named)
+ })
+ .collect::<Vec<_>>();
+
+ if !unused.is_empty() {
+ // FIXME: Diagnose
+ }
+
+ FormatArgs { template: template.into_boxed_slice(), arguments: args.finish() }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct FormatArgumentsCollector {
+ arguments: Vec<FormatArgument>,
+ num_unnamed_args: usize,
+ num_explicit_args: usize,
+ names: Vec<(Name, usize)>,
+}
+
+impl FormatArgumentsCollector {
+ pub(crate) fn finish(self) -> FormatArguments {
+ FormatArguments {
+ arguments: self.arguments.into_boxed_slice(),
+ num_unnamed_args: self.num_unnamed_args,
+ num_explicit_args: self.num_explicit_args,
+ names: self.names.into_boxed_slice(),
+ }
+ }
+
+ pub fn new() -> Self {
+ Self { arguments: vec![], names: vec![], num_unnamed_args: 0, num_explicit_args: 0 }
+ }
+
+ pub fn add(&mut self, arg: FormatArgument) -> usize {
+ let index = self.arguments.len();
+ if let Some(name) = arg.kind.ident() {
+ self.names.push((name.clone(), index));
+ } else if self.names.is_empty() {
+ // Only count the unnamed args before the first named arg.
+ // (Any later ones are errors.)
+ self.num_unnamed_args += 1;
+ }
+ if !matches!(arg.kind, FormatArgumentKind::Captured(..)) {
+ // This is an explicit argument.
+ // Make sure that all arguments so far are explicit.
+ assert_eq!(
+ self.num_explicit_args,
+ self.arguments.len(),
+ "captured arguments must be added last"
+ );
+ self.num_explicit_args += 1;
+ }
+ self.arguments.push(arg);
+ index
+ }
+
+ pub fn by_name(&self, name: &Name) -> Option<(usize, &FormatArgument)> {
+ let &(_, i) = self.names.iter().find(|(n, _)| n == name)?;
+ Some((i, &self.arguments[i]))
+ }
+
+ pub fn by_index(&self, i: usize) -> Option<&FormatArgument> {
+ (i < self.num_explicit_args).then(|| &self.arguments[i])
+ }
+
+ pub fn unnamed_args(&self) -> &[FormatArgument] {
+ &self.arguments[..self.num_unnamed_args]
+ }
+
+ pub fn named_args(&self) -> &[FormatArgument] {
+ &self.arguments[self.num_unnamed_args..self.num_explicit_args]
+ }
+
+ pub fn explicit_args(&self) -> &[FormatArgument] {
+ &self.arguments[..self.num_explicit_args]
+ }
+
+ pub fn all_args(&self) -> &[FormatArgument] {
+ &self.arguments[..]
+ }
+
+ pub fn all_args_mut(&mut self) -> &mut Vec<FormatArgument> {
+ &mut self.arguments
+ }
+}
+
+impl FormatArgumentKind {
+ pub fn ident(&self) -> Option<&Name> {
+ match self {
+ Self::Normal => None,
+ Self::Named(id) => Some(id),
+ Self::Captured(id) => Some(id),
+ }
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
index 57f023ef3..75adf21ab 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
@@ -393,6 +393,17 @@ impl ConstRef {
Self::Scalar(LiteralConstRef::Unknown)
}
+ pub(crate) fn from_const_param(
+ lower_ctx: &LowerCtx<'_>,
+ param: &ast::ConstParam,
+ ) -> Option<Self> {
+ let default = param.default_val();
+ match default {
+ Some(_) => Some(Self::from_const_arg(lower_ctx, default)),
+ None => None,
+ }
+ }
+
pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a {
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRef);
impl fmt::Display for Display<'_> {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
index 4b2e5041a..44b7f1b4f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
@@ -11,6 +11,7 @@ use itertools::Itertools;
use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
use triomphe::Arc;
+use crate::item_scope::ImportOrExternCrate;
use crate::{
db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, visibility::Visibility, AssocItemId,
ModuleDefId, ModuleId, TraitId,
@@ -29,6 +30,10 @@ pub struct ImportInfo {
pub container: ModuleId,
/// Whether the import is a trait associated item or not.
pub is_trait_assoc_item: bool,
+ /// Whether this item is annotated with `#[doc(hidden)]`.
+ pub is_doc_hidden: bool,
+ /// Whether this item is annotated with `#[unstable(..)]`.
+ pub is_unstable: bool,
}
/// A map from publicly exported items to its name.
@@ -109,23 +114,71 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
});
for (name, per_ns) in visible_items {
- for item in per_ns.iter_items() {
+ for (item, import) in per_ns.iter_items() {
+ let attr_id = if let Some(import) = import {
+ match import {
+ ImportOrExternCrate::ExternCrate(id) => Some(id.into()),
+ ImportOrExternCrate::Import(id) => Some(id.import.into()),
+ }
+ } else {
+ match item {
+ ItemInNs::Types(id) | ItemInNs::Values(id) => id.try_into().ok(),
+ ItemInNs::Macros(id) => Some(id.into()),
+ }
+ };
+ let status @ (is_doc_hidden, is_unstable) =
+ attr_id.map_or((false, false), |attr_id| {
+ let attrs = db.attrs(attr_id);
+ (attrs.has_doc_hidden(), attrs.is_unstable())
+ });
+
let import_info = ImportInfo {
name: name.clone(),
container: module,
is_trait_assoc_item: false,
+ is_doc_hidden,
+ is_unstable,
};
match depth_map.entry(item) {
- Entry::Vacant(entry) => {
- entry.insert(depth);
- }
+ Entry::Vacant(entry) => _ = entry.insert((depth, status)),
Entry::Occupied(mut entry) => {
- if depth < *entry.get() {
- entry.insert(depth);
- } else {
+ let &(occ_depth, (occ_is_doc_hidden, occ_is_unstable)) = entry.get();
+ (depth, occ_depth);
+ let overwrite = match (
+ is_doc_hidden,
+ occ_is_doc_hidden,
+ is_unstable,
+ occ_is_unstable,
+ ) {
+ // no change of hiddeness or unstableness
+ (true, true, true, true)
+ | (true, true, false, false)
+ | (false, false, true, true)
+ | (false, false, false, false) => depth < occ_depth,
+
+ // either less hidden or less unstable, accept
+ (true, true, false, true)
+ | (false, true, true, true)
+ | (false, true, false, true)
+ | (false, true, false, false)
+ | (false, false, false, true) => true,
+ // more hidden or unstable, discard
+ (true, true, true, false)
+ | (true, false, true, true)
+ | (true, false, true, false)
+ | (true, false, false, false)
+ | (false, false, true, false) => false,
+
+ // exchanges doc(hidden) for unstable (and vice-versa),
+ (true, false, false, true) | (false, true, true, false) => {
+ depth < occ_depth
+ }
+ };
+ if !overwrite {
continue;
}
+ entry.insert((depth, status));
}
}
@@ -150,7 +203,7 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
}
}
}
-
+ map.shrink_to_fit();
map
}
@@ -162,10 +215,10 @@ fn collect_trait_assoc_items(
trait_import_info: &ImportInfo,
) {
let _p = profile::span("collect_trait_assoc_items");
- for (assoc_item_name, item) in &db.trait_data(tr).items {
+ for &(ref assoc_item_name, item) in &db.trait_data(tr).items {
let module_def_id = match item {
- AssocItemId::FunctionId(f) => ModuleDefId::from(*f),
- AssocItemId::ConstId(c) => ModuleDefId::from(*c),
+ AssocItemId::FunctionId(f) => ModuleDefId::from(f),
+ AssocItemId::ConstId(c) => ModuleDefId::from(c),
// cannot use associated type aliases directly: need a `<Struct as Trait>::TypeAlias`
// qualifier, ergo no need to store it for imports in import_map
AssocItemId::TypeAliasId(_) => {
@@ -179,10 +232,13 @@ fn collect_trait_assoc_items(
ItemInNs::Values(module_def_id)
};
+ let attrs = &db.attrs(item.into());
let assoc_item_info = ImportInfo {
container: trait_import_info.container,
name: assoc_item_name.clone(),
is_trait_assoc_item: true,
+ is_doc_hidden: attrs.has_doc_hidden(),
+ is_unstable: attrs.is_unstable(),
};
map.insert(assoc_item, assoc_item_info);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
index 873accafb..7c11fb9d1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
@@ -6,6 +6,7 @@ use std::collections::hash_map::Entry;
use base_db::CrateId;
use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId};
use itertools::Itertools;
+use la_arena::Idx;
use once_cell::sync::Lazy;
use profile::Count;
use rustc_hash::{FxHashMap, FxHashSet};
@@ -15,16 +16,10 @@ use syntax::ast;
use crate::{
db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ConstId,
- ExternCrateId, HasModule, ImplId, LocalModuleId, MacroId, ModuleDefId, ModuleId, TraitId,
- UseId,
+ ExternCrateId, HasModule, ImplId, LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId,
+ TraitId, UseId,
};
-#[derive(Copy, Clone, Debug)]
-pub(crate) enum ImportType {
- Glob,
- Named,
-}
-
#[derive(Debug, Default)]
pub struct PerNsGlobImports {
types: FxHashSet<(LocalModuleId, Name)>,
@@ -32,15 +27,50 @@ pub struct PerNsGlobImports {
macros: FxHashSet<(LocalModuleId, Name)>,
}
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum ImportOrExternCrate {
+ Import(ImportId),
+ ExternCrate(ExternCrateId),
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub(crate) enum ImportType {
+ Import(ImportId),
+ Glob(UseId),
+ ExternCrate(ExternCrateId),
+}
+
+impl ImportOrExternCrate {
+ pub fn into_import(self) -> Option<ImportId> {
+ match self {
+ ImportOrExternCrate::Import(it) => Some(it),
+ _ => None,
+ }
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum ImportOrDef {
+ Import(ImportId),
+ ExternCrate(ExternCrateId),
+ Def(ModuleDefId),
+}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
+pub struct ImportId {
+ pub import: UseId,
+ pub idx: Idx<ast::UseTree>,
+}
+
#[derive(Debug, Default, PartialEq, Eq)]
pub struct ItemScope {
_c: Count<Self>,
/// Defs visible in this scope. This includes `declarations`, but also
- /// imports.
- types: FxHashMap<Name, (ModuleDefId, Visibility)>,
- values: FxHashMap<Name, (ModuleDefId, Visibility)>,
- macros: FxHashMap<Name, (MacroId, Visibility)>,
+ /// imports. The imports belong to this module and can be resolved by using them on
+ /// the `use_imports_*` fields.
+ types: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
+ values: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportId>)>,
+ macros: FxHashMap<Name, (MacroId, Visibility, Option<ImportId>)>,
unresolved: FxHashSet<Name>,
/// The defs declared in this scope. Each def has a single scope where it is
@@ -50,7 +80,14 @@ pub struct ItemScope {
impls: Vec<ImplId>,
unnamed_consts: Vec<ConstId>,
/// Traits imported via `use Trait as _;`.
- unnamed_trait_imports: FxHashMap<TraitId, Visibility>,
+ unnamed_trait_imports: FxHashMap<TraitId, (Visibility, Option<ImportId>)>,
+
+ // the resolutions of the imports of this scope
+ use_imports_types: FxHashMap<ImportOrExternCrate, ImportOrDef>,
+ use_imports_values: FxHashMap<ImportId, ImportOrDef>,
+ use_imports_macros: FxHashMap<ImportId, ImportOrDef>,
+
+ use_decls: Vec<UseId>,
extern_crate_decls: Vec<ExternCrateId>,
/// Macros visible in current module in legacy textual scope
///
@@ -82,7 +119,7 @@ struct DeriveMacroInvocation {
pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
BuiltinType::ALL
.iter()
- .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public)))
+ .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public, None)))
.collect()
});
@@ -105,11 +142,77 @@ impl ItemScope {
.chain(self.values.keys())
.chain(self.macros.keys())
.chain(self.unresolved.iter())
- .sorted()
.unique()
+ .sorted()
.map(move |name| (name, self.get(name)))
}
+ pub fn imports(&self) -> impl Iterator<Item = ImportId> + '_ {
+ self.use_imports_types
+ .keys()
+ .copied()
+ .filter_map(ImportOrExternCrate::into_import)
+ .chain(self.use_imports_values.keys().copied())
+ .chain(self.use_imports_macros.keys().copied())
+ .unique()
+ .sorted()
+ }
+
+ pub fn fully_resolve_import(&self, db: &dyn DefDatabase, mut import: ImportId) -> PerNs {
+ let mut res = PerNs::none();
+
+ let mut def_map;
+ let mut scope = self;
+ while let Some(&m) = scope.use_imports_macros.get(&import) {
+ match m {
+ ImportOrDef::Import(i) => {
+ let module_id = i.import.lookup(db).container;
+ def_map = module_id.def_map(db);
+ scope = &def_map[module_id.local_id].scope;
+ import = i;
+ }
+ ImportOrDef::Def(ModuleDefId::MacroId(def)) => {
+ res.macros = Some((def, Visibility::Public, None));
+ break;
+ }
+ _ => break,
+ }
+ }
+ let mut scope = self;
+ while let Some(&m) = scope.use_imports_types.get(&ImportOrExternCrate::Import(import)) {
+ match m {
+ ImportOrDef::Import(i) => {
+ let module_id = i.import.lookup(db).container;
+ def_map = module_id.def_map(db);
+ scope = &def_map[module_id.local_id].scope;
+ import = i;
+ }
+ ImportOrDef::Def(def) => {
+ res.types = Some((def, Visibility::Public, None));
+ break;
+ }
+ _ => break,
+ }
+ }
+ let mut scope = self;
+ while let Some(&m) = scope.use_imports_values.get(&import) {
+ match m {
+ ImportOrDef::Import(i) => {
+ let module_id = i.import.lookup(db).container;
+ def_map = module_id.def_map(db);
+ scope = &def_map[module_id.local_id].scope;
+ import = i;
+ }
+ ImportOrDef::Def(def) => {
+ res.values = Some((def, Visibility::Public, None));
+ break;
+ }
+ _ => break,
+ }
+ }
+ res
+ }
+
pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
self.declarations.iter().copied()
}
@@ -121,8 +224,7 @@ impl ItemScope {
}
pub fn use_decls(&self) -> impl Iterator<Item = UseId> + ExactSizeIterator + '_ {
- // FIXME: to be implemented
- std::iter::empty()
+ self.use_decls.iter().copied()
}
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
@@ -132,13 +234,13 @@ impl ItemScope {
pub fn values(
&self,
) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
- self.values.values().copied()
+ self.values.values().copied().map(|(a, b, _)| (a, b))
}
- pub fn types(
+ pub(crate) fn types(
&self,
) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
- self.types.values().copied()
+ self.types.values().copied().map(|(def, vis, _)| (def, vis))
}
pub fn unnamed_consts(&self) -> impl Iterator<Item = ConstId> + '_ {
@@ -165,33 +267,55 @@ impl ItemScope {
}
pub(crate) fn type_(&self, name: &Name) -> Option<(ModuleDefId, Visibility)> {
- self.types.get(name).copied()
+ self.types.get(name).copied().map(|(a, b, _)| (a, b))
}
/// XXX: this is O(N) rather than O(1), try to not introduce new usages.
pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility)> {
- let (def, mut iter) = match item {
- ItemInNs::Macros(def) => {
- return self.macros.iter().find_map(|(name, &(other_def, vis))| {
- (other_def == def).then_some((name, vis))
- });
- }
- ItemInNs::Types(def) => (def, self.types.iter()),
- ItemInNs::Values(def) => (def, self.values.iter()),
- };
- iter.find_map(|(name, &(other_def, vis))| (other_def == def).then_some((name, vis)))
+ match item {
+ ItemInNs::Macros(def) => self
+ .macros
+ .iter()
+ .find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
+ ItemInNs::Types(def) => self
+ .types
+ .iter()
+ .find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
+
+ ItemInNs::Values(def) => self
+ .values
+ .iter()
+ .find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
+ }
}
pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
self.types
.values()
- .filter_map(|&(def, _)| match def {
+ .filter_map(|&(def, _, _)| match def {
ModuleDefId::TraitId(t) => Some(t),
_ => None,
})
.chain(self.unnamed_trait_imports.keys().copied())
}
+ pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
+ self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
+ self.unnamed_trait_imports.iter().map(|(tr, (vis, i))| {
+ (
+ None,
+ PerNs::types(
+ ModuleDefId::TraitId(*tr),
+ *vis,
+ i.map(ImportOrExternCrate::Import),
+ ),
+ )
+ }),
+ )
+ }
+}
+
+impl ItemScope {
pub(crate) fn declare(&mut self, def: ModuleDefId) {
self.declarations.push(def)
}
@@ -277,12 +401,14 @@ impl ItemScope {
})
}
+ // FIXME: This is only used in collection, we should move the relevant parts of it out of ItemScope
pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
- self.unnamed_trait_imports.get(&tr).copied()
+ self.unnamed_trait_imports.get(&tr).copied().map(|(a, _)| a)
}
pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
- self.unnamed_trait_imports.insert(tr, vis);
+ // FIXME: import
+ self.unnamed_trait_imports.insert(tr, (vis, None));
}
pub(crate) fn push_res_with_import(
@@ -290,51 +416,187 @@ impl ItemScope {
glob_imports: &mut PerNsGlobImports,
lookup: (LocalModuleId, Name),
def: PerNs,
- def_import_type: ImportType,
+ import: Option<ImportType>,
) -> bool {
let mut changed = false;
- macro_rules! check_changed {
- (
- $changed:ident,
- ( $this:ident / $def:ident ) . $field:ident,
- $glob_imports:ident [ $lookup:ident ],
- $def_import_type:ident
- ) => {{
- if let Some(fld) = $def.$field {
- let existing = $this.$field.entry($lookup.1.clone());
- match existing {
- Entry::Vacant(entry) => {
- match $def_import_type {
- ImportType::Glob => {
- $glob_imports.$field.insert($lookup.clone());
+ // FIXME: Document and simplify this
+
+ if let Some(mut fld) = def.types {
+ let existing = self.types.entry(lookup.1.clone());
+ match existing {
+ Entry::Vacant(entry) => {
+ match import {
+ Some(ImportType::Glob(_)) => {
+ glob_imports.types.insert(lookup.clone());
+ }
+ _ => _ = glob_imports.types.remove(&lookup),
+ }
+ let import = match import {
+ Some(ImportType::ExternCrate(extern_crate)) => {
+ Some(ImportOrExternCrate::ExternCrate(extern_crate))
+ }
+ Some(ImportType::Import(import)) => {
+ Some(ImportOrExternCrate::Import(import))
+ }
+ None | Some(ImportType::Glob(_)) => None,
+ };
+ let prev = std::mem::replace(&mut fld.2, import);
+ if let Some(import) = import {
+ self.use_imports_types.insert(
+ import,
+ match prev {
+ Some(ImportOrExternCrate::Import(import)) => {
+ ImportOrDef::Import(import)
}
- ImportType::Named => {
- $glob_imports.$field.remove(&$lookup);
+ Some(ImportOrExternCrate::ExternCrate(import)) => {
+ ImportOrDef::ExternCrate(import)
}
+ None => ImportOrDef::Def(fld.0),
+ },
+ );
+ }
+ entry.insert(fld);
+ changed = true;
+ }
+ Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
+ if glob_imports.types.remove(&lookup) {
+ let import = match import {
+ Some(ImportType::ExternCrate(extern_crate)) => {
+ Some(ImportOrExternCrate::ExternCrate(extern_crate))
+ }
+ Some(ImportType::Import(import)) => {
+ Some(ImportOrExternCrate::Import(import))
}
+ None | Some(ImportType::Glob(_)) => None,
+ };
+ let prev = std::mem::replace(&mut fld.2, import);
+ if let Some(import) = import {
+ self.use_imports_types.insert(
+ import,
+ match prev {
+ Some(ImportOrExternCrate::Import(import)) => {
+ ImportOrDef::Import(import)
+ }
+ Some(ImportOrExternCrate::ExternCrate(import)) => {
+ ImportOrDef::ExternCrate(import)
+ }
+ None => ImportOrDef::Def(fld.0),
+ },
+ );
+ }
+ cov_mark::hit!(import_shadowed);
+ entry.insert(fld);
+ changed = true;
+ }
+ }
+ _ => {}
+ }
+ }
- entry.insert(fld);
- $changed = true;
+ if let Some(mut fld) = def.values {
+ let existing = self.values.entry(lookup.1.clone());
+ match existing {
+ Entry::Vacant(entry) => {
+ match import {
+ Some(ImportType::Glob(_)) => {
+ glob_imports.values.insert(lookup.clone());
}
- Entry::Occupied(mut entry)
- if matches!($def_import_type, ImportType::Named) =>
- {
- if $glob_imports.$field.remove(&$lookup) {
- cov_mark::hit!(import_shadowed);
- entry.insert(fld);
- $changed = true;
- }
+ _ => _ = glob_imports.values.remove(&lookup),
+ }
+ let import = match import {
+ Some(ImportType::Import(import)) => Some(import),
+ _ => None,
+ };
+ let prev = std::mem::replace(&mut fld.2, import);
+ if let Some(import) = import {
+ self.use_imports_values.insert(
+ import,
+ match prev {
+ Some(import) => ImportOrDef::Import(import),
+ None => ImportOrDef::Def(fld.0),
+ },
+ );
+ }
+ entry.insert(fld);
+ changed = true;
+ }
+ Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
+ if glob_imports.values.remove(&lookup) {
+ cov_mark::hit!(import_shadowed);
+ let import = match import {
+ Some(ImportType::Import(import)) => Some(import),
+ _ => None,
+ };
+ let prev = std::mem::replace(&mut fld.2, import);
+ if let Some(import) = import {
+ self.use_imports_values.insert(
+ import,
+ match prev {
+ Some(import) => ImportOrDef::Import(import),
+ None => ImportOrDef::Def(fld.0),
+ },
+ );
}
- _ => {}
+ entry.insert(fld);
+ changed = true;
}
}
- }};
+ _ => {}
+ }
}
- check_changed!(changed, (self / def).types, glob_imports[lookup], def_import_type);
- check_changed!(changed, (self / def).values, glob_imports[lookup], def_import_type);
- check_changed!(changed, (self / def).macros, glob_imports[lookup], def_import_type);
+ if let Some(mut fld) = def.macros {
+ let existing = self.macros.entry(lookup.1.clone());
+ match existing {
+ Entry::Vacant(entry) => {
+ match import {
+ Some(ImportType::Glob(_)) => {
+ glob_imports.macros.insert(lookup.clone());
+ }
+ _ => _ = glob_imports.macros.remove(&lookup),
+ }
+ let import = match import {
+ Some(ImportType::Import(import)) => Some(import),
+ _ => None,
+ };
+ let prev = std::mem::replace(&mut fld.2, import);
+ if let Some(import) = import {
+ self.use_imports_macros.insert(
+ import,
+ match prev {
+ Some(import) => ImportOrDef::Import(import),
+ None => ImportOrDef::Def(fld.0.into()),
+ },
+ );
+ }
+ entry.insert(fld);
+ changed = true;
+ }
+ Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
+ if glob_imports.macros.remove(&lookup) {
+ cov_mark::hit!(import_shadowed);
+ let import = match import {
+ Some(ImportType::Import(import)) => Some(import),
+ _ => None,
+ };
+ let prev = std::mem::replace(&mut fld.2, import);
+ if let Some(import) = import {
+ self.use_imports_macros.insert(
+ import,
+ match prev {
+ Some(import) => ImportOrDef::Import(import),
+ None => ImportOrDef::Def(fld.0.into()),
+ },
+ );
+ }
+ entry.insert(fld);
+ changed = true;
+ }
+ }
+ _ => {}
+ }
+ }
if def.is_none() && self.unresolved.insert(lookup.1) {
changed = true;
@@ -343,27 +605,18 @@ impl ItemScope {
changed
}
- pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
- self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
- self.unnamed_trait_imports
- .iter()
- .map(|(tr, vis)| (None, PerNs::types(ModuleDefId::TraitId(*tr), *vis))),
- )
- }
-
/// Marks everything that is not a procedural macro as private to `this_module`.
pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {
self.types
.values_mut()
- .chain(self.values.values_mut())
+ .map(|(def, vis, _)| (def, vis))
+ .chain(self.values.values_mut().map(|(def, vis, _)| (def, vis)))
.map(|(_, v)| v)
- .chain(self.unnamed_trait_imports.values_mut())
+ .chain(self.unnamed_trait_imports.values_mut().map(|(vis, _)| vis))
.for_each(|vis| *vis = Visibility::Module(this_module));
- for (mac, vis) in self.macros.values_mut() {
- if let MacroId::ProcMacroId(_) = mac {
- // FIXME: Technically this is insufficient since reexports of proc macros are also
- // forbidden. Practically nobody does that.
+ for (mac, vis, import) in self.macros.values_mut() {
+ if matches!(mac, MacroId::ProcMacroId(_) if import.is_none()) {
continue;
}
@@ -382,14 +635,25 @@ impl ItemScope {
name.map_or("_".to_string(), |name| name.display(db).to_string())
);
- if def.types.is_some() {
+ if let Some((.., i)) = def.types {
buf.push_str(" t");
+ match i {
+ Some(ImportOrExternCrate::Import(_)) => buf.push('i'),
+ Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'),
+ None => (),
+ }
}
- if def.values.is_some() {
+ if let Some((.., i)) = def.values {
buf.push_str(" v");
+ if i.is_some() {
+ buf.push('i');
+ }
}
- if def.macros.is_some() {
+ if let Some((.., i)) = def.macros {
buf.push_str(" m");
+ if i.is_some() {
+ buf.push('i');
+ }
}
if def.is_none() {
buf.push_str(" _");
@@ -415,10 +679,17 @@ impl ItemScope {
attr_macros,
derive_macros,
extern_crate_decls,
+ use_decls,
+ use_imports_values,
+ use_imports_types,
+ use_imports_macros,
} = self;
types.shrink_to_fit();
values.shrink_to_fit();
macros.shrink_to_fit();
+ use_imports_types.shrink_to_fit();
+ use_imports_values.shrink_to_fit();
+ use_imports_macros.shrink_to_fit();
unresolved.shrink_to_fit();
declarations.shrink_to_fit();
impls.shrink_to_fit();
@@ -428,32 +699,44 @@ impl ItemScope {
attr_macros.shrink_to_fit();
derive_macros.shrink_to_fit();
extern_crate_decls.shrink_to_fit();
+ use_decls.shrink_to_fit();
}
}
impl PerNs {
- pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) -> PerNs {
+ pub(crate) fn from_def(
+ def: ModuleDefId,
+ v: Visibility,
+ has_constructor: bool,
+ import: Option<ImportOrExternCrate>,
+ ) -> PerNs {
match def {
- ModuleDefId::ModuleId(_) => PerNs::types(def, v),
- ModuleDefId::FunctionId(_) => PerNs::values(def, v),
+ ModuleDefId::ModuleId(_) => PerNs::types(def, v, import),
+ ModuleDefId::FunctionId(_) => {
+ PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
+ }
ModuleDefId::AdtId(adt) => match adt {
- AdtId::UnionId(_) => PerNs::types(def, v),
- AdtId::EnumId(_) => PerNs::types(def, v),
+ AdtId::UnionId(_) => PerNs::types(def, v, import),
+ AdtId::EnumId(_) => PerNs::types(def, v, import),
AdtId::StructId(_) => {
if has_constructor {
- PerNs::both(def, def, v)
+ PerNs::both(def, def, v, import)
} else {
- PerNs::types(def, v)
+ PerNs::types(def, v, import)
}
}
},
- ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
- ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
- ModuleDefId::TraitId(_) => PerNs::types(def, v),
- ModuleDefId::TraitAliasId(_) => PerNs::types(def, v),
- ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
- ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
- ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),
+ ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v, import),
+ ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => {
+ PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
+ }
+ ModuleDefId::TraitId(_) => PerNs::types(def, v, import),
+ ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import),
+ ModuleDefId::TypeAliasId(_) => PerNs::types(def, v, import),
+ ModuleDefId::BuiltinType(_) => PerNs::types(def, v, import),
+ ModuleDefId::MacroId(mac) => {
+ PerNs::macros(mac, v, import.and_then(ImportOrExternCrate::into_import))
+ }
}
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index c9b0f75f1..4c812b62a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -64,11 +64,11 @@ use triomphe::Arc;
use crate::{
attr::Attrs,
db::DefDatabase,
- generics::GenericParams,
+ generics::{GenericParams, LifetimeParamData, TypeOrConstParamData},
path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
visibility::RawVisibility,
- BlockId,
+ BlockId, Lookup,
};
#[derive(Copy, Clone, Eq, PartialEq)]
@@ -143,6 +143,16 @@ impl ItemTree {
Arc::new(item_tree)
}
+ pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
+ let loc = block.lookup(db);
+ let block = loc.ast_id.to_node(db.upcast());
+
+ let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
+ let mut item_tree = ctx.lower_block(&block);
+ item_tree.shrink_to_fit();
+ Arc::new(item_tree)
+ }
+
/// Returns an iterator over all items located at the top level of the `HirFileId` this
/// `ItemTree` was created from.
pub fn top_level_items(&self) -> &[ModItem] {
@@ -167,7 +177,7 @@ impl ItemTree {
}
pub fn pretty_print(&self, db: &dyn DefDatabase) -> String {
- pretty::print_item_tree(db.upcast(), self)
+ pretty::print_item_tree(db, self)
}
fn data(&self) -> &ItemTreeData {
@@ -178,13 +188,6 @@ impl ItemTree {
self.data.get_or_insert_with(Box::default)
}
- fn block_item_tree(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
- let loc = db.lookup_intern_block(block);
- let block = loc.ast_id.to_node(db.upcast());
- let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
- Arc::new(ctx.lower_block(&block))
- }
-
fn shrink_to_fit(&mut self) {
if let Some(data) = &mut self.data {
let ItemTreeData {
@@ -296,10 +299,12 @@ pub enum AttrOwner {
Variant(Idx<Variant>),
Field(Idx<Field>),
Param(Idx<Param>),
+ TypeOrConstParamData(Idx<TypeOrConstParamData>),
+ LifetimeParamData(Idx<LifetimeParamData>),
}
macro_rules! from_attrs {
- ( $( $var:ident($t:ty) ),+ ) => {
+ ( $( $var:ident($t:ty) ),+ $(,)? ) => {
$(
impl From<$t> for AttrOwner {
fn from(t: $t) -> AttrOwner {
@@ -310,7 +315,14 @@ macro_rules! from_attrs {
};
}
-from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>), Param(Idx<Param>));
+from_attrs!(
+ ModItem(ModItem),
+ Variant(Idx<Variant>),
+ Field(Idx<Field>),
+ Param(Idx<Param>),
+ TypeOrConstParamData(Idx<TypeOrConstParamData>),
+ LifetimeParamData(Idx<LifetimeParamData>),
+);
/// Trait implemented by all item nodes in the item tree.
pub trait ItemTreeNode: Clone {
@@ -373,7 +385,7 @@ impl TreeId {
pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
match self.block {
- Some(block) => ItemTree::block_item_tree(db, block),
+ Some(block) => db.block_item_tree_query(block),
None => db.file_item_tree(self.file),
}
}
@@ -761,6 +773,19 @@ impl Use {
lower::lower_use_tree(db, &hygiene, ast_use_tree).expect("failed to lower use tree");
source_map[index].clone()
}
+ /// Maps a `UseTree` contained in this import back to its AST node.
+ pub fn use_tree_source_map(
+ &self,
+ db: &dyn DefDatabase,
+ file_id: HirFileId,
+ ) -> Arena<ast::UseTree> {
+ // Re-lower the AST item and get the source map.
+ // Note: The AST unwraps are fine, since if they fail we should have never obtained `index`.
+ let ast = InFile::new(file_id, self.ast_id).to_node(db.upcast());
+ let ast_use_tree = ast.use_tree().expect("missing `use_tree`");
+ let hygiene = Hygiene::new(db.upcast(), file_id);
+ lower::lower_use_tree(db, &hygiene, ast_use_tree).expect("failed to lower use tree").1
+ }
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -785,7 +810,7 @@ impl UseTree {
fn expand_impl(
&self,
prefix: Option<ModPath>,
- cb: &mut dyn FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
+ cb: &mut impl FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
) {
fn concat_mod_paths(
prefix: Option<ModPath>,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
index 7b898e62d..e4702c113 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
@@ -77,6 +77,9 @@ impl<'a> Ctx<'a> {
}
pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree {
+ self.tree
+ .attrs
+ .insert(AttrOwner::TopLevel, RawAttrs::new(self.db.upcast(), block, self.hygiene()));
self.tree.top_level = block
.statements()
.filter_map(|stmt| match stmt {
@@ -602,7 +605,21 @@ impl<'a> Ctx<'a> {
generics.fill_bounds(&self.body_ctx, bounds, Either::Left(self_param));
}
- generics.fill(&self.body_ctx, node);
+ let add_param_attrs = |item, param| {
+ let attrs = RawAttrs::new(self.db.upcast(), &param, self.body_ctx.hygiene());
+ // This is identical to the body of `Ctx::add_attrs()` but we can't call that here
+ // because it requires `&mut self` and the call to `generics.fill()` below also
+ // references `self`.
+ match self.tree.attrs.entry(item) {
+ Entry::Occupied(mut entry) => {
+ *entry.get_mut() = entry.get().merge(attrs);
+ }
+ Entry::Vacant(entry) => {
+ entry.insert(attrs);
+ }
+ }
+ };
+ generics.fill(&self.body_ctx, node, add_param_attrs);
generics.shrink_to_fit();
Interned::new(generics)
@@ -763,7 +780,7 @@ impl UseTreeLowering<'_> {
}
}
-pub(super) fn lower_use_tree(
+pub(crate) fn lower_use_tree(
db: &dyn DefDatabase,
hygiene: &Hygiene,
tree: ast::UseTree,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
index da30830fe..417bd37c8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
@@ -2,8 +2,6 @@
use std::fmt::{self, Write};
-use hir_expand::db::ExpandDatabase;
-
use crate::{
generics::{TypeOrConstParamData, WherePredicate, WherePredicateTypeTarget},
pretty::{print_path, print_type_bounds, print_type_ref},
@@ -12,11 +10,11 @@ use crate::{
use super::*;
-pub(super) fn print_item_tree(db: &dyn ExpandDatabase, tree: &ItemTree) -> String {
+pub(super) fn print_item_tree(db: &dyn DefDatabase, tree: &ItemTree) -> String {
let mut p = Printer { db, tree, buf: String::new(), indent_level: 0, needs_indent: true };
if let Some(attrs) = tree.attrs.get(&AttrOwner::TopLevel) {
- p.print_attrs(attrs, true);
+ p.print_attrs(attrs, true, "\n");
}
p.blank();
@@ -45,7 +43,7 @@ macro_rules! wln {
}
struct Printer<'a> {
- db: &'a dyn ExpandDatabase,
+ db: &'a dyn DefDatabase,
tree: &'a ItemTree,
buf: String,
indent_level: usize,
@@ -84,28 +82,29 @@ impl Printer<'_> {
}
}
- fn print_attrs(&mut self, attrs: &RawAttrs, inner: bool) {
+ fn print_attrs(&mut self, attrs: &RawAttrs, inner: bool, separated_by: &str) {
let inner = if inner { "!" } else { "" };
for attr in &**attrs {
- wln!(
+ w!(
self,
- "#{}[{}{}]",
+ "#{}[{}{}]{}",
inner,
- attr.path.display(self.db),
+ attr.path.display(self.db.upcast()),
attr.input.as_ref().map(|it| it.to_string()).unwrap_or_default(),
+ separated_by,
);
}
}
- fn print_attrs_of(&mut self, of: impl Into<AttrOwner>) {
+ fn print_attrs_of(&mut self, of: impl Into<AttrOwner>, separated_by: &str) {
if let Some(attrs) = self.tree.attrs.get(&of.into()) {
- self.print_attrs(attrs, false);
+ self.print_attrs(attrs, false, separated_by);
}
}
fn print_visibility(&mut self, vis: RawVisibilityId) {
match &self.tree[vis] {
- RawVisibility::Module(path) => w!(self, "pub({}) ", path.display(self.db)),
+ RawVisibility::Module(path) => w!(self, "pub({}) ", path.display(self.db.upcast())),
RawVisibility::Public => w!(self, "pub "),
};
}
@@ -118,9 +117,9 @@ impl Printer<'_> {
self.indented(|this| {
for field in fields.clone() {
let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field];
- this.print_attrs_of(field);
+ this.print_attrs_of(field, "\n");
this.print_visibility(*visibility);
- w!(this, "{}: ", name.display(self.db));
+ w!(this, "{}: ", name.display(self.db.upcast()));
this.print_type_ref(type_ref);
wln!(this, ",");
}
@@ -132,9 +131,9 @@ impl Printer<'_> {
self.indented(|this| {
for field in fields.clone() {
let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field];
- this.print_attrs_of(field);
+ this.print_attrs_of(field, "\n");
this.print_visibility(*visibility);
- w!(this, "{}: ", name.display(self.db));
+ w!(this, "{}: ", name.display(self.db.upcast()));
this.print_type_ref(type_ref);
wln!(this, ",");
}
@@ -167,20 +166,20 @@ impl Printer<'_> {
fn print_use_tree(&mut self, use_tree: &UseTree) {
match &use_tree.kind {
UseTreeKind::Single { path, alias } => {
- w!(self, "{}", path.display(self.db));
+ w!(self, "{}", path.display(self.db.upcast()));
if let Some(alias) = alias {
w!(self, " as {}", alias);
}
}
UseTreeKind::Glob { path } => {
if let Some(path) = path {
- w!(self, "{}::", path.display(self.db));
+ w!(self, "{}::", path.display(self.db.upcast()));
}
w!(self, "*");
}
UseTreeKind::Prefixed { prefix, list } => {
if let Some(prefix) = prefix {
- w!(self, "{}::", prefix.display(self.db));
+ w!(self, "{}::", prefix.display(self.db.upcast()));
}
w!(self, "{{");
for (i, tree) in list.iter().enumerate() {
@@ -195,7 +194,7 @@ impl Printer<'_> {
}
fn print_mod_item(&mut self, item: ModItem) {
- self.print_attrs_of(item);
+ self.print_attrs_of(item, "\n");
match item {
ModItem::Use(it) => {
@@ -208,7 +207,7 @@ impl Printer<'_> {
ModItem::ExternCrate(it) => {
let ExternCrate { name, alias, visibility, ast_id: _ } = &self.tree[it];
self.print_visibility(*visibility);
- w!(self, "extern crate {}", name.display(self.db));
+ w!(self, "extern crate {}", name.display(self.db.upcast()));
if let Some(alias) = alias {
w!(self, " as {}", alias);
}
@@ -255,13 +254,13 @@ impl Printer<'_> {
if let Some(abi) = abi {
w!(self, "extern \"{}\" ", abi);
}
- w!(self, "fn {}", name.display(self.db));
+ w!(self, "fn {}", name.display(self.db.upcast()));
self.print_generic_params(explicit_generic_params);
w!(self, "(");
if !params.is_empty() {
self.indented(|this| {
for param in params.clone() {
- this.print_attrs_of(param);
+ this.print_attrs_of(param, "\n");
match &this.tree[param] {
Param::Normal(ty) => {
if flags.contains(FnFlags::HAS_SELF_PARAM) {
@@ -289,7 +288,7 @@ impl Printer<'_> {
ModItem::Struct(it) => {
let Struct { visibility, name, fields, generic_params, ast_id: _ } = &self.tree[it];
self.print_visibility(*visibility);
- w!(self, "struct {}", name.display(self.db));
+ w!(self, "struct {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params);
self.print_fields_and_where_clause(fields, generic_params);
if matches!(fields, Fields::Record(_)) {
@@ -301,7 +300,7 @@ impl Printer<'_> {
ModItem::Union(it) => {
let Union { name, visibility, fields, generic_params, ast_id: _ } = &self.tree[it];
self.print_visibility(*visibility);
- w!(self, "union {}", name.display(self.db));
+ w!(self, "union {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params);
self.print_fields_and_where_clause(fields, generic_params);
if matches!(fields, Fields::Record(_)) {
@@ -313,14 +312,14 @@ impl Printer<'_> {
ModItem::Enum(it) => {
let Enum { name, visibility, variants, generic_params, ast_id: _ } = &self.tree[it];
self.print_visibility(*visibility);
- w!(self, "enum {}", name.display(self.db));
+ w!(self, "enum {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params);
self.print_where_clause_and_opening_brace(generic_params);
self.indented(|this| {
for variant in variants.clone() {
let Variant { name, fields, ast_id: _ } = &this.tree[variant];
- this.print_attrs_of(variant);
- w!(this, "{}", name.display(self.db));
+ this.print_attrs_of(variant, "\n");
+ w!(this, "{}", name.display(self.db.upcast()));
this.print_fields(fields);
wln!(this, ",");
}
@@ -332,7 +331,7 @@ impl Printer<'_> {
self.print_visibility(*visibility);
w!(self, "const ");
match name {
- Some(name) => w!(self, "{}", name.display(self.db)),
+ Some(name) => w!(self, "{}", name.display(self.db.upcast())),
None => w!(self, "_"),
}
w!(self, ": ");
@@ -346,7 +345,7 @@ impl Printer<'_> {
if *mutable {
w!(self, "mut ");
}
- w!(self, "{}: ", name.display(self.db));
+ w!(self, "{}: ", name.display(self.db.upcast()));
self.print_type_ref(type_ref);
w!(self, " = _;");
wln!(self);
@@ -368,7 +367,7 @@ impl Printer<'_> {
if *is_auto {
w!(self, "auto ");
}
- w!(self, "trait {}", name.display(self.db));
+ w!(self, "trait {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params);
self.print_where_clause_and_opening_brace(generic_params);
self.indented(|this| {
@@ -381,7 +380,7 @@ impl Printer<'_> {
ModItem::TraitAlias(it) => {
let TraitAlias { name, visibility, generic_params, ast_id: _ } = &self.tree[it];
self.print_visibility(*visibility);
- w!(self, "trait {}", name.display(self.db));
+ w!(self, "trait {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params);
w!(self, " = ");
self.print_where_clause(generic_params);
@@ -414,7 +413,7 @@ impl Printer<'_> {
let TypeAlias { name, visibility, bounds, type_ref, generic_params, ast_id: _ } =
&self.tree[it];
self.print_visibility(*visibility);
- w!(self, "type {}", name.display(self.db));
+ w!(self, "type {}", name.display(self.db.upcast()));
self.print_generic_params(generic_params);
if !bounds.is_empty() {
w!(self, ": ");
@@ -431,7 +430,7 @@ impl Printer<'_> {
ModItem::Mod(it) => {
let Mod { name, visibility, kind, ast_id: _ } = &self.tree[it];
self.print_visibility(*visibility);
- w!(self, "mod {}", name.display(self.db));
+ w!(self, "mod {}", name.display(self.db.upcast()));
match kind {
ModKind::Inline { items } => {
w!(self, " {{");
@@ -449,16 +448,16 @@ impl Printer<'_> {
}
ModItem::MacroCall(it) => {
let MacroCall { path, ast_id: _, expand_to: _ } = &self.tree[it];
- wln!(self, "{}!(...);", path.display(self.db));
+ wln!(self, "{}!(...);", path.display(self.db.upcast()));
}
ModItem::MacroRules(it) => {
let MacroRules { name, ast_id: _ } = &self.tree[it];
- wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db));
+ wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db.upcast()));
}
ModItem::MacroDef(it) => {
let MacroDef { name, visibility, ast_id: _ } = &self.tree[it];
self.print_visibility(*visibility);
- wln!(self, "macro {} {{ ... }}", name.display(self.db));
+ wln!(self, "macro {} {{ ... }}", name.display(self.db.upcast()));
}
}
@@ -484,25 +483,27 @@ impl Printer<'_> {
w!(self, "<");
let mut first = true;
- for (_, lt) in params.lifetimes.iter() {
+ for (idx, lt) in params.lifetimes.iter() {
if !first {
w!(self, ", ");
}
first = false;
- w!(self, "{}", lt.name.display(self.db));
+ self.print_attrs_of(idx, " ");
+ w!(self, "{}", lt.name.display(self.db.upcast()));
}
for (idx, x) in params.type_or_consts.iter() {
if !first {
w!(self, ", ");
}
first = false;
+ self.print_attrs_of(idx, " ");
match x {
TypeOrConstParamData::TypeParamData(ty) => match &ty.name {
- Some(name) => w!(self, "{}", name.display(self.db)),
+ Some(name) => w!(self, "{}", name.display(self.db.upcast())),
None => w!(self, "_anon_{}", idx.into_raw()),
},
TypeOrConstParamData::ConstParamData(konst) => {
- w!(self, "const {}: ", konst.name.display(self.db));
+ w!(self, "const {}: ", konst.name.display(self.db.upcast()));
self.print_type_ref(&konst.ty);
}
}
@@ -537,8 +538,8 @@ impl Printer<'_> {
wln!(
this,
"{}: {},",
- target.name.display(self.db),
- bound.name.display(self.db)
+ target.name.display(self.db.upcast()),
+ bound.name.display(self.db.upcast())
);
continue;
}
@@ -548,7 +549,7 @@ impl Printer<'_> {
if i != 0 {
w!(this, ", ");
}
- w!(this, "{}", lt.display(self.db));
+ w!(this, "{}", lt.display(self.db.upcast()));
}
w!(this, "> ");
(target, bound)
@@ -559,7 +560,7 @@ impl Printer<'_> {
WherePredicateTypeTarget::TypeRef(ty) => this.print_type_ref(ty),
WherePredicateTypeTarget::TypeOrConstParam(id) => {
match &params.type_or_consts[*id].name() {
- Some(name) => w!(this, "{}", name.display(self.db)),
+ Some(name) => w!(this, "{}", name.display(self.db.upcast())),
None => w!(this, "_anon_{}", id.into_raw()),
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
index 5ded4b6b2..4180f8172 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
@@ -358,3 +358,15 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
"#]],
)
}
+
+#[test]
+fn generics_with_attributes() {
+ check(
+ r#"
+struct S<#[cfg(never)] T>;
+ "#,
+ expect![[r#"
+ pub(self) struct S<#[cfg(never)] T>;
+ "#]],
+ )
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
index 627479bb7..1ae6bd4c9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
@@ -2,6 +2,7 @@
//!
//! This attribute to tell the compiler about semi built-in std library
//! features, such as Fn family of traits.
+use hir_expand::name::Name;
use rustc_hash::FxHashMap;
use syntax::SmolStr;
use triomphe::Arc;
@@ -238,7 +239,17 @@ impl LangItem {
pub fn path(&self, db: &dyn DefDatabase, start_crate: CrateId) -> Option<Path> {
let t = db.lang_item(start_crate, *self)?;
- Some(Path::LangItem(t))
+ Some(Path::LangItem(t, None))
+ }
+
+ pub fn ty_rel_path(
+ &self,
+ db: &dyn DefDatabase,
+ start_crate: CrateId,
+ seg: Name,
+ ) -> Option<Path> {
+ let t = db.lang_item(start_crate, *self)?;
+ Some(Path::LangItem(t, Some(seg)))
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index 1901db8a0..3f87fe62b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -109,6 +109,17 @@ impl CrateRootModuleId {
}
}
+impl PartialEq<ModuleId> for CrateRootModuleId {
+ fn eq(&self, other: &ModuleId) -> bool {
+ other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate
+ }
+}
+impl PartialEq<CrateRootModuleId> for ModuleId {
+ fn eq(&self, other: &CrateRootModuleId) -> bool {
+ other == self
+ }
+}
+
impl From<CrateRootModuleId> for ModuleId {
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
ModuleId { krate, block: None, local_id: DefMap::ROOT }
@@ -854,14 +865,36 @@ impl_from!(
ConstId,
FunctionId,
TraitId,
+ TraitAliasId,
TypeAliasId,
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
ImplId,
GenericParamId,
- ExternCrateId
+ ExternCrateId,
+ UseId
for AttrDefId
);
+impl TryFrom<ModuleDefId> for AttrDefId {
+ type Error = ();
+
+ fn try_from(value: ModuleDefId) -> Result<Self, Self::Error> {
+ match value {
+ ModuleDefId::ModuleId(it) => Ok(it.into()),
+ ModuleDefId::FunctionId(it) => Ok(it.into()),
+ ModuleDefId::AdtId(it) => Ok(it.into()),
+ ModuleDefId::EnumVariantId(it) => Ok(it.into()),
+ ModuleDefId::ConstId(it) => Ok(it.into()),
+ ModuleDefId::StaticId(it) => Ok(it.into()),
+ ModuleDefId::TraitId(it) => Ok(it.into()),
+ ModuleDefId::TypeAliasId(it) => Ok(it.into()),
+ ModuleDefId::TraitAliasId(id) => Ok(id.into()),
+ ModuleDefId::MacroId(id) => Ok(id.into()),
+ ModuleDefId::BuiltinType(_) => Err(()),
+ }
+ }
+}
+
impl From<ItemContainerId> for AttrDefId {
fn from(acid: ItemContainerId) -> Self {
match acid {
@@ -872,6 +905,15 @@ impl From<ItemContainerId> for AttrDefId {
}
}
}
+impl From<AssocItemId> for AttrDefId {
+ fn from(assoc: AssocItemId) -> Self {
+ match assoc {
+ AssocItemId::FunctionId(it) => AttrDefId::FunctionId(it),
+ AssocItemId::ConstId(it) => AttrDefId::ConstId(it),
+ AssocItemId::TypeAliasId(it) => AttrDefId::TypeAliasId(it),
+ }
+ }
+}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VariantId {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/lower.rs
index e523c2291..52781d988 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lower.rs
@@ -1,10 +1,11 @@
//! Context for lowering paths.
+use std::cell::OnceCell;
+
use hir_expand::{
ast_id_map::{AstIdMap, AstIdNode},
hygiene::Hygiene,
AstId, HirFileId, InFile,
};
-use once_cell::unsync::OnceCell;
use syntax::ast;
use triomphe::Arc;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index 1250cbb74..4aedb22c6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -23,6 +23,45 @@ fn main() { 0 as u32; }
}
#[test]
+fn test_asm_expand() {
+ check(
+ r#"
+#[rustc_builtin_macro]
+macro_rules! asm {() => {}}
+
+fn main() {
+ let i: u64 = 3;
+ let o: u64;
+ unsafe {
+ asm!(
+ "mov {0}, {1}",
+ "add {0}, 5",
+ out(reg) o,
+ in(reg) i,
+ );
+ }
+}
+"#,
+ expect![[r##"
+#[rustc_builtin_macro]
+macro_rules! asm {() => {}}
+
+fn main() {
+ let i: u64 = 3;
+ let o: u64;
+ unsafe {
+ builtin #asm ( {
+ $crate::format_args!("mov {0}, {1}");
+ $crate::format_args!("add {0}, 5");
+ }
+ );
+ }
+}
+"##]],
+ );
+}
+
+#[test]
fn test_line_expand() {
check(
r#"
@@ -201,7 +240,7 @@ macro_rules! format_args {
}
fn main() {
- ::core::fmt::Arguments::new_v1(&["", " ", ], &[::core::fmt::ArgumentV1::new(&(arg1(a, b, c)), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(arg2), ::core::fmt::Debug::fmt), ]);
+ builtin #format_args ("{} {:?}", arg1(a, b, c), arg2);
}
"##]],
);
@@ -219,10 +258,10 @@ macro_rules! format_args {
fn main() {
format_args!(x = 2);
- format_args!(x =);
- format_args!(x =, x = 2);
- format_args!("{}", x =);
- format_args!(=, "{}", x =);
+ format_args!/*+errors*/(x =);
+ format_args!/*+errors*/(x =, x = 2);
+ format_args!/*+errors*/("{}", x =);
+ format_args!/*+errors*/(=, "{}", x =);
format_args!(x = 2, "{}", 5);
}
"#,
@@ -234,12 +273,19 @@ macro_rules! format_args {
}
fn main() {
- /* error: no rule matches input tokens */;
- /* error: expected expression */;
- /* error: expected expression, expected COMMA */;
- /* error: expected expression */::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(), ::core::fmt::Display::fmt), ]);
- /* error: expected expression, expected expression */;
- ::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(5), ::core::fmt::Display::fmt), ]);
+ builtin #format_args (x = 2);
+ /* parse error: expected expression */
+builtin #format_args (x = );
+ /* parse error: expected expression */
+/* parse error: expected R_PAREN */
+/* parse error: expected expression, item or let statement */
+builtin #format_args (x = , x = 2);
+ /* parse error: expected expression */
+builtin #format_args ("{}", x = );
+ /* parse error: expected expression */
+/* parse error: expected expression */
+builtin #format_args ( = , "{}", x = );
+ builtin #format_args (x = 2, "{}", 5);
}
"##]],
);
@@ -267,7 +313,7 @@ macro_rules! format_args {
}
fn main() {
- ::core::fmt::Arguments::new_v1(&["", " ", ], &[::core::fmt::ArgumentV1::new(&(a::<A, B>()), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(b), ::core::fmt::Debug::fmt), ]);
+ builtin #format_args ("{} {:?}", a::<A, B>(), b);
}
"##]],
);
@@ -300,7 +346,7 @@ macro_rules! format_args {
}
fn main() {
- ::core::fmt::Arguments::new_v1(&[r#""#, r#",mismatch,""#, r#"",""#, r#"""#, ], &[::core::fmt::ArgumentV1::new(&(location_csv_pat(db, &analysis, vfs, &sm, pat_id)), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(mismatch.expected.display(db)), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(mismatch.actual.display(db)), ::core::fmt::Display::fmt), ]);
+ builtin #format_args (r#"{},mismatch,"{}","{}""#, location_csv_pat(db, &analysis, vfs, &sm, pat_id), mismatch.expected.display(db), mismatch.actual.display(db));
}
"##]],
);
@@ -334,7 +380,7 @@ macro_rules! format_args {
}
fn main() {
- ::core::fmt::Arguments::new_v1(&["xxx", "y", "zzz", ], &[::core::fmt::ArgumentV1::new(&(2), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(b), ::core::fmt::Debug::fmt), ]);
+ builtin #format_args (concat!("xxx{}y", "{:?}zzz"), 2, b);
}
"##]],
);
@@ -364,8 +410,8 @@ macro_rules! format_args {
fn main() {
let _ =
- /* error: expected field name or number *//* parse error: expected field name or number */
-::core::fmt::Arguments::new_v1(&["", " ", ], &[::core::fmt::ArgumentV1::new(&(a.), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(), ::core::fmt::Debug::fmt), ]);
+ /* parse error: expected field name or number */
+builtin #format_args ("{} {:?}", a.);
}
"##]],
);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
index 2170cadcf..d09062132 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -117,7 +117,7 @@ fn main(foo: ()) {
macro_rules! format_args {}
fn main(foo: ()) {
- /* error: unresolved macro identity */::core::fmt::Arguments::new_v1(&["", " ", " ", ], &[::core::fmt::ArgumentV1::new(&(::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(0), ::core::fmt::Display::fmt), ])), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(foo), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(identity!(10)), ::core::fmt::Display::fmt), ])
+ builtin #format_args ("{} {} {}", format_args!("{}", 0), foo, identity!(10), "bar")
}
"##]],
);
@@ -150,8 +150,8 @@ macro_rules! identity {
}
fn main(foo: ()) {
- // format_args/*+tokenids*/!("{} {} {}"#1,#3 format_args!("{}", 0#10),#12 foo#13,#14 identity!(10#18),#21 "bar"#22)
-::core#4294967295::fmt#4294967295::Arguments#4294967295::new_v1#4294967295(&#4294967295[#4294967295""#4294967295,#4294967295 " "#4294967295,#4294967295 " "#4294967295,#4294967295 ]#4294967295,#4294967295 &#4294967295[::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(::core#4294967295::fmt#4294967295::Arguments#4294967295::new_v1#4294967295(&#4294967295[#4294967295""#4294967295,#4294967295 ]#4294967295,#4294967295 &#4294967295[::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(#42949672950#10)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ]#4294967295)#4294967295)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(#4294967295foo#13)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(#429496729510#18)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ]#4294967295)#4294967295
+ // format_args/*+tokenids*/!("{} {} {}"#1,#2 format_args#3!#4("{}"#6,#7 0#8),#9 foo#10,#11 identity#12!#13(10#15),#16 "bar"#17)
+builtin#4294967295 ##4294967295format_args#4294967295 (#0"{} {} {}"#1,#2 format_args#3!#4(#5"{}"#6,#7 0#8)#5,#9 foo#10,#11 identity#12!#13(#1410#15)#14,#16 "bar"#17)#0
}
"##]],
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index d8e4a4dcc..b416f45ff 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -909,3 +909,64 @@ macro_rules! with_std {
"##]],
)
}
+
+#[test]
+fn eager_regression_15403() {
+ check(
+ r#"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+ format_args /* +errors */ !("{}", line.1.);
+}
+
+"#,
+ expect![[r##"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+ /* parse error: expected field name or number */
+builtin #format_args ("{}", line.1.);
+}
+
+"##]],
+ );
+}
+
+#[test]
+fn eager_regression_154032() {
+ check(
+ r#"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+ format_args /* +errors */ !("{}", &[0 2]);
+}
+
+"#,
+ expect![[r##"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+ /* parse error: expected COMMA */
+/* parse error: expected R_BRACK */
+/* parse error: expected COMMA */
+/* parse error: expected COMMA */
+/* parse error: expected expression */
+/* parse error: expected R_PAREN */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+builtin #format_args ("{}", &[0 2]);
+}
+
+"##]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
index 7a87e61c6..8adced4e0 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -131,7 +131,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
.as_call_id_with_errors(&db, krate, |path| {
resolver
.resolve_path_as_macro(&db, &path, Some(MacroSubNs::Bang))
- .map(|it| macro_id_to_def_id(&db, it))
+ .map(|(it, _)| macro_id_to_def_id(&db, it))
})
.unwrap();
let macro_call_id = res.value.unwrap();
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
index 86818ce26..9a9fa0e02 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
@@ -60,7 +60,7 @@ mod tests;
use std::{cmp::Ord, ops::Deref};
use base_db::{CrateId, Edition, FileId, ProcMacroKind};
-use hir_expand::{name::Name, HirFileId, InFile, MacroCallId, MacroDefId};
+use hir_expand::{ast_id_map::FileAstId, name::Name, HirFileId, InFile, MacroCallId, MacroDefId};
use itertools::Itertools;
use la_arena::Arena;
use profile::Count;
@@ -77,8 +77,8 @@ use crate::{
path::ModPath,
per_ns::PerNs,
visibility::Visibility,
- AstId, BlockId, BlockLoc, CrateRootModuleId, FunctionId, LocalModuleId, Lookup, MacroExpander,
- MacroId, ModuleId, ProcMacroId,
+ AstId, BlockId, BlockLoc, CrateRootModuleId, ExternCrateId, FunctionId, LocalModuleId, Lookup,
+ MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
};
/// Contains the results of (early) name resolution.
@@ -93,7 +93,7 @@ use crate::{
#[derive(Debug, PartialEq, Eq)]
pub struct DefMap {
_c: Count<Self>,
- /// When this is a block def map, this will hold the block id of the the block and module that
+ /// When this is a block def map, this will hold the block id of the block and module that
/// contains this block.
block: Option<BlockInfo>,
/// The modules and their data declared in this crate.
@@ -105,10 +105,11 @@ pub struct DefMap {
/// The prelude is empty for non-block DefMaps (unless `#[prelude_import]` was used,
/// but that attribute is nightly and when used in a block, it affects resolution globally
/// so we aren't handling this correctly anyways).
- prelude: Option<ModuleId>,
+ prelude: Option<(ModuleId, Option<UseId>)>,
/// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that
/// this contains all kinds of macro, not just `macro_rules!` macro.
- macro_use_prelude: FxHashMap<Name, MacroId>,
+ /// ExternCrateId being None implies it being imported from the general prelude import.
+ macro_use_prelude: FxHashMap<Name, (MacroId, Option<ExternCrateId>)>,
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
/// attributes.
@@ -125,7 +126,7 @@ pub struct DefMap {
#[derive(Clone, Debug, PartialEq, Eq)]
struct DefMapCrateData {
/// The extern prelude which contains all root modules of external crates that are in scope.
- extern_prelude: FxHashMap<Name, CrateRootModuleId>,
+ extern_prelude: FxHashMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
/// Side table for resolving derive helpers.
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
@@ -217,16 +218,17 @@ pub enum ModuleOrigin {
/// Note that non-inline modules, by definition, live inside non-macro file.
File {
is_mod_rs: bool,
- declaration: AstId<ast::Module>,
+ declaration: FileAstId<ast::Module>,
declaration_tree_id: ItemTreeId<Mod>,
definition: FileId,
},
Inline {
definition_tree_id: ItemTreeId<Mod>,
- definition: AstId<ast::Module>,
+ definition: FileAstId<ast::Module>,
},
/// Pseudo-module introduced by a block scope (contains only inner items).
BlockExpr {
+ id: BlockId,
block: AstId<ast::BlockExpr>,
},
}
@@ -234,8 +236,12 @@ pub enum ModuleOrigin {
impl ModuleOrigin {
pub fn declaration(&self) -> Option<AstId<ast::Module>> {
match self {
- ModuleOrigin::File { declaration: module, .. }
- | ModuleOrigin::Inline { definition: module, .. } => Some(*module),
+ &ModuleOrigin::File { declaration, declaration_tree_id, .. } => {
+ Some(AstId::new(declaration_tree_id.file_id(), declaration))
+ }
+ &ModuleOrigin::Inline { definition, definition_tree_id } => {
+ Some(AstId::new(definition_tree_id.file_id(), definition))
+ }
ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None,
}
}
@@ -260,16 +266,17 @@ impl ModuleOrigin {
/// That is, a file or a `mod foo {}` with items.
fn definition_source(&self, db: &dyn DefDatabase) -> InFile<ModuleSource> {
match self {
- ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
- let file_id = *definition;
- let sf = db.parse(file_id).tree();
- InFile::new(file_id.into(), ModuleSource::SourceFile(sf))
+ &ModuleOrigin::File { definition, .. } | &ModuleOrigin::CrateRoot { definition } => {
+ let sf = db.parse(definition).tree();
+ InFile::new(definition.into(), ModuleSource::SourceFile(sf))
}
- ModuleOrigin::Inline { definition, .. } => InFile::new(
- definition.file_id,
- ModuleSource::Module(definition.to_node(db.upcast())),
+ &ModuleOrigin::Inline { definition, definition_tree_id } => InFile::new(
+ definition_tree_id.file_id(),
+ ModuleSource::Module(
+ AstId::new(definition_tree_id.file_id(), definition).to_node(db.upcast()),
+ ),
),
- ModuleOrigin::BlockExpr { block } => {
+ ModuleOrigin::BlockExpr { block, .. } => {
InFile::new(block.file_id, ModuleSource::BlockExpr(block.to_node(db.upcast())))
}
}
@@ -314,9 +321,7 @@ impl DefMap {
}
pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
- let block: BlockLoc = db.lookup_intern_block(block_id);
-
- let tree_id = TreeId::new(block.ast_id.file_id, Some(block_id));
+ let block: BlockLoc = block_id.lookup(db);
let parent_map = block.module.def_map(db);
let krate = block.module.krate;
@@ -325,8 +330,10 @@ impl DefMap {
// modules declared by blocks with items. At the moment, we don't use
// this visibility for anything outside IDE, so that's probably OK.
let visibility = Visibility::Module(ModuleId { krate, local_id, block: None });
- let module_data =
- ModuleData::new(ModuleOrigin::BlockExpr { block: block.ast_id }, visibility);
+ let module_data = ModuleData::new(
+ ModuleOrigin::BlockExpr { block: block.ast_id, id: block_id },
+ visibility,
+ );
let mut def_map = DefMap::empty(krate, parent_map.data.edition, module_data);
def_map.data = parent_map.data.clone();
@@ -338,7 +345,8 @@ impl DefMap {
},
});
- let def_map = collector::collect_defs(db, def_map, tree_id);
+ let def_map =
+ collector::collect_defs(db, def_map, TreeId::new(block.ast_id.file_id, Some(block_id)));
Arc::new(def_map)
}
@@ -427,15 +435,19 @@ impl DefMap {
self.block.map(|block| block.block)
}
- pub(crate) fn prelude(&self) -> Option<ModuleId> {
+ pub(crate) fn prelude(&self) -> Option<(ModuleId, Option<UseId>)> {
self.prelude
}
- pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
- self.data.extern_prelude.iter().map(|(name, &def)| (name, def.into()))
+ pub(crate) fn extern_prelude(
+ &self,
+ ) -> impl Iterator<Item = (&Name, (CrateRootModuleId, Option<ExternCrateId>))> + '_ {
+ self.data.extern_prelude.iter().map(|(name, &def)| (name, def))
}
- pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
+ pub(crate) fn macro_use_prelude(
+ &self,
+ ) -> impl Iterator<Item = (&Name, (MacroId, Option<ExternCrateId>))> + '_ {
self.macro_use_prelude.iter().map(|(name, &def)| (name, def))
}
@@ -638,8 +650,8 @@ impl ModuleData {
ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
definition.into()
}
- ModuleOrigin::Inline { definition, .. } => definition.file_id,
- ModuleOrigin::BlockExpr { block } => block.file_id,
+ ModuleOrigin::Inline { definition_tree_id, .. } => definition_tree_id.file_id(),
+ ModuleOrigin::BlockExpr { block, .. } => block.file_id,
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index eef54fc49..2d4586146 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -33,7 +33,7 @@ use crate::{
attr_macro_as_call_id,
db::DefDatabase,
derive_macro_as_call_id,
- item_scope::{ImportType, PerNsGlobImports},
+ item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
item_tree::{
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
@@ -52,10 +52,10 @@ use crate::{
tt,
visibility::{RawVisibility, Visibility},
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
- ExternBlockLoc, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId,
- LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc,
- ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc,
- TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseLoc,
+ ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
+ ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId,
+ MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc,
+ StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
};
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
@@ -146,8 +146,8 @@ impl PartialResolvedImport {
#[derive(Clone, Debug, Eq, PartialEq)]
enum ImportSource {
- Use { id: ItemTreeId<item_tree::Use>, use_tree: Idx<ast::UseTree> },
- ExternCrate(ItemTreeId<item_tree::ExternCrate>),
+ Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool, kind: ImportKind },
+ ExternCrate { id: ExternCrateId },
}
#[derive(Debug, Eq, PartialEq)]
@@ -155,54 +155,41 @@ struct Import {
path: ModPath,
alias: Option<ImportAlias>,
visibility: RawVisibility,
- kind: ImportKind,
source: ImportSource,
- is_prelude: bool,
- is_macro_use: bool,
}
impl Import {
fn from_use(
- db: &dyn DefDatabase,
- krate: CrateId,
tree: &ItemTree,
- id: ItemTreeId<item_tree::Use>,
+ item_tree_id: ItemTreeId<item_tree::Use>,
+ id: UseId,
+ is_prelude: bool,
mut cb: impl FnMut(Self),
) {
- let it = &tree[id.value];
- let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
+ let it = &tree[item_tree_id.value];
let visibility = &tree[it.visibility];
- let is_prelude = attrs.by_key("prelude_import").exists();
it.use_tree.expand(|idx, path, kind, alias| {
cb(Self {
path,
alias,
visibility: visibility.clone(),
- kind,
- is_prelude,
- is_macro_use: false,
- source: ImportSource::Use { id, use_tree: idx },
+ source: ImportSource::Use { use_tree: idx, id, is_prelude, kind },
});
});
}
fn from_extern_crate(
- db: &dyn DefDatabase,
- krate: CrateId,
tree: &ItemTree,
- id: ItemTreeId<item_tree::ExternCrate>,
+ item_tree_id: ItemTreeId<item_tree::ExternCrate>,
+ id: ExternCrateId,
) -> Self {
- let it = &tree[id.value];
- let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
+ let it = &tree[item_tree_id.value];
let visibility = &tree[it.visibility];
Self {
path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
alias: it.alias.clone(),
visibility: visibility.clone(),
- kind: ImportKind::Plain,
- is_prelude: false,
- is_macro_use: attrs.by_key("macro_use").exists(),
- source: ImportSource::ExternCrate(id),
+ source: ImportSource::ExternCrate { id },
}
}
}
@@ -235,7 +222,7 @@ struct DefCollector<'a> {
db: &'a dyn DefDatabase,
def_map: DefMap,
deps: FxHashMap<Name, Dependency>,
- glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
+ glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>,
unresolved_imports: Vec<ImportDirective>,
indeterminate_imports: Vec<ImportDirective>,
unresolved_macros: Vec<MacroDirective>,
@@ -280,7 +267,7 @@ impl DefCollector<'_> {
if dep.is_prelude() {
crate_data
.extern_prelude
- .insert(name.clone(), CrateRootModuleId { krate: dep.crate_id });
+ .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
}
}
@@ -556,8 +543,12 @@ impl DefCollector<'_> {
self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
match per_ns.types {
- Some((ModuleDefId::ModuleId(m), _)) => {
- self.def_map.prelude = Some(m);
+ Some((ModuleDefId::ModuleId(m), _, import)) => {
+ // FIXME: This should specifically look for a glob import somehow and record that here
+ self.def_map.prelude = Some((
+ m,
+ import.and_then(ImportOrExternCrate::into_import).map(|it| it.import),
+ ));
}
types => {
tracing::debug!(
@@ -657,9 +648,9 @@ impl DefCollector<'_> {
self.def_map.modules[module_id].scope.declare(macro_.into());
self.update(
module_id,
- &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+ &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
Visibility::Public,
- ImportType::Named,
+ None,
);
}
}
@@ -693,9 +684,9 @@ impl DefCollector<'_> {
self.def_map.modules[module_id].scope.declare(macro_.into());
self.update(
module_id,
- &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+ &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
vis,
- ImportType::Named,
+ None,
);
}
@@ -708,9 +699,9 @@ impl DefCollector<'_> {
self.def_map.modules[module_id].scope.declare(macro_.into());
self.update(
module_id,
- &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+ &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
Visibility::Public,
- ImportType::Named,
+ None,
);
}
@@ -720,21 +711,29 @@ impl DefCollector<'_> {
/// Exported macros are just all macros in the root module scope.
/// Note that it contains not only all `#[macro_export]` macros, but also all aliases
/// created by `use` in the root module, ignoring the visibility of `use`.
- fn import_macros_from_extern_crate(&mut self, krate: CrateId, names: Option<Vec<Name>>) {
+ fn import_macros_from_extern_crate(
+ &mut self,
+ krate: CrateId,
+ names: Option<Vec<Name>>,
+ extern_crate: Option<ExternCrateId>,
+ ) {
let def_map = self.db.crate_def_map(krate);
// `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
// macros.
let root_scope = &def_map[DefMap::ROOT].scope;
- if let Some(names) = names {
- for name in names {
- // FIXME: Report diagnostic on 404.
- if let Some(def) = root_scope.get(&name).take_macros() {
- self.def_map.macro_use_prelude.insert(name, def);
+ match names {
+ Some(names) => {
+ for name in names {
+ // FIXME: Report diagnostic on 404.
+ if let Some(def) = root_scope.get(&name).take_macros() {
+ self.def_map.macro_use_prelude.insert(name, (def, extern_crate));
+ }
}
}
- } else {
- for (name, def) in root_scope.macros() {
- self.def_map.macro_use_prelude.insert(name.clone(), def);
+ None => {
+ for (name, def) in root_scope.macros() {
+ self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
+ }
}
}
}
@@ -771,48 +770,53 @@ impl DefCollector<'_> {
let _p = profile::span("resolve_import")
.detail(|| format!("{}", import.path.display(self.db.upcast())));
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
- if matches!(import.source, ImportSource::ExternCrate { .. }) {
- let name = import
- .path
- .as_ident()
- .expect("extern crate should have been desugared to one-element path");
-
- let res = self.resolve_extern_crate(name);
-
- match res {
- Some(res) => {
- PartialResolvedImport::Resolved(PerNs::types(res.into(), Visibility::Public))
+ match import.source {
+ ImportSource::ExternCrate { .. } => {
+ let name = import
+ .path
+ .as_ident()
+ .expect("extern crate should have been desugared to one-element path");
+
+ let res = self.resolve_extern_crate(name);
+
+ match res {
+ Some(res) => PartialResolvedImport::Resolved(PerNs::types(
+ res.into(),
+ Visibility::Public,
+ None,
+ )),
+ None => PartialResolvedImport::Unresolved,
}
- None => PartialResolvedImport::Unresolved,
}
- } else {
- let res = self.def_map.resolve_path_fp_with_macro(
- self.db,
- ResolveMode::Import,
- module_id,
- &import.path,
- BuiltinShadowMode::Module,
- None, // An import may resolve to any kind of macro.
- );
+ ImportSource::Use { .. } => {
+ let res = self.def_map.resolve_path_fp_with_macro(
+ self.db,
+ ResolveMode::Import,
+ module_id,
+ &import.path,
+ BuiltinShadowMode::Module,
+ None, // An import may resolve to any kind of macro.
+ );
- let def = res.resolved_def;
- if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
- return PartialResolvedImport::Unresolved;
- }
+ let def = res.resolved_def;
+ if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
+ return PartialResolvedImport::Unresolved;
+ }
- if let Some(krate) = res.krate {
- if krate != self.def_map.krate {
- return PartialResolvedImport::Resolved(
- def.filter_visibility(|v| matches!(v, Visibility::Public)),
- );
+ if let Some(krate) = res.krate {
+ if krate != self.def_map.krate {
+ return PartialResolvedImport::Resolved(
+ def.filter_visibility(|v| matches!(v, Visibility::Public)),
+ );
+ }
}
- }
- // Check whether all namespaces are resolved.
- if def.is_full() {
- PartialResolvedImport::Resolved(def)
- } else {
- PartialResolvedImport::Indeterminate(def)
+ // Check whether all namespaces are resolved.
+ if def.is_full() {
+ PartialResolvedImport::Resolved(def)
+ } else {
+ PartialResolvedImport::Indeterminate(def)
+ }
}
}
}
@@ -837,8 +841,9 @@ impl DefCollector<'_> {
.resolve_visibility(self.db, module_id, &directive.import.visibility, false)
.unwrap_or(Visibility::Public);
- match import.kind {
- ImportKind::Plain | ImportKind::TypeOnly => {
+ match import.source {
+ ImportSource::ExternCrate { .. }
+ | ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => {
let name = match &import.alias {
Some(ImportAlias::Alias(name)) => Some(name),
Some(ImportAlias::Underscore) => None,
@@ -851,40 +856,44 @@ impl DefCollector<'_> {
},
};
- if import.kind == ImportKind::TypeOnly {
- def.values = None;
- def.macros = None;
- }
-
- tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
-
- // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
- if matches!(import.source, ImportSource::ExternCrate { .. })
- && self.def_map.block.is_none()
- && module_id == DefMap::ROOT
- {
- if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
- {
- if let Ok(def) = def.try_into() {
- Arc::get_mut(&mut self.def_map.data)
- .unwrap()
- .extern_prelude
- .insert(name.clone(), def);
+ let imp = match import.source {
+ // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
+ ImportSource::ExternCrate { id, .. } => {
+ if self.def_map.block.is_none() && module_id == DefMap::ROOT {
+ if let (Some(ModuleDefId::ModuleId(def)), Some(name)) =
+ (def.take_types(), name)
+ {
+ if let Ok(def) = def.try_into() {
+ Arc::get_mut(&mut self.def_map.data)
+ .unwrap()
+ .extern_prelude
+ .insert(name.clone(), (def, Some(id)));
+ }
+ }
}
+ ImportType::ExternCrate(id)
}
- }
+ ImportSource::Use { kind, id, use_tree, .. } => {
+ if kind == ImportKind::TypeOnly {
+ def.values = None;
+ def.macros = None;
+ }
+ ImportType::Import(ImportId { import: id, idx: use_tree })
+ }
+ };
+ tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
- self.update(module_id, &[(name.cloned(), def)], vis, ImportType::Named);
+ self.update(module_id, &[(name.cloned(), def)], vis, Some(imp));
}
- ImportKind::Glob => {
+ ImportSource::Use { kind: ImportKind::Glob, id, .. } => {
tracing::debug!("glob import: {:?}", import);
match def.take_types() {
Some(ModuleDefId::ModuleId(m)) => {
- if import.is_prelude {
+ if let ImportSource::Use { id, is_prelude: true, .. } = import.source {
// Note: This dodgily overrides the injected prelude. The rustc
// implementation seems to work the same though.
cov_mark::hit!(std_prelude);
- self.def_map.prelude = Some(m);
+ self.def_map.prelude = Some((m, Some(id)));
} else if m.krate != self.def_map.krate {
cov_mark::hit!(glob_across_crates);
// glob import from other crate => we can just import everything once
@@ -901,7 +910,7 @@ impl DefCollector<'_> {
.filter(|(_, res)| !res.is_none())
.collect::<Vec<_>>();
- self.update(module_id, &items, vis, ImportType::Glob);
+ self.update(module_id, &items, vis, Some(ImportType::Glob(id)));
} else {
// glob import from same crate => we do an initial
// import, and then need to propagate any further
@@ -933,11 +942,11 @@ impl DefCollector<'_> {
.filter(|(_, res)| !res.is_none())
.collect::<Vec<_>>();
- self.update(module_id, &items, vis, ImportType::Glob);
+ self.update(module_id, &items, vis, Some(ImportType::Glob(id)));
// record the glob import in case we add further items
let glob = self.glob_imports.entry(m.local_id).or_default();
- if !glob.iter().any(|(mid, _)| *mid == module_id) {
- glob.push((module_id, vis));
+ if !glob.iter().any(|(mid, _, _)| *mid == module_id) {
+ glob.push((module_id, vis, id));
}
}
}
@@ -959,11 +968,11 @@ impl DefCollector<'_> {
.map(|(local_id, variant_data)| {
let name = variant_data.name.clone();
let variant = EnumVariantId { parent: e, local_id };
- let res = PerNs::both(variant.into(), variant.into(), vis);
+ let res = PerNs::both(variant.into(), variant.into(), vis, None);
(Some(name), res)
})
.collect::<Vec<_>>();
- self.update(module_id, &resolutions, vis, ImportType::Glob);
+ self.update(module_id, &resolutions, vis, Some(ImportType::Glob(id)));
}
Some(d) => {
tracing::debug!("glob import {:?} from non-module/enum {:?}", import, d);
@@ -983,10 +992,10 @@ impl DefCollector<'_> {
resolutions: &[(Option<Name>, PerNs)],
// Visibility this import will have
vis: Visibility,
- import_type: ImportType,
+ import: Option<ImportType>,
) {
self.db.unwind_if_cancelled();
- self.update_recursive(module_id, resolutions, vis, import_type, 0)
+ self.update_recursive(module_id, resolutions, vis, import, 0)
}
fn update_recursive(
@@ -997,7 +1006,7 @@ impl DefCollector<'_> {
// All resolutions are imported with this visibility; the visibilities in
// the `PerNs` values are ignored and overwritten
vis: Visibility,
- import_type: ImportType,
+ import: Option<ImportType>,
depth: usize,
) {
if GLOB_RECURSION_LIMIT.check(depth).is_err() {
@@ -1014,7 +1023,7 @@ impl DefCollector<'_> {
&mut self.from_glob_import,
(module_id, name.clone()),
res.with_visibility(vis),
- import_type,
+ import,
);
}
None => {
@@ -1059,7 +1068,7 @@ impl DefCollector<'_> {
.get(&module_id)
.into_iter()
.flatten()
- .filter(|(glob_importing_module, _)| {
+ .filter(|(glob_importing_module, _, _)| {
// we know all resolutions have the same visibility (`vis`), so we
// just need to check that once
vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module)
@@ -1067,12 +1076,12 @@ impl DefCollector<'_> {
.cloned()
.collect::<Vec<_>>();
- for (glob_importing_module, glob_import_vis) in glob_imports {
+ for (glob_importing_module, glob_import_vis, use_) in glob_imports {
self.update_recursive(
glob_importing_module,
resolutions,
glob_import_vis,
- ImportType::Glob,
+ Some(ImportType::Glob(use_)),
depth + 1,
);
}
@@ -1460,31 +1469,34 @@ impl DefCollector<'_> {
// heuristic, but it works in practice.
let mut diagnosed_extern_crates = FxHashSet::default();
for directive in &self.unresolved_imports {
- if let ImportSource::ExternCrate(krate) = directive.import.source {
- let item_tree = krate.item_tree(self.db);
- let extern_crate = &item_tree[krate.value];
+ if let ImportSource::ExternCrate { id } = directive.import.source {
+ let item_tree_id = id.lookup(self.db).id;
+ let item_tree = item_tree_id.item_tree(self.db);
+ let extern_crate = &item_tree[item_tree_id.value];
diagnosed_extern_crates.insert(extern_crate.name.clone());
self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate(
directive.module_id,
- InFile::new(krate.file_id(), extern_crate.ast_id),
+ InFile::new(item_tree_id.file_id(), extern_crate.ast_id),
));
}
}
for directive in &self.unresolved_imports {
- if let ImportSource::Use { id: import, use_tree } = directive.import.source {
+ if let ImportSource::Use { use_tree, id, is_prelude: _, kind: _ } =
+ directive.import.source
+ {
if matches!(
(directive.import.path.segments().first(), &directive.import.path.kind),
(Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate)
) {
continue;
}
-
+ let item_tree_id = id.lookup(self.db).id;
self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
directive.module_id,
- import,
+ item_tree_id,
use_tree,
));
}
@@ -1519,72 +1531,66 @@ impl ModCollector<'_, '_> {
self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
// Prelude module is always considered to be `#[macro_use]`.
- if let Some(prelude_module) = self.def_collector.def_map.prelude {
+ if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude {
if prelude_module.krate != krate && is_crate_root {
cov_mark::hit!(prelude_is_macro_use);
- self.def_collector.import_macros_from_extern_crate(prelude_module.krate, None);
- }
- }
-
- // This should be processed eagerly instead of deferred to resolving.
- // `#[macro_use] extern crate` is hoisted to imports macros before collecting
- // any other items.
- //
- // If we're not at the crate root, `macro_use`d extern crates are an error so let's just
- // ignore them.
- if is_crate_root {
- for &item in items {
- if let ModItem::ExternCrate(id) = item {
- self.process_macro_use_extern_crate(id);
- }
+ self.def_collector.import_macros_from_extern_crate(
+ prelude_module.krate,
+ None,
+ None,
+ );
}
}
+ let db = self.def_collector.db;
+ let module_id = self.module_id;
+ let update_def =
+ |def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| {
+ def_collector.def_map.modules[module_id].scope.declare(id);
+ def_collector.update(
+ module_id,
+ &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor, None))],
+ vis,
+ None,
+ )
+ };
+ let resolve_vis = |def_map: &DefMap, visibility| {
+ def_map
+ .resolve_visibility(db, module_id, visibility, false)
+ .unwrap_or(Visibility::Public)
+ };
- for &item in items {
- let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
+ let mut process_mod_item = |item: ModItem| {
+ let attrs = self.item_tree.attrs(db, krate, item.into());
if let Some(cfg) = attrs.cfg() {
if !self.is_cfg_enabled(&cfg) {
self.emit_unconfigured_diagnostic(item, &cfg);
- continue;
+ return;
}
}
if let Err(()) = self.resolve_attributes(&attrs, item, container) {
// Do not process the item. It has at least one non-builtin attribute, so the
// fixed-point algorithm is required to resolve the rest of them.
- continue;
+ return;
}
- let db = self.def_collector.db;
- let module = self.def_collector.def_map.module_id(self.module_id);
+ let module = self.def_collector.def_map.module_id(module_id);
let def_map = &mut self.def_collector.def_map;
- let update_def =
- |def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| {
- def_collector.def_map.modules[self.module_id].scope.declare(id);
- def_collector.update(
- self.module_id,
- &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
- vis,
- ImportType::Named,
- )
- };
- let resolve_vis = |def_map: &DefMap, visibility| {
- def_map
- .resolve_visibility(db, self.module_id, visibility, false)
- .unwrap_or(Visibility::Public)
- };
match item {
ModItem::Mod(m) => self.collect_module(m, &attrs),
- ModItem::Use(import_id) => {
- let _import_id =
- UseLoc { container: module, id: ItemTreeId::new(self.tree_id, import_id) }
- .intern(db);
+ ModItem::Use(item_tree_id) => {
+ let id = UseLoc {
+ container: module,
+ id: ItemTreeId::new(self.tree_id, item_tree_id),
+ }
+ .intern(db);
+ let is_prelude = attrs.by_key("prelude_import").exists();
Import::from_use(
- db,
- krate,
self.item_tree,
- ItemTreeId::new(self.tree_id, import_id),
+ ItemTreeId::new(self.tree_id, item_tree_id),
+ id,
+ is_prelude,
|import| {
self.def_collector.unresolved_imports.push(ImportDirective {
module_id: self.module_id,
@@ -1594,22 +1600,29 @@ impl ModCollector<'_, '_> {
},
)
}
- ModItem::ExternCrate(import_id) => {
- let extern_crate_id = ExternCrateLoc {
+ ModItem::ExternCrate(item_tree_id) => {
+ let id = ExternCrateLoc {
container: module,
- id: ItemTreeId::new(self.tree_id, import_id),
+ id: ItemTreeId::new(self.tree_id, item_tree_id),
}
.intern(db);
+ if is_crate_root {
+ self.process_macro_use_extern_crate(
+ item_tree_id,
+ id,
+ attrs.by_key("macro_use").attrs(),
+ );
+ }
+
self.def_collector.def_map.modules[self.module_id]
.scope
- .define_extern_crate_decl(extern_crate_id);
+ .define_extern_crate_decl(id);
self.def_collector.unresolved_imports.push(ImportDirective {
module_id: self.module_id,
import: Import::from_extern_crate(
- db,
- krate,
self.item_tree,
- ItemTreeId::new(self.tree_id, import_id),
+ ItemTreeId::new(self.tree_id, item_tree_id),
+ id,
),
status: PartialResolvedImport::Unresolved,
})
@@ -1768,21 +1781,34 @@ impl ModCollector<'_, '_> {
);
}
}
+ };
+
+ // extern crates should be processed eagerly instead of deferred to resolving.
+ // `#[macro_use] extern crate` is hoisted to imports macros before collecting
+ // any other items.
+ if is_crate_root {
+ items
+ .iter()
+ .filter(|it| matches!(it, ModItem::ExternCrate(..)))
+ .copied()
+ .for_each(&mut process_mod_item);
+ items
+ .iter()
+ .filter(|it| !matches!(it, ModItem::ExternCrate(..)))
+ .copied()
+ .for_each(process_mod_item);
+ } else {
+ items.iter().copied().for_each(process_mod_item);
}
}
- fn process_macro_use_extern_crate(&mut self, extern_crate: FileItemTreeId<ExternCrate>) {
+ fn process_macro_use_extern_crate<'a>(
+ &mut self,
+ extern_crate: FileItemTreeId<ExternCrate>,
+ extern_crate_id: ExternCrateId,
+ macro_use_attrs: impl Iterator<Item = &'a Attr>,
+ ) {
let db = self.def_collector.db;
- let attrs = self.item_tree.attrs(
- db,
- self.def_collector.def_map.krate,
- ModItem::from(extern_crate).into(),
- );
- if let Some(cfg) = attrs.cfg() {
- if !self.is_cfg_enabled(&cfg) {
- return;
- }
- }
let target_crate =
match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) {
@@ -1798,11 +1824,15 @@ impl ModCollector<'_, '_> {
let mut single_imports = Vec::new();
let hygiene = Hygiene::new_unhygienic();
- for attr in attrs.by_key("macro_use").attrs() {
+ for attr in macro_use_attrs {
let Some(paths) = attr.parse_path_comma_token_tree(db.upcast(), &hygiene) else {
// `#[macro_use]` (without any paths) found, forget collected names and just import
// all visible macros.
- self.def_collector.import_macros_from_extern_crate(target_crate, None);
+ self.def_collector.import_macros_from_extern_crate(
+ target_crate,
+ None,
+ Some(extern_crate_id),
+ );
return;
};
for path in paths {
@@ -1812,7 +1842,11 @@ impl ModCollector<'_, '_> {
}
}
- self.def_collector.import_macros_from_extern_crate(target_crate, Some(single_imports));
+ self.def_collector.import_macros_from_extern_crate(
+ target_crate,
+ Some(single_imports),
+ Some(extern_crate_id),
+ );
}
fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) {
@@ -1824,7 +1858,7 @@ impl ModCollector<'_, '_> {
ModKind::Inline { items } => {
let module_id = self.push_child_module(
module.name.clone(),
- AstId::new(self.file_id(), module.ast_id),
+ module.ast_id,
None,
&self.item_tree[module.visibility],
module_id,
@@ -1862,7 +1896,7 @@ impl ModCollector<'_, '_> {
if is_enabled {
let module_id = self.push_child_module(
module.name.clone(),
- ast_id,
+ ast_id.value,
Some((file_id, is_mod_rs)),
&self.item_tree[module.visibility],
module_id,
@@ -1889,7 +1923,7 @@ impl ModCollector<'_, '_> {
Err(candidates) => {
self.push_child_module(
module.name.clone(),
- ast_id,
+ ast_id.value,
None,
&self.item_tree[module.visibility],
module_id,
@@ -1906,7 +1940,7 @@ impl ModCollector<'_, '_> {
fn push_child_module(
&mut self,
name: Name,
- declaration: AstId<ast::Module>,
+ declaration: FileAstId<ast::Module>,
definition: Option<(FileId, bool)>,
visibility: &crate::visibility::RawVisibility,
mod_tree_id: FileItemTreeId<Mod>,
@@ -1948,9 +1982,9 @@ impl ModCollector<'_, '_> {
def_map.modules[self.module_id].scope.declare(def);
self.def_collector.update(
self.module_id,
- &[(Some(name), PerNs::from_def(def, vis, false))],
+ &[(Some(name), PerNs::from_def(def, vis, false, None))],
vis,
- ImportType::Named,
+ None,
);
res
}
@@ -2198,7 +2232,7 @@ impl ModCollector<'_, '_> {
map[module].scope.get_legacy_macro(name)?.last().copied()
})
.or_else(|| def_map[self.module_id].scope.get(name).take_macros())
- .or_else(|| def_map.macro_use_prelude.get(name).copied())
+ .or_else(|| Some(def_map.macro_use_prelude.get(name).copied()?.0))
.filter(|&id| {
sub_namespace_match(
Some(MacroSubNs::from_id(db, id)),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
index de22ea101..460a908b6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
@@ -15,8 +15,9 @@ use hir_expand::name::Name;
use triomphe::Arc;
use crate::{
+ data::adt::VariantData,
db::DefDatabase,
- item_scope::BUILTIN_SCOPE,
+ item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
path::{ModPath, PathKind},
per_ns::PerNs,
@@ -65,7 +66,7 @@ impl PerNs {
db: &dyn DefDatabase,
expected: Option<MacroSubNs>,
) -> Self {
- self.macros = self.macros.filter(|&(id, _)| {
+ self.macros = self.macros.filter(|&(id, _, _)| {
let this = MacroSubNs::from_id(db, id);
sub_namespace_match(Some(this), expected)
});
@@ -196,15 +197,15 @@ impl DefMap {
PathKind::DollarCrate(krate) => {
if krate == self.krate {
cov_mark::hit!(macro_dollar_crate_self);
- PerNs::types(self.crate_root().into(), Visibility::Public)
+ PerNs::types(self.crate_root().into(), Visibility::Public, None)
} else {
let def_map = db.crate_def_map(krate);
let module = def_map.module_id(Self::ROOT);
cov_mark::hit!(macro_dollar_crate_other);
- PerNs::types(module.into(), Visibility::Public)
+ PerNs::types(module.into(), Visibility::Public, None)
}
}
- PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public),
+ PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public, None),
// plain import or absolute path in 2015: crate-relative with
// fallback to extern prelude (with the simplification in
// rust-lang/rust#57745)
@@ -291,7 +292,7 @@ impl DefMap {
);
}
- PerNs::types(module.into(), Visibility::Public)
+ PerNs::types(module.into(), Visibility::Public, None)
}
PathKind::Abs => {
// 2018-style absolute path -- only extern prelude
@@ -299,9 +300,13 @@ impl DefMap {
Some((_, segment)) => segment,
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
};
- if let Some(&def) = self.data.extern_prelude.get(segment) {
+ if let Some(&(def, extern_crate)) = self.data.extern_prelude.get(segment) {
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
- PerNs::types(def.into(), Visibility::Public)
+ PerNs::types(
+ def.into(),
+ Visibility::Public,
+ extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
} else {
return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
}
@@ -309,7 +314,7 @@ impl DefMap {
};
for (i, segment) in segments {
- let (curr, vis) = match curr_per_ns.take_types_vis() {
+ let (curr, vis, imp) = match curr_per_ns.take_types_full() {
Some(r) => r,
None => {
// we still have path segments left, but the path so far
@@ -364,18 +369,20 @@ impl DefMap {
Some(local_id) => {
let variant = EnumVariantId { parent: e, local_id };
match &*enum_data.variants[local_id].variant_data {
- crate::data::adt::VariantData::Record(_) => {
- PerNs::types(variant.into(), Visibility::Public)
- }
- crate::data::adt::VariantData::Tuple(_)
- | crate::data::adt::VariantData::Unit => {
- PerNs::both(variant.into(), variant.into(), Visibility::Public)
+ VariantData::Record(_) => {
+ PerNs::types(variant.into(), Visibility::Public, None)
}
+ VariantData::Tuple(_) | VariantData::Unit => PerNs::both(
+ variant.into(),
+ variant.into(),
+ Visibility::Public,
+ None,
+ ),
}
}
None => {
return ResolvePathResult::with(
- PerNs::types(e.into(), vis),
+ PerNs::types(e.into(), vis, imp),
ReachedFixedPoint::Yes,
Some(i),
Some(self.krate),
@@ -393,7 +400,7 @@ impl DefMap {
);
return ResolvePathResult::with(
- PerNs::types(s, vis),
+ PerNs::types(s, vis, imp),
ReachedFixedPoint::Yes,
Some(i),
Some(self.krate),
@@ -430,7 +437,7 @@ impl DefMap {
.filter(|&id| {
sub_namespace_match(Some(MacroSubNs::from_id(db, id)), expected_macro_subns)
})
- .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
+ .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public, None));
let from_scope = self[module].scope.get(name).filter_macro(db, expected_macro_subns);
let from_builtin = match self.block {
Some(_) => {
@@ -449,18 +456,27 @@ impl DefMap {
let extern_prelude = || {
if self.block.is_some() {
- // Don't resolve extern prelude in block `DefMap`s.
+ // Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so
+ // that blocks can properly shadow them
return PerNs::none();
}
- self.data
- .extern_prelude
- .get(name)
- .map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
+ self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
+ PerNs::types(
+ it.into(),
+ Visibility::Public,
+ extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
+ })
};
let macro_use_prelude = || {
- self.macro_use_prelude
- .get(name)
- .map_or(PerNs::none(), |&it| PerNs::macros(it.into(), Visibility::Public))
+ self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
+ PerNs::macros(
+ it.into(),
+ Visibility::Public,
+ // FIXME?
+ None, // extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
+ })
};
let prelude = || self.resolve_in_prelude(db, name);
@@ -488,18 +504,23 @@ impl DefMap {
// Don't resolve extern prelude in block `DefMap`s.
return PerNs::none();
}
- self.data
- .extern_prelude
- .get(name)
- .copied()
- .map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public))
+ self.data.extern_prelude.get(name).copied().map_or(
+ PerNs::none(),
+ |(it, extern_crate)| {
+ PerNs::types(
+ it.into(),
+ Visibility::Public,
+ extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
+ },
+ )
};
from_crate_root.or_else(from_extern_prelude)
}
fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
- if let Some(prelude) = self.prelude {
+ if let Some((prelude, _use)) = self.prelude {
let keep;
let def_map = if prelude.krate == self.krate {
self
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
index dd7c3c363..e7cc44b04 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
@@ -168,7 +168,7 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Foo: t v
+ Foo: ti vi
foo: t
crate::foo
@@ -194,8 +194,8 @@ pub enum Quux {};
"#,
expect![[r#"
crate
- Baz: t v
- Quux: t
+ Baz: ti vi
+ Quux: ti
foo: t
crate::foo
@@ -225,11 +225,11 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Baz: t v
+ Baz: ti vi
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
bar: t
crate::foo::bar
@@ -274,7 +274,7 @@ use self::E::V;
expect![[r#"
crate
E: t
- V: t v
+ V: ti vi
"#]],
);
}
@@ -307,7 +307,7 @@ pub struct FromLib;
crate::foo
Bar: _
- FromLib: t v
+ FromLib: ti vi
"#]],
);
}
@@ -328,7 +328,7 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Baz: t
+ Baz: ti
foo: t
crate::foo
@@ -352,7 +352,7 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Baz: t v
+ Baz: ti vi
"#]],
);
}
@@ -375,13 +375,13 @@ pub struct Arc;
expect![[r#"
crate
alloc: t
- alloc_crate: t
+ alloc_crate: te
sync: t
crate::alloc
crate::sync
- Arc: t v
+ Arc: ti vi
"#]],
);
}
@@ -404,13 +404,13 @@ pub struct Arc;
expect![[r#"
crate
alloc: t
- alloc_crate: t
+ alloc_crate: te
sync: t
crate::alloc
crate::sync
- Arc: t v
+ Arc: ti vi
"#]],
);
}
@@ -426,7 +426,7 @@ extern crate self as bla;
"#,
expect![[r#"
crate
- bla: t
+ bla: te
"#]],
);
}
@@ -447,7 +447,7 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Baz: t v
+ Baz: ti vi
"#]],
);
}
@@ -465,7 +465,7 @@ pub struct Bar;
"#,
expect![[r#"
crate
- Bar: t v
+ Bar: ti vi
foo: v
"#]],
);
@@ -492,9 +492,9 @@ fn no_std_prelude() {
}
"#,
expect![[r#"
- crate
- Rust: t v
- "#]],
+ crate
+ Rust: ti vi
+ "#]],
);
}
@@ -516,9 +516,9 @@ fn edition_specific_preludes() {
}
"#,
expect![[r#"
- crate
- Rust2018: t v
- "#]],
+ crate
+ Rust2018: ti vi
+ "#]],
);
check(
r#"
@@ -533,9 +533,9 @@ fn edition_specific_preludes() {
}
"#,
expect![[r#"
- crate
- Rust2021: t v
- "#]],
+ crate
+ Rust2021: ti vi
+ "#]],
);
}
@@ -563,8 +563,8 @@ pub mod prelude {
"#,
expect![[r#"
crate
- Bar: t v
- Foo: t v
+ Bar: ti vi
+ Foo: ti vi
"#]],
);
}
@@ -590,7 +590,7 @@ pub mod prelude {
"#,
expect![[r#"
crate
- Bar: t v
+ Bar: ti vi
Baz: _
Foo: _
"#]],
@@ -619,8 +619,8 @@ pub mod prelude {
expect![[r#"
crate
Bar: _
- Baz: t v
- Foo: t v
+ Baz: ti vi
+ Foo: ti vi
"#]],
);
}
@@ -643,7 +643,7 @@ mod b {
"#,
expect![[r#"
crate
- T: t v
+ T: ti vi
a: t
b: t
@@ -816,8 +816,8 @@ fn bar() {}
expect![[r#"
crate
bar: v
- baz: v
- foo: t
+ baz: vi
+ foo: ti
"#]],
);
}
@@ -836,7 +836,7 @@ use self::m::S::{self};
"#,
expect![[r#"
crate
- S: t
+ S: ti
m: t
crate::m
@@ -860,8 +860,8 @@ pub const settings: () = ();
"#,
expect![[r#"
crate
- Settings: t v
- settings: v
+ Settings: ti vi
+ settings: vi
"#]],
)
}
@@ -890,8 +890,8 @@ pub struct Struct;
"#,
expect![[r#"
crate
- Struct: t v
- dep: t
+ Struct: ti vi
+ dep: te
"#]],
);
}
@@ -917,13 +917,13 @@ use some_module::unknown_func;
crate
other_module: t
some_module: t
- unknown_func: v
+ unknown_func: vi
crate::other_module
some_submodule: t
crate::other_module::some_submodule
- unknown_func: v
+ unknown_func: vi
crate::some_module
unknown_func: v
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs
index 88a3c7639..1ca74b5da 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs
@@ -24,7 +24,7 @@ pub struct Baz;
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
Foo: t v
bar: t
@@ -237,9 +237,9 @@ pub mod baz { pub struct Bar; }
"#,
expect![[r#"
crate
- Bar: t v
+ Bar: ti vi
bar: t
- baz: t
+ baz: ti
foo: t
crate::bar
@@ -276,9 +276,9 @@ pub mod baz { pub struct Bar; }
"#,
expect![[r#"
crate
- Bar: t v
+ Bar: ti vi
bar: t
- baz: t
+ baz: ti
foo: t
crate::bar
@@ -323,7 +323,7 @@ mod d {
X: t v
crate::b
- foo: t
+ foo: ti
crate::c
foo: t
@@ -332,8 +332,8 @@ mod d {
Y: t v
crate::d
- Y: t v
- foo: t
+ Y: ti vi
+ foo: ti
"#]],
);
}
@@ -355,7 +355,7 @@ use event::Event;
"#,
expect![[r#"
crate
- Event: t
+ Event: ti
event: t
crate::event
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
index 40d3a1654..4a86f88e5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
@@ -212,7 +212,7 @@ pub type Ty = ();
}
for (_, res) in module_data.scope.resolutions() {
- match res.values.or(res.types).unwrap().0 {
+ match res.values.map(|(a, _, _)| a).or(res.types.map(|(a, _, _)| a)).unwrap() {
ModuleDefId::FunctionId(f) => _ = db.function_data(f),
ModuleDefId::AdtId(adt) => match adt {
AdtId::StructId(it) => _ = db.struct_data(it),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
index f4cca8d68..e64fa0b46 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
@@ -203,8 +203,8 @@ macro_rules! bar {
expect![[r#"
crate
Foo: t
- bar: m
- foo: m
+ bar: mi
+ foo: mi
"#]],
);
}
@@ -251,7 +251,7 @@ mod priv_mod {
Bar: t v
Foo: t v
bar: t
- foo: t
+ foo: te
crate::bar
Baz: t v
@@ -318,9 +318,9 @@ macro_rules! baz3 { () => { struct OkBaz3; } }
OkBaz1: t v
OkBaz2: t v
OkBaz3: t v
- all: t
- empty: t
- multiple: t
+ all: te
+ empty: te
+ multiple: te
"#]],
);
}
@@ -551,8 +551,8 @@ fn baz() {}
"#,
expect![[r#"
crate
- bar: t m
- baz: t v m
+ bar: ti mi
+ baz: ti v mi
foo: t m
"#]],
);
@@ -583,7 +583,7 @@ mod m {
crate
Alias: t v
Direct: t v
- foo: t
+ foo: te
"#]],
);
}
@@ -628,9 +628,9 @@ mod m {
m: t
crate::m
- alias1: m
- alias2: m
- alias3: m
+ alias1: mi
+ alias2: mi
+ alias3: mi
not_found: _
"#]],
);
@@ -682,11 +682,11 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Bar: t v
- Baz: t v
+ Bar: ti vi
+ Baz: ti vi
Foo: t v
- FooSelf: t v
- foo: t
+ FooSelf: ti vi
+ foo: te
m: t
crate::m
@@ -725,7 +725,7 @@ pub struct bar;
"#,
expect![[r#"
crate
- bar: t v
+ bar: ti vi
"#]],
);
}
@@ -1340,7 +1340,7 @@ pub mod prelude {
crate
Ok: t v
bar: m
- dep: t
+ dep: te
foo: m
ok: v
"#]],
@@ -1370,13 +1370,13 @@ macro_rules! mk_foo {
}
"#,
expect![[r#"
- crate
- a: t
- lib: t
+ crate
+ a: t
+ lib: te
- crate::a
- Ok: t v
- "#]],
+ crate::a
+ Ok: t v
+ "#]],
);
}
@@ -1427,8 +1427,8 @@ pub mod prelude {
expect![[r#"
crate
Ok: t v
- bar: m
- foo: m
+ bar: mi
+ foo: mi
ok: v
"#]],
);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
index 81bc0ff91..1327d9aa6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
@@ -80,18 +80,18 @@ pub trait Iterator;
prelude: t
crate::iter
- Iterator: t
+ Iterator: ti
traits: t
crate::iter::traits
- Iterator: t
+ Iterator: ti
iterator: t
crate::iter::traits::iterator
Iterator: t
crate::prelude
- Iterator: t
+ Iterator: ti
"#]],
);
}
@@ -109,7 +109,7 @@ pub struct Bar;
"#,
expect![[r#"
crate
- Bar: t v
+ Bar: ti vi
foo: t
crate::foo
@@ -139,7 +139,7 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Bar: t v
+ Bar: ti vi
r#async: t
crate::r#async
@@ -176,8 +176,8 @@ pub struct Bar;
"#,
expect![[r#"
crate
- Bar: t v
- Foo: t v
+ Bar: ti vi
+ Foo: ti vi
r#async: t
crate::r#async
@@ -207,7 +207,7 @@ pub struct Bar;
"#,
expect![[r#"
crate
- Bar: t v
+ Bar: ti vi
foo: t
crate::foo
@@ -236,7 +236,7 @@ pub struct Baz;
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
bar: t
crate::foo::bar
@@ -265,7 +265,7 @@ pub struct Baz;
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
bar: t
crate::foo::bar
@@ -292,7 +292,7 @@ use super::Baz;
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
"#]],
);
}
@@ -626,7 +626,7 @@ pub struct Baz;
"#,
expect![[r#"
crate
- Baz: t v
+ Baz: ti vi
foo: t
crate::foo
@@ -660,7 +660,7 @@ pub struct Baz;
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
bar: t
crate::foo::bar
@@ -694,7 +694,7 @@ pub struct Baz;
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
bar: t
crate::foo::bar
@@ -728,7 +728,7 @@ pub struct Baz;
foo: t
crate::foo
- Baz: t v
+ Baz: ti vi
bar: t
crate::foo::bar
@@ -868,7 +868,7 @@ pub mod hash { pub trait Hash {} }
"#,
expect![[r#"
crate
- Hash: t
+ Hash: ti
core: t
crate::core
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs
index 215e8952d..271eb1c79 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs
@@ -14,10 +14,10 @@ pub use i32 as int;
expect![[r#"
crate
foo: t
- int: t
+ int: ti
crate::foo
- int: t
+ int: ti
"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path.rs b/src/tools/rust-analyzer/crates/hir-def/src/path.rs
index 06530cc7e..3894172a5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/path.rs
@@ -47,7 +47,7 @@ pub enum Path {
},
/// A link to a lang item. It is used in desugaring of things like `it?`. We can show these
/// links via a normal path since they might be private and not accessible in the usage place.
- LangItem(LangItemTarget),
+ LangItem(LangItemTarget, Option<Name>),
}
/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This
@@ -122,33 +122,40 @@ impl Path {
pub fn kind(&self) -> &PathKind {
match self {
Path::Normal { mod_path, .. } => &mod_path.kind,
- Path::LangItem(_) => &PathKind::Abs,
+ Path::LangItem(..) => &PathKind::Abs,
}
}
pub fn type_anchor(&self) -> Option<&TypeRef> {
match self {
Path::Normal { type_anchor, .. } => type_anchor.as_deref(),
- Path::LangItem(_) => None,
+ Path::LangItem(..) => None,
}
}
pub fn segments(&self) -> PathSegments<'_> {
- let Path::Normal { mod_path, generic_args, .. } = self else {
- return PathSegments { segments: &[], generic_args: None };
- };
- let s =
- PathSegments { segments: mod_path.segments(), generic_args: generic_args.as_deref() };
- if let Some(generic_args) = s.generic_args {
- assert_eq!(s.segments.len(), generic_args.len());
+ match self {
+ Path::Normal { mod_path, generic_args, .. } => {
+ let s = PathSegments {
+ segments: mod_path.segments(),
+ generic_args: generic_args.as_deref(),
+ };
+ if let Some(generic_args) = s.generic_args {
+ assert_eq!(s.segments.len(), generic_args.len());
+ }
+ s
+ }
+ Path::LangItem(_, seg) => PathSegments {
+ segments: seg.as_ref().map_or(&[], |seg| std::slice::from_ref(seg)),
+ generic_args: None,
+ },
}
- s
}
pub fn mod_path(&self) -> Option<&ModPath> {
match self {
Path::Normal { mod_path, .. } => Some(&mod_path),
- Path::LangItem(_) => None,
+ Path::LangItem(..) => None,
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
index 2bc1f8e92..14890364d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
@@ -3,13 +3,24 @@
//!
//! `PerNs` (per namespace) captures this.
-use crate::{item_scope::ItemInNs, visibility::Visibility, MacroId, ModuleDefId};
+use crate::{
+ item_scope::{ImportId, ImportOrExternCrate, ItemInNs},
+ visibility::Visibility,
+ MacroId, ModuleDefId,
+};
+
+#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
+pub enum Namespace {
+ Types,
+ Values,
+ Macros,
+}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct PerNs {
- pub types: Option<(ModuleDefId, Visibility)>,
- pub values: Option<(ModuleDefId, Visibility)>,
- pub macros: Option<(MacroId, Visibility)>,
+ pub types: Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
+ pub values: Option<(ModuleDefId, Visibility, Option<ImportId>)>,
+ pub macros: Option<(MacroId, Visibility, Option<ImportId>)>,
}
impl Default for PerNs {
@@ -23,20 +34,29 @@ impl PerNs {
PerNs { types: None, values: None, macros: None }
}
- pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
- PerNs { types: None, values: Some((t, v)), macros: None }
+ pub fn values(t: ModuleDefId, v: Visibility, i: Option<ImportId>) -> PerNs {
+ PerNs { types: None, values: Some((t, v, i)), macros: None }
}
- pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
- PerNs { types: Some((t, v)), values: None, macros: None }
+ pub fn types(t: ModuleDefId, v: Visibility, i: Option<ImportOrExternCrate>) -> PerNs {
+ PerNs { types: Some((t, v, i)), values: None, macros: None }
}
- pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
- PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
+ pub fn both(
+ types: ModuleDefId,
+ values: ModuleDefId,
+ v: Visibility,
+ i: Option<ImportOrExternCrate>,
+ ) -> PerNs {
+ PerNs {
+ types: Some((types, v, i)),
+ values: Some((values, v, i.and_then(ImportOrExternCrate::into_import))),
+ macros: None,
+ }
}
- pub fn macros(macro_: MacroId, v: Visibility) -> PerNs {
- PerNs { types: None, values: None, macros: Some((macro_, v)) }
+ pub fn macros(macro_: MacroId, v: Visibility, i: Option<ImportId>) -> PerNs {
+ PerNs { types: None, values: None, macros: Some((macro_, v, i)) }
}
pub fn is_none(&self) -> bool {
@@ -51,7 +71,7 @@ impl PerNs {
self.types.map(|it| it.0)
}
- pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
+ pub fn take_types_full(self) -> Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)> {
self.types
}
@@ -59,24 +79,32 @@ impl PerNs {
self.values.map(|it| it.0)
}
+ pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportId>)> {
+ self.values.map(|it| (it.0, it.2))
+ }
+
pub fn take_macros(self) -> Option<MacroId> {
self.macros.map(|it| it.0)
}
+ pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportId>)> {
+ self.macros.map(|it| (it.0, it.2))
+ }
+
pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
let _p = profile::span("PerNs::filter_visibility");
PerNs {
- types: self.types.filter(|(_, v)| f(*v)),
- values: self.values.filter(|(_, v)| f(*v)),
- macros: self.macros.filter(|(_, v)| f(*v)),
+ types: self.types.filter(|&(_, v, _)| f(v)),
+ values: self.values.filter(|&(_, v, _)| f(v)),
+ macros: self.macros.filter(|&(_, v, _)| f(v)),
}
}
pub fn with_visibility(self, vis: Visibility) -> PerNs {
PerNs {
- types: self.types.map(|(it, _)| (it, vis)),
- values: self.values.map(|(it, _)| (it, vis)),
- macros: self.macros.map(|(it, _)| (it, vis)),
+ types: self.types.map(|(it, _, c)| (it, vis, c)),
+ values: self.values.map(|(it, _, c)| (it, vis, c)),
+ macros: self.macros.map(|(it, _, import)| (it, vis, import)),
}
}
@@ -96,12 +124,20 @@ impl PerNs {
}
}
- pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
+ pub fn iter_items(self) -> impl Iterator<Item = (ItemInNs, Option<ImportOrExternCrate>)> {
let _p = profile::span("PerNs::iter_items");
self.types
- .map(|it| ItemInNs::Types(it.0))
+ .map(|it| (ItemInNs::Types(it.0), it.2))
.into_iter()
- .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter())
- .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter())
+ .chain(
+ self.values
+ .map(|it| (ItemInNs::Values(it.0), it.2.map(ImportOrExternCrate::Import)))
+ .into_iter(),
+ )
+ .chain(
+ self.macros
+ .map(|it| (ItemInNs::Macros(it.0), it.2.map(ImportOrExternCrate::Import)))
+ .into_iter(),
+ )
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
index 11d58a6ba..f4f5541e3 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
@@ -2,18 +2,54 @@
use std::fmt::{self, Write};
-use hir_expand::{db::ExpandDatabase, mod_path::PathKind};
+use hir_expand::mod_path::PathKind;
use intern::Interned;
use itertools::Itertools;
use crate::{
+ db::DefDatabase,
+ lang_item::LangItemTarget,
path::{GenericArg, GenericArgs, Path},
type_ref::{Mutability, TraitBoundModifier, TypeBound, TypeRef},
};
-pub(crate) fn print_path(db: &dyn ExpandDatabase, path: &Path, buf: &mut dyn Write) -> fmt::Result {
- if let Path::LangItem(it) = path {
- return write!(buf, "$lang_item::{it:?}");
+pub(crate) fn print_path(db: &dyn DefDatabase, path: &Path, buf: &mut dyn Write) -> fmt::Result {
+ if let Path::LangItem(it, s) = path {
+ write!(buf, "builtin#lang(")?;
+ match *it {
+ LangItemTarget::ImplDef(it) => write!(buf, "{it:?}")?,
+ LangItemTarget::EnumId(it) => {
+ write!(buf, "{}", db.enum_data(it).name.display(db.upcast()))?
+ }
+ LangItemTarget::Function(it) => {
+ write!(buf, "{}", db.function_data(it).name.display(db.upcast()))?
+ }
+ LangItemTarget::Static(it) => {
+ write!(buf, "{}", db.static_data(it).name.display(db.upcast()))?
+ }
+ LangItemTarget::Struct(it) => {
+ write!(buf, "{}", db.struct_data(it).name.display(db.upcast()))?
+ }
+ LangItemTarget::Union(it) => {
+ write!(buf, "{}", db.union_data(it).name.display(db.upcast()))?
+ }
+ LangItemTarget::TypeAlias(it) => {
+ write!(buf, "{}", db.type_alias_data(it).name.display(db.upcast()))?
+ }
+ LangItemTarget::Trait(it) => {
+ write!(buf, "{}", db.trait_data(it).name.display(db.upcast()))?
+ }
+ LangItemTarget::EnumVariant(it) => write!(
+ buf,
+ "{}",
+ db.enum_data(it.parent).variants[it.local_id].name.display(db.upcast())
+ )?,
+ }
+
+ if let Some(s) = s {
+ write!(buf, "::{}", s.display(db.upcast()))?;
+ }
+ return write!(buf, ")");
}
match path.type_anchor() {
Some(anchor) => {
@@ -44,7 +80,7 @@ pub(crate) fn print_path(db: &dyn ExpandDatabase, path: &Path, buf: &mut dyn Wri
write!(buf, "::")?;
}
- write!(buf, "{}", segment.name.display(db))?;
+ write!(buf, "{}", segment.name.display(db.upcast()))?;
if let Some(generics) = segment.args_and_bindings {
write!(buf, "::<")?;
print_generic_args(db, generics, buf)?;
@@ -57,7 +93,7 @@ pub(crate) fn print_path(db: &dyn ExpandDatabase, path: &Path, buf: &mut dyn Wri
}
pub(crate) fn print_generic_args(
- db: &dyn ExpandDatabase,
+ db: &dyn DefDatabase,
generics: &GenericArgs,
buf: &mut dyn Write,
) -> fmt::Result {
@@ -83,7 +119,7 @@ pub(crate) fn print_generic_args(
write!(buf, ", ")?;
}
first = false;
- write!(buf, "{}", binding.name.display(db))?;
+ write!(buf, "{}", binding.name.display(db.upcast()))?;
if !binding.bounds.is_empty() {
write!(buf, ": ")?;
print_type_bounds(db, &binding.bounds, buf)?;
@@ -97,19 +133,19 @@ pub(crate) fn print_generic_args(
}
pub(crate) fn print_generic_arg(
- db: &dyn ExpandDatabase,
+ db: &dyn DefDatabase,
arg: &GenericArg,
buf: &mut dyn Write,
) -> fmt::Result {
match arg {
GenericArg::Type(ty) => print_type_ref(db, ty, buf),
- GenericArg::Const(c) => write!(buf, "{}", c.display(db)),
- GenericArg::Lifetime(lt) => write!(buf, "{}", lt.name.display(db)),
+ GenericArg::Const(c) => write!(buf, "{}", c.display(db.upcast())),
+ GenericArg::Lifetime(lt) => write!(buf, "{}", lt.name.display(db.upcast())),
}
}
pub(crate) fn print_type_ref(
- db: &dyn ExpandDatabase,
+ db: &dyn DefDatabase,
type_ref: &TypeRef,
buf: &mut dyn Write,
) -> fmt::Result {
@@ -143,7 +179,7 @@ pub(crate) fn print_type_ref(
};
write!(buf, "&")?;
if let Some(lt) = lt {
- write!(buf, "{} ", lt.name.display(db))?;
+ write!(buf, "{} ", lt.name.display(db.upcast()))?;
}
write!(buf, "{mtbl}")?;
print_type_ref(db, pointee, buf)?;
@@ -151,7 +187,7 @@ pub(crate) fn print_type_ref(
TypeRef::Array(elem, len) => {
write!(buf, "[")?;
print_type_ref(db, elem, buf)?;
- write!(buf, "; {}]", len.display(db))?;
+ write!(buf, "; {}]", len.display(db.upcast()))?;
}
TypeRef::Slice(elem) => {
write!(buf, "[")?;
@@ -198,7 +234,7 @@ pub(crate) fn print_type_ref(
}
pub(crate) fn print_type_bounds(
- db: &dyn ExpandDatabase,
+ db: &dyn DefDatabase,
bounds: &[Interned<TypeBound>],
buf: &mut dyn Write,
) -> fmt::Result {
@@ -216,10 +252,14 @@ pub(crate) fn print_type_bounds(
print_path(db, path, buf)?;
}
TypeBound::ForLifetime(lifetimes, path) => {
- write!(buf, "for<{}> ", lifetimes.iter().map(|it| it.display(db)).format(", "))?;
+ write!(
+ buf,
+ "for<{}> ",
+ lifetimes.iter().map(|it| it.display(db.upcast())).format(", ")
+ )?;
print_path(db, path, buf)?;
}
- TypeBound::Lifetime(lt) => write!(buf, "{}", lt.name.display(db))?,
+ TypeBound::Lifetime(lt) => write!(buf, "{}", lt.name.display(db.upcast()))?,
TypeBound::Error => write!(buf, "{{unknown}}")?,
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index b112c1070..50da9ed06 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -12,20 +12,21 @@ use triomphe::Arc;
use crate::{
body::scope::{ExprScopes, ScopeId},
builtin_type::BuiltinType,
+ data::ExternCrateDeclData,
db::DefDatabase,
generics::{GenericParams, TypeOrConstParamData},
hir::{BindingId, ExprId, LabelId},
- item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
+ item_scope::{BuiltinShadowMode, ImportId, ImportOrExternCrate, BUILTIN_SCOPE},
lang_item::LangItemTarget,
nameres::{DefMap, MacroSubNs},
path::{ModPath, Path, PathKind},
per_ns::PerNs,
visibility::{RawVisibility, Visibility},
- AdtId, AssocItemId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId,
- EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId,
- HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId,
- MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId,
- TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
+ AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
+ ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
+ ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
+ ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
+ TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
};
#[derive(Debug, Clone)]
@@ -100,8 +101,8 @@ pub enum TypeNs {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ResolveValueResult {
- ValueNs(ValueNs),
- Partial(TypeNs, usize),
+ ValueNs(ValueNs, Option<ImportId>),
+ Partial(TypeNs, usize, Option<ImportOrExternCrate>),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -148,56 +149,26 @@ impl Resolver {
self.resolve_module_path(db, path, BuiltinShadowMode::Module)
}
- // FIXME: This shouldn't exist
- pub fn resolve_module_path_in_trait_assoc_items(
- &self,
- db: &dyn DefDatabase,
- path: &ModPath,
- ) -> Option<PerNs> {
- let (item_map, module) = self.item_scope();
- let (module_res, idx) =
- item_map.resolve_path(db, module, path, BuiltinShadowMode::Module, None);
- match module_res.take_types()? {
- ModuleDefId::TraitId(it) => {
- let idx = idx?;
- let unresolved = &path.segments()[idx..];
- let assoc = match unresolved {
- [it] => it,
- _ => return None,
- };
- let &(_, assoc) = db.trait_data(it).items.iter().find(|(n, _)| n == assoc)?;
- Some(match assoc {
- AssocItemId::FunctionId(it) => PerNs::values(it.into(), Visibility::Public),
- AssocItemId::ConstId(it) => PerNs::values(it.into(), Visibility::Public),
- AssocItemId::TypeAliasId(it) => PerNs::types(it.into(), Visibility::Public),
- })
- }
- _ => None,
- }
- }
-
pub fn resolve_path_in_type_ns(
&self,
db: &dyn DefDatabase,
path: &Path,
- ) -> Option<(TypeNs, Option<usize>)> {
+ ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
let path = match path {
Path::Normal { mod_path, .. } => mod_path,
- Path::LangItem(l) => {
- return Some((
- match *l {
- LangItemTarget::Union(it) => TypeNs::AdtId(it.into()),
- LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it),
- LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()),
- LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it),
- LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
- LangItemTarget::Trait(it) => TypeNs::TraitId(it),
- LangItemTarget::Function(_)
- | LangItemTarget::ImplDef(_)
- | LangItemTarget::Static(_) => return None,
- },
- None,
- ))
+ Path::LangItem(l, seg) => {
+ let type_ns = match *l {
+ LangItemTarget::Union(it) => TypeNs::AdtId(it.into()),
+ LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it),
+ LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()),
+ LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it),
+ LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
+ LangItemTarget::Trait(it) => TypeNs::TraitId(it),
+ LangItemTarget::Function(_)
+ | LangItemTarget::ImplDef(_)
+ | LangItemTarget::Static(_) => return None,
+ };
+ return Some((type_ns, seg.as_ref().map(|_| 1), None));
}
};
let first_name = path.segments().first()?;
@@ -213,17 +184,17 @@ impl Resolver {
Scope::ExprScope(_) => continue,
Scope::GenericParams { params, def } => {
if let Some(id) = params.find_type_by_name(first_name, *def) {
- return Some((TypeNs::GenericParam(id), remaining_idx()));
+ return Some((TypeNs::GenericParam(id), remaining_idx(), None));
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- return Some((TypeNs::SelfType(impl_), remaining_idx()));
+ return Some((TypeNs::SelfType(impl_), remaining_idx(), None));
}
}
&Scope::AdtScope(adt) => {
if first_name == &name![Self] {
- return Some((TypeNs::AdtSelfType(adt), remaining_idx()));
+ return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None));
}
}
Scope::BlockScope(m) => {
@@ -236,12 +207,24 @@ impl Resolver {
self.module_scope.resolve_path_in_type_ns(db, path)
}
+ pub fn resolve_path_in_type_ns_fully_with_imports(
+ &self,
+ db: &dyn DefDatabase,
+ path: &Path,
+ ) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
+ let (res, unresolved, imp) = self.resolve_path_in_type_ns(db, path)?;
+ if unresolved.is_some() {
+ return None;
+ }
+ Some((res, imp))
+ }
+
pub fn resolve_path_in_type_ns_fully(
&self,
db: &dyn DefDatabase,
path: &Path,
) -> Option<TypeNs> {
- let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
+ let (res, unresolved, _) = self.resolve_path_in_type_ns(db, path)?;
if unresolved.is_some() {
return None;
}
@@ -263,7 +246,6 @@ impl Resolver {
RawVisibility::Public => Some(Visibility::Public),
}
}
-
pub fn resolve_path_in_value_ns(
&self,
db: &dyn DefDatabase,
@@ -271,18 +253,35 @@ impl Resolver {
) -> Option<ResolveValueResult> {
let path = match path {
Path::Normal { mod_path, .. } => mod_path,
- Path::LangItem(l) => {
- return Some(ResolveValueResult::ValueNs(match *l {
- LangItemTarget::Function(it) => ValueNs::FunctionId(it),
- LangItemTarget::Static(it) => ValueNs::StaticId(it),
- LangItemTarget::Struct(it) => ValueNs::StructId(it),
- LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
- LangItemTarget::Union(_)
+ Path::LangItem(l, None) => {
+ return Some(ResolveValueResult::ValueNs(
+ match *l {
+ LangItemTarget::Function(it) => ValueNs::FunctionId(it),
+ LangItemTarget::Static(it) => ValueNs::StaticId(it),
+ LangItemTarget::Struct(it) => ValueNs::StructId(it),
+ LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
+ LangItemTarget::Union(_)
+ | LangItemTarget::ImplDef(_)
+ | LangItemTarget::TypeAlias(_)
+ | LangItemTarget::Trait(_)
+ | LangItemTarget::EnumId(_) => return None,
+ },
+ None,
+ ))
+ }
+ Path::LangItem(l, Some(_)) => {
+ let type_ns = match *l {
+ LangItemTarget::Union(it) => TypeNs::AdtId(it.into()),
+ LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it),
+ LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()),
+ LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it),
+ LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
+ LangItemTarget::Trait(it) => TypeNs::TraitId(it),
+ LangItemTarget::Function(_)
| LangItemTarget::ImplDef(_)
- | LangItemTarget::TypeAlias(_)
- | LangItemTarget::Trait(_)
- | LangItemTarget::EnumId(_) => return None,
- }))
+ | LangItemTarget::Static(_) => return None,
+ };
+ return Some(ResolveValueResult::Partial(type_ns, 1, None));
}
};
let n_segments = path.segments().len();
@@ -304,20 +303,24 @@ impl Resolver {
.find(|entry| entry.name() == first_name);
if let Some(e) = entry {
- return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(
- e.binding(),
- )));
+ return Some(ResolveValueResult::ValueNs(
+ ValueNs::LocalBinding(e.binding()),
+ None,
+ ));
}
}
Scope::GenericParams { params, def } => {
if let Some(id) = params.find_const_by_name(first_name, *def) {
let val = ValueNs::GenericParam(id);
- return Some(ResolveValueResult::ValueNs(val));
+ return Some(ResolveValueResult::ValueNs(val, None));
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- return Some(ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_)));
+ return Some(ResolveValueResult::ValueNs(
+ ValueNs::ImplSelf(impl_),
+ None,
+ ));
}
}
// bare `Self` doesn't work in the value namespace in a struct/enum definition
@@ -336,18 +339,22 @@ impl Resolver {
Scope::GenericParams { params, def } => {
if let Some(id) = params.find_type_by_name(first_name, *def) {
let ty = TypeNs::GenericParam(id);
- return Some(ResolveValueResult::Partial(ty, 1));
+ return Some(ResolveValueResult::Partial(ty, 1, None));
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- return Some(ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1));
+ return Some(ResolveValueResult::Partial(
+ TypeNs::SelfType(impl_),
+ 1,
+ None,
+ ));
}
}
Scope::AdtScope(adt) => {
if first_name == &name![Self] {
let ty = TypeNs::AdtSelfType(*adt);
- return Some(ResolveValueResult::Partial(ty, 1));
+ return Some(ResolveValueResult::Partial(ty, 1, None));
}
}
Scope::BlockScope(m) => {
@@ -368,7 +375,7 @@ impl Resolver {
// `use core::u16;`.
if path.kind == PathKind::Plain && n_segments > 1 {
if let Some(builtin) = BuiltinType::by_name(first_name) {
- return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
+ return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None));
}
}
@@ -381,7 +388,7 @@ impl Resolver {
path: &Path,
) -> Option<ValueNs> {
match self.resolve_path_in_value_ns(db, path)? {
- ResolveValueResult::ValueNs(it) => Some(it),
+ ResolveValueResult::ValueNs(it, _) => Some(it),
ResolveValueResult::Partial(..) => None,
}
}
@@ -391,12 +398,12 @@ impl Resolver {
db: &dyn DefDatabase,
path: &ModPath,
expected_macro_kind: Option<MacroSubNs>,
- ) -> Option<MacroId> {
+ ) -> Option<(MacroId, Option<ImportId>)> {
let (item_map, module) = self.item_scope();
item_map
.resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
.0
- .take_macros()
+ .take_macros_import()
}
/// Returns a set of names available in the current scope.
@@ -456,21 +463,22 @@ impl Resolver {
def_map[module_id].scope.entries().for_each(|(name, def)| {
res.add_per_ns(name, def);
});
+
def_map[module_id].scope.legacy_macros().for_each(|(name, macs)| {
macs.iter().for_each(|&mac| {
res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)));
})
});
- def_map.macro_use_prelude().for_each(|(name, def)| {
+ def_map.macro_use_prelude().for_each(|(name, (def, _extern_crate))| {
res.add(name, ScopeDef::ModuleDef(def.into()));
});
- def_map.extern_prelude().for_each(|(name, def)| {
- res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
+ def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
+ res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into())));
});
BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
res.add_per_ns(name, def);
});
- if let Some(prelude) = def_map.prelude() {
+ if let Some((prelude, _use)) = def_map.prelude() {
let prelude_def_map = prelude.def_map(db);
for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
res.add_per_ns(name, def)
@@ -479,6 +487,23 @@ impl Resolver {
res.map
}
+ pub fn extern_crate_decls_in_scope<'a>(
+ &'a self,
+ db: &'a dyn DefDatabase,
+ ) -> impl Iterator<Item = Name> + 'a {
+ self.module_scope.def_map[self.module_scope.module_id]
+ .scope
+ .extern_crate_decls()
+ .map(|id| ExternCrateDeclData::extern_crate_decl_data_query(db, id).name.clone())
+ }
+
+ pub fn extern_crates_in_scope<'a>(&'a self) -> impl Iterator<Item = (Name, ModuleId)> + 'a {
+ self.module_scope
+ .def_map
+ .extern_prelude()
+ .map(|(name, module_id)| (name.clone(), module_id.0.into()))
+ }
+
pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
// FIXME(trait_alias): Trait alias brings aliased traits in scope! Note that supertraits of
// aliased traits are NOT brought in scope (unless also aliased).
@@ -501,7 +526,7 @@ impl Resolver {
}
// Fill in the prelude traits
- if let Some(prelude) = self.module_scope.def_map.prelude() {
+ if let Some((prelude, _use)) = self.module_scope.def_map.prelude() {
let prelude_def_map = prelude.def_map(db);
traits.extend(prelude_def_map[prelude.local_id].scope.traits());
}
@@ -804,11 +829,12 @@ impl ModuleItemMap {
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
match idx {
None => {
- let value = to_value_ns(module_def)?;
- Some(ResolveValueResult::ValueNs(value))
+ let (value, import) = to_value_ns(module_def)?;
+ Some(ResolveValueResult::ValueNs(value, import))
}
Some(idx) => {
- let ty = match module_def.take_types()? {
+ let (def, _, import) = module_def.take_types_full()?;
+ let ty = match def {
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
@@ -822,7 +848,7 @@ impl ModuleItemMap {
| ModuleDefId::MacroId(_)
| ModuleDefId::StaticId(_) => return None,
};
- Some(ResolveValueResult::Partial(ty, idx))
+ Some(ResolveValueResult::Partial(ty, idx, import))
}
}
}
@@ -831,16 +857,17 @@ impl ModuleItemMap {
&self,
db: &dyn DefDatabase,
path: &ModPath,
- ) -> Option<(TypeNs, Option<usize>)> {
+ ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
let (module_def, idx) =
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
- let res = to_type_ns(module_def)?;
- Some((res, idx))
+ let (res, import) = to_type_ns(module_def)?;
+ Some((res, idx, import))
}
}
-fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
- let res = match per_ns.take_values()? {
+fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
+ let (def, import) = per_ns.take_values_import()?;
+ let res = match def {
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
@@ -855,11 +882,12 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
| ModuleDefId::MacroId(_)
| ModuleDefId::ModuleId(_) => return None,
};
- Some(res)
+ Some((res, import))
}
-fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
- let res = match per_ns.take_types()? {
+fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
+ let (def, _, import) = per_ns.take_types_full()?;
+ let res = match def {
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
@@ -875,7 +903,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
| ModuleDefId::StaticId(_)
| ModuleDefId::ModuleId(_) => return None,
};
- Some(res)
+ Some((res, import))
}
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
@@ -892,13 +920,13 @@ impl ScopeNames {
}
}
fn add_per_ns(&mut self, name: &Name, def: PerNs) {
- if let &Some((ty, _)) = &def.types {
+ if let &Some((ty, _, _)) = &def.types {
self.add(name, ScopeDef::ModuleDef(ty))
}
- if let &Some((def, _)) = &def.values {
+ if let &Some((def, _, _)) = &def.values {
self.add(name, ScopeDef::ModuleDef(def))
}
- if let &Some((mac, _)) = &def.macros {
+ if let &Some((mac, _, _)) = &def.macros {
self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)))
}
if def.is_none() {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
index 6047f770d..3770103cd 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
@@ -5,8 +5,8 @@ use la_arena::ArenaMap;
use syntax::ast;
use crate::{
- db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc, Macro2Loc, MacroRulesLoc,
- ProcMacroLoc,
+ db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc, Lookup, Macro2Loc,
+ MacroRulesLoc, ProcMacroLoc, UseId,
};
pub trait HasSource {
@@ -83,3 +83,18 @@ pub trait HasChildSource<ChildId> {
type Value;
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>;
}
+
+impl HasChildSource<la_arena::Idx<ast::UseTree>> for UseId {
+ type Value = ast::UseTree;
+ fn child_source(
+ &self,
+ db: &dyn DefDatabase,
+ ) -> InFile<ArenaMap<la_arena::Idx<ast::UseTree>, Self::Value>> {
+ let loc = &self.lookup(db);
+ let use_ = &loc.id.item_tree(db)[loc.id.value];
+ InFile::new(
+ loc.id.file_id(),
+ use_.use_tree_source_map(db, loc.id.file_id()).into_iter().collect(),
+ )
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
index 4c918e55b..0ec2422b3 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
@@ -342,14 +342,7 @@ fn inner_attributes(
ast::Impl(it) => it.assoc_item_list()?.syntax().clone(),
ast::Module(it) => it.item_list()?.syntax().clone(),
ast::BlockExpr(it) => {
- use syntax::SyntaxKind::{BLOCK_EXPR , EXPR_STMT};
- // Block expressions accept outer and inner attributes, but only when they are the outer
- // expression of an expression statement or the final expression of another block expression.
- let may_carry_attributes = matches!(
- it.syntax().parent().map(|it| it.kind()),
- Some(BLOCK_EXPR | EXPR_STMT)
- );
- if !may_carry_attributes {
+ if !it.may_carry_attributes() {
return None
}
syntax.clone()
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
index 95c6baf42..30b19b6e5 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
@@ -1,13 +1,9 @@
//! Builtin macro
-use std::mem;
-
-use ::tt::Ident;
use base_db::{AnchoredPath, Edition, FileId};
use cfg::CfgExpr;
use either::Either;
use mbe::{parse_exprs_with_sep, parse_to_token_tree, TokenMap};
-use rustc_hash::FxHashMap;
use syntax::{
ast::{self, AstToken},
SmolStr,
@@ -97,11 +93,11 @@ register_builtin! {
(unreachable, Unreachable) => unreachable_expand,
(log_syntax, LogSyntax) => log_syntax_expand,
(trace_macros, TraceMacros) => trace_macros_expand,
-
- EAGER:
(format_args, FormatArgs) => format_args_expand,
(const_format_args, ConstFormatArgs) => format_args_expand,
(format_args_nl, FormatArgsNl) => format_args_nl_expand,
+
+ EAGER:
(compile_error, CompileError) => compile_error_expand,
(concat, Concat) => concat_expand,
(concat_idents, ConcatIdents) => concat_idents_expand,
@@ -247,151 +243,15 @@ fn format_args_expand_general(
_db: &dyn ExpandDatabase,
_id: MacroCallId,
tt: &tt::Subtree,
- end_string: &str,
+ // FIXME: Make use of this so that mir interpretation works properly
+ _end_string: &str,
) -> ExpandResult<tt::Subtree> {
- let args = parse_exprs_with_sep(tt, ',');
-
- let expand_error =
- ExpandResult::new(tt::Subtree::empty(), mbe::ExpandError::NoMatchingRule.into());
-
- let mut key_args = FxHashMap::default();
- let mut args = args.into_iter().filter_map(|mut arg| {
- // Remove `key =`.
- if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=')
- {
- // but not with `==`
- if !matches!(arg.token_trees.get(2), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=')
- {
- let key = arg.token_trees.drain(..2).next().unwrap();
- key_args.insert(key.to_string(), arg);
- return None;
- }
- }
- Some(arg)
- }).collect::<Vec<_>>().into_iter();
- // ^^^^^^^ we need this collect, to enforce the side effect of the filter_map closure (building the `key_args`)
- let Some(format_subtree) = args.next() else {
- return expand_error;
- };
- let format_string = (|| {
- let token_tree = format_subtree.token_trees.get(0)?;
- match token_tree {
- tt::TokenTree::Leaf(l) => match l {
- tt::Leaf::Literal(l) => {
- if let Some(mut text) = l.text.strip_prefix('r') {
- let mut raw_sharps = String::new();
- while let Some(t) = text.strip_prefix('#') {
- text = t;
- raw_sharps.push('#');
- }
- text =
- text.strip_suffix(&raw_sharps)?.strip_prefix('"')?.strip_suffix('"')?;
- Some((text, l.span, Some(raw_sharps)))
- } else {
- let text = l.text.strip_prefix('"')?.strip_suffix('"')?;
- let span = l.span;
- Some((text, span, None))
- }
- }
- _ => None,
- },
- tt::TokenTree::Subtree(_) => None,
- }
- })();
- let Some((format_string, _format_string_span, raw_sharps)) = format_string else {
- return expand_error;
- };
- let mut format_iter = format_string.chars().peekable();
- let mut parts = vec![];
- let mut last_part = String::new();
- let mut arg_tts = vec![];
- let mut err = None;
- while let Some(c) = format_iter.next() {
- // Parsing the format string. See https://doc.rust-lang.org/std/fmt/index.html#syntax for the grammar and more info
- match c {
- '{' => {
- if format_iter.peek() == Some(&'{') {
- format_iter.next();
- last_part.push('{');
- continue;
- }
- let mut argument = String::new();
- while ![Some(&'}'), Some(&':')].contains(&format_iter.peek()) {
- argument.push(match format_iter.next() {
- Some(c) => c,
- None => return expand_error,
- });
- }
- let format_spec = match format_iter.next().unwrap() {
- '}' => "".to_owned(),
- ':' => {
- let mut s = String::new();
- while let Some(c) = format_iter.next() {
- if c == '}' {
- break;
- }
- s.push(c);
- }
- s
- }
- _ => unreachable!(),
- };
- parts.push(mem::take(&mut last_part));
- let arg_tree = if argument.is_empty() {
- match args.next() {
- Some(it) => it,
- None => {
- err = Some(mbe::ExpandError::NoMatchingRule.into());
- tt::Subtree::empty()
- }
- }
- } else if let Some(tree) = key_args.get(&argument) {
- tree.clone()
- } else {
- // FIXME: we should pick the related substring of the `_format_string_span` as the span. You
- // can use `.char_indices()` instead of `.char()` for `format_iter` to find the substring interval.
- let ident = Ident::new(argument, tt::TokenId::unspecified());
- quote!(#ident)
- };
- let formatter = match &*format_spec {
- "?" => quote!(::core::fmt::Debug::fmt),
- "" => quote!(::core::fmt::Display::fmt),
- _ => {
- // FIXME: implement the rest and return expand error here
- quote!(::core::fmt::Display::fmt)
- }
- };
- arg_tts.push(quote! { ::core::fmt::ArgumentV1::new(&(#arg_tree), #formatter), });
- }
- '}' => {
- if format_iter.peek() == Some(&'}') {
- format_iter.next();
- last_part.push('}');
- } else {
- return expand_error;
- }
- }
- _ => last_part.push(c),
- }
- }
- last_part += end_string;
- if !last_part.is_empty() {
- parts.push(last_part);
- }
- let part_tts = parts.into_iter().map(|it| {
- let text = if let Some(raw) = &raw_sharps {
- format!("r{raw}\"{}\"{raw}", it).into()
- } else {
- format!("\"{}\"", it).into()
- };
- let l = tt::Literal { span: tt::TokenId::unspecified(), text };
- quote!(#l ,)
+ let pound = quote! {@PUNCT '#'};
+ let mut tt = tt.clone();
+ tt.delimiter.kind = tt::DelimiterKind::Parenthesis;
+ return ExpandResult::ok(quote! {
+ builtin #pound format_args #tt
});
- let arg_tts = arg_tts.into_iter().flat_map(|arg| arg.token_trees);
- let expanded = quote! {
- ::core::fmt::Arguments::new_v1(&[##part_tts], &[##arg_tts])
- };
- ExpandResult { value: expanded, err }
}
fn asm_expand(
@@ -415,10 +275,12 @@ fn asm_expand(
}
}
- let expanded = quote! {{
- ##literals
- loop {}
- }};
+ let pound = quote! {@PUNCT '#'};
+ let expanded = quote! {
+ builtin #pound asm (
+ {##literals}
+ )
+ };
ExpandResult::ok(expanded)
}
@@ -692,7 +554,7 @@ pub(crate) fn include_arg_to_tt(
arg_id: MacroCallId,
) -> Result<(triomphe::Arc<(::tt::Subtree<::tt::TokenId>, TokenMap)>, FileId), ExpandError> {
let loc = db.lookup_intern_macro_call(arg_id);
- let Some(EagerCallInfo { arg,arg_id, .. }) = loc.eager.as_deref() else {
+ let Some(EagerCallInfo { arg, arg_id, .. }) = loc.eager.as_deref() else {
panic!("include_arg_to_tt called on non include macro call: {:?}", &loc.eager);
};
let path = parse_string(&arg.0)?;
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs
index ade4a5928..ca65db113 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/hygiene.rs
@@ -242,7 +242,7 @@ impl HygieneFrame {
krate,
call_site: None,
def_site: None,
- }
+ };
};
let def_site = info.attr_input_or_mac_def_start.map(|it| db.hygiene_frame(it.file_id));
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index 1f1e20f49..4be55126b 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -37,7 +37,7 @@ use either::Either;
use syntax::{
algo::{self, skip_trivia_token},
ast::{self, AstNode, HasDocComments},
- AstPtr, Direction, SyntaxNode, SyntaxNodePtr, SyntaxToken,
+ AstPtr, Direction, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextSize,
};
use crate::{
@@ -544,7 +544,7 @@ impl MacroCallKind {
};
let range = match kind {
- MacroCallKind::FnLike { ast_id, .. } => ast_id.to_node(db).syntax().text_range(),
+ MacroCallKind::FnLike { ast_id, .. } => ast_id.to_ptr(db).text_range(),
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
// FIXME: should be the range of the macro name, not the whole derive
// FIXME: handle `cfg_attr`
@@ -642,6 +642,8 @@ impl ExpansionInfo {
db: &dyn db::ExpandDatabase,
item: Option<ast::Item>,
token: InFile<&SyntaxToken>,
+ // FIXME: use this for range mapping, so that we can resolve inline format args
+ _relative_token_offset: Option<TextSize>,
) -> Option<impl Iterator<Item = InFile<SyntaxToken>> + '_> {
assert_eq!(token.file_id, self.arg.file_id);
let token_id_in_attr_input = if let Some(item) = item {
@@ -840,9 +842,6 @@ impl<N: AstIdNode> AstId<N> {
pub type ErasedAstId = InFile<ErasedFileAstId>;
impl ErasedAstId {
- pub fn to_node(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
- self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id))
- }
pub fn to_ptr(&self, db: &dyn db::ExpandDatabase) -> SyntaxNodePtr {
db.ast_id_map(self.file_id).get_raw(self.value)
}
@@ -1054,16 +1053,6 @@ impl InFile<SyntaxToken> {
}
}
}
-
- pub fn ancestors_with_macros(
- self,
- db: &dyn db::ExpandDatabase,
- ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ {
- self.value.parent().into_iter().flat_map({
- let file_id = self.file_id;
- move |parent| InFile::new(file_id, &parent).ancestors_with_macros(db)
- })
- }
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
index 7c179c0cf..a876f48bd 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
@@ -54,6 +54,12 @@ impl Name {
Name(Repr::Text(text))
}
+ // FIXME: See above, unfortunately some places really need this right now
+ #[doc(hidden)]
+ pub const fn new_text_dont_use(text: SmolStr) -> Name {
+ Name(Repr::Text(text))
+ }
+
pub fn new_tuple_field(idx: usize) -> Name {
Name(Repr::TupleField(idx))
}
@@ -302,6 +308,16 @@ pub mod known {
rust_2018,
rust_2021,
v1,
+ new_display,
+ new_debug,
+ new_lower_exp,
+ new_upper_exp,
+ new_octal,
+ new_pointer,
+ new_binary,
+ new_lower_hex,
+ new_upper_hex,
+ from_usize,
// Components of known path (type name)
Iterator,
IntoIterator,
@@ -327,6 +343,13 @@ pub mod known {
Not,
None,
Index,
+ Left,
+ Right,
+ Center,
+ Unknown,
+ Is,
+ Param,
+ Implied,
// Components of known path (function name)
filter_map,
next,
@@ -335,6 +358,8 @@ pub mod known {
is_empty,
as_str,
new,
+ new_v1_formatted,
+ none,
// Builtin macros
asm,
assert,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
index abc19d63a..b95ae05cc 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
@@ -32,7 +32,8 @@ once_cell = "1.17.0"
triomphe.workspace = true
nohash-hasher.workspace = true
typed-arena = "2.0.1"
-rustc_index = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
+
+rustc_index.workspace = true
# local deps
stdx.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
index eec57ba3f..967e028bf 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
@@ -17,7 +17,8 @@ use smallvec::SmallVec;
use crate::{
consteval::unknown_const_as_generic, db::HirDatabase, infer::unify::InferenceTable, primitive,
to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, BoundVar, CallableSig,
- GenericArg, Interner, ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt, TyKind,
+ GenericArg, GenericArgData, Interner, ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt,
+ TyKind,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -79,9 +80,9 @@ impl<D> TyBuilder<D> {
let expected_kind = &self.param_kinds[self.vec.len()];
let arg_kind = match arg.data(Interner) {
- chalk_ir::GenericArgData::Ty(_) => ParamKind::Type,
- chalk_ir::GenericArgData::Lifetime(_) => panic!("Got lifetime in TyBuilder::push"),
- chalk_ir::GenericArgData::Const(c) => {
+ GenericArgData::Ty(_) => ParamKind::Type,
+ GenericArgData::Lifetime(_) => panic!("Got lifetime in TyBuilder::push"),
+ GenericArgData::Const(c) => {
let c = c.data(Interner);
ParamKind::Const(c.ty.clone())
}
@@ -139,8 +140,8 @@ impl<D> TyBuilder<D> {
fn assert_match_kind(&self, a: &chalk_ir::GenericArg<Interner>, e: &ParamKind) {
match (a.data(Interner), e) {
- (chalk_ir::GenericArgData::Ty(_), ParamKind::Type)
- | (chalk_ir::GenericArgData::Const(_), ParamKind::Const(_)) => (),
+ (GenericArgData::Ty(_), ParamKind::Type)
+ | (GenericArgData::Const(_), ParamKind::Const(_)) => (),
_ => panic!("Mismatched kinds: {a:?}, {:?}, {:?}", self.vec, self.param_kinds),
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
index 1c0f7b08d..0348680e5 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -1,7 +1,7 @@
//! Constant evaluation details
use base_db::CrateId;
-use chalk_ir::{BoundVar, DebruijnIndex, GenericArgData};
+use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex};
use hir_def::{
hir::Expr,
path::Path,
@@ -120,7 +120,7 @@ pub fn unknown_const(ty: Ty) -> Const {
}
pub fn unknown_const_as_generic(ty: Ty) -> GenericArg {
- GenericArgData::Const(unknown_const(ty)).intern(Interner)
+ unknown_const(ty).cast(Interner)
}
/// Interns a constant scalar with the given type
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
index 666955fa1..7ad3659a4 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
@@ -1203,6 +1203,27 @@ fn destructing_assignment() {
"#,
5,
);
+ check_number(
+ r#"
+ const GOAL: u8 = {
+ let (mut a, mut b) = (2, 5);
+ (a, b) = (b, a);
+ a * 10 + b
+ };
+ "#,
+ 52,
+ );
+ check_number(
+ r#"
+ struct Point { x: i32, y: i32 }
+ const GOAL: i32 = {
+ let mut p = Point { x: 5, y: 6 };
+ (p.x, _) = (p.y, p.x);
+ p.x * 10 + p.y
+ };
+ "#,
+ 66,
+ );
}
#[test]
@@ -1433,6 +1454,30 @@ fn from_trait() {
}
#[test]
+fn closure_clone() {
+ check_number(
+ r#"
+//- minicore: clone, fn
+struct S(u8);
+
+impl Clone for S(u8) {
+ fn clone(&self) -> S {
+ S(self.0 + 5)
+ }
+}
+
+const GOAL: u8 = {
+ let s = S(3);
+ let cl = move || s;
+ let cl = cl.clone();
+ cl().0
+}
+ "#,
+ 8,
+ );
+}
+
+#[test]
fn builtin_derive_macro() {
check_number(
r#"
@@ -2396,14 +2441,14 @@ fn const_loop() {
fn const_transfer_memory() {
check_number(
r#"
- //- minicore: slice, index, coerce_unsized
+ //- minicore: slice, index, coerce_unsized, option
const A1: &i32 = &1;
const A2: &i32 = &10;
const A3: [&i32; 3] = [&1, &2, &100];
- const A4: (i32, &i32) = (1, &1000);
- const GOAL: i32 = *A1 + *A2 + *A3[2] + *A4.1;
+ const A4: (i32, &i32, Option<&i32>) = (1, &1000, Some(&10000));
+ const GOAL: i32 = *A1 + *A2 + *A3[2] + *A4.1 + *A4.2.unwrap_or(&5);
"#,
- 1111,
+ 11111,
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
index 2855f7890..44a4ac27a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
@@ -499,24 +499,26 @@ fn offset() {
r#"
//- minicore: coerce_unsized, index, slice
extern "rust-intrinsic" {
- pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+ pub fn offset<Ptr, Delta>(dst: Ptr, offset: Delta) -> Ptr;
+ pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
}
- const GOAL: u8 = unsafe {
- let ar: &[(u8, u8, u8)] = &[
+ const GOAL: i32 = unsafe {
+ let ar: &[(i32, i32, i32)] = &[
(10, 11, 12),
(20, 21, 22),
(30, 31, 32),
(40, 41, 42),
(50, 51, 52),
];
- let ar: *const [(u8, u8, u8)] = ar;
- let ar = ar as *const (u8, u8, u8);
- let element = *offset(ar, 2);
- element.1
+ let ar: *const [(i32, i32, i32)] = ar;
+ let ar = ar as *const (i32, i32, i32);
+ let element3 = *offset(ar, 2usize);
+ let element4 = *arith_offset(ar, 3);
+ element3.1 * 100 + element4.0
};
"#,
- 31,
+ 3140,
);
}
@@ -585,6 +587,24 @@ fn write_bytes() {
}
#[test]
+fn write_via_move() {
+ check_number(
+ r#"
+ extern "rust-intrinsic" {
+ fn write_via_move<T>(ptr: *mut T, value: T);
+ }
+
+ const GOAL: i32 = unsafe {
+ let mut x = 2;
+ write_via_move(&mut x, 100);
+ x
+ };
+ "#,
+ 100,
+ );
+}
+
+#[test]
fn copy() {
check_number(
r#"
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
index a94a962c1..36d69edf9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -163,25 +163,56 @@ impl<'a> DeclValidator<'a> {
|| allows.contains(allow::NONSTANDARD_STYLE)
})
};
+ let db = self.db.upcast();
+ let file_id_is_derive = || {
+ match id {
+ AttrDefId::ModuleId(m) => {
+ m.def_map(db)[m.local_id].origin.file_id().map(Into::into)
+ }
+ AttrDefId::FunctionId(f) => Some(f.lookup(db).id.file_id()),
+ AttrDefId::StaticId(sid) => Some(sid.lookup(db).id.file_id()),
+ AttrDefId::ConstId(cid) => Some(cid.lookup(db).id.file_id()),
+ AttrDefId::TraitId(tid) => Some(tid.lookup(db).id.file_id()),
+ AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).id.file_id()),
+ AttrDefId::ImplId(iid) => Some(iid.lookup(db).id.file_id()),
+ AttrDefId::ExternBlockId(id) => Some(id.lookup(db).id.file_id()),
+ AttrDefId::ExternCrateId(id) => Some(id.lookup(db).id.file_id()),
+ AttrDefId::UseId(id) => Some(id.lookup(db).id.file_id()),
+ // These warnings should not explore macro definitions at all
+ AttrDefId::MacroId(_) => None,
+ AttrDefId::AdtId(aid) => match aid {
+ AdtId::StructId(sid) => Some(sid.lookup(db).id.file_id()),
+ AdtId::EnumId(eid) => Some(eid.lookup(db).id.file_id()),
+ // Unions aren't yet supported
+ AdtId::UnionId(_) => None,
+ },
+ AttrDefId::FieldId(_) => None,
+ AttrDefId::EnumVariantId(_) => None,
+ AttrDefId::TypeAliasId(_) => None,
+ AttrDefId::GenericParamId(_) => None,
+ }
+ .map_or(false, |file_id| {
+ file_id.is_custom_derive(db.upcast()) || file_id.is_builtin_derive(db.upcast())
+ })
+ };
- is_allowed(id)
- // go upwards one step or give up
- || match id {
- AttrDefId::ModuleId(m) => m.containing_module(self.db.upcast()).map(|v| v.into()),
- AttrDefId::FunctionId(f) => Some(f.lookup(self.db.upcast()).container.into()),
- AttrDefId::StaticId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
- AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()),
- AttrDefId::TraitId(tid) => Some(tid.lookup(self.db.upcast()).container.into()),
- AttrDefId::TraitAliasId(taid) => Some(taid.lookup(self.db.upcast()).container.into()),
- AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
- AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()),
- AttrDefId::ExternCrateId(id) => Some(id.lookup(self.db.upcast()).container.into()),
- AttrDefId::UseId(id) => Some(id.lookup(self.db.upcast()).container.into()),
+ let parent = || {
+ match id {
+ AttrDefId::ModuleId(m) => m.containing_module(db).map(|v| v.into()),
+ AttrDefId::FunctionId(f) => Some(f.lookup(db).container.into()),
+ AttrDefId::StaticId(sid) => Some(sid.lookup(db).container.into()),
+ AttrDefId::ConstId(cid) => Some(cid.lookup(db).container.into()),
+ AttrDefId::TraitId(tid) => Some(tid.lookup(db).container.into()),
+ AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).container.into()),
+ AttrDefId::ImplId(iid) => Some(iid.lookup(db).container.into()),
+ AttrDefId::ExternBlockId(id) => Some(id.lookup(db).container.into()),
+ AttrDefId::ExternCrateId(id) => Some(id.lookup(db).container.into()),
+ AttrDefId::UseId(id) => Some(id.lookup(db).container.into()),
// These warnings should not explore macro definitions at all
AttrDefId::MacroId(_) => None,
AttrDefId::AdtId(aid) => match aid {
- AdtId::StructId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
- AdtId::EnumId(eid) => Some(eid.lookup(self.db.upcast()).container.into()),
+ AdtId::StructId(sid) => Some(sid.lookup(db).container.into()),
+ AdtId::EnumId(eid) => Some(eid.lookup(db).container.into()),
// Unions aren't yet supported
AdtId::UnionId(_) => None,
},
@@ -191,6 +222,12 @@ impl<'a> DeclValidator<'a> {
AttrDefId::GenericParamId(_) => None,
}
.is_some_and(|mid| self.allowed(mid, allow_name, true))
+ };
+ is_allowed(id)
+ // FIXME: this is a hack to avoid false positives in derive macros currently
+ || file_id_is_derive()
+ // go upwards one step or give up
+ || parent()
}
fn validate_func(&mut self, func: FunctionId) {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 9f9a56ffa..cbca0e801 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -75,7 +75,7 @@ fn walk_unsafe(
Expr::Path(path) => {
let resolver = resolver_for_expr(db.upcast(), def, current);
let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
- if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial {
+ if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
if db.static_data(id).mutable {
unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 1b4ee4613..f6d6b00d7 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -1809,6 +1809,25 @@ impl HirDisplay for Path {
}
}
+ // Convert trait's `Self` bound back to the surface syntax. Note there is no associated
+ // trait, so there can only be one path segment that `has_self_type`. The `Self` type
+ // itself can contain further qualified path through, which will be handled by recursive
+ // `hir_fmt`s.
+ //
+ // `trait_mod::Trait<Self = type_mod::Type, Args>::Assoc`
+ // =>
+ // `<type_mod::Type as trait_mod::Trait<Args>>::Assoc`
+ let trait_self_ty = self.segments().iter().find_map(|seg| {
+ let generic_args = seg.args_and_bindings?;
+ generic_args.has_self_type.then(|| &generic_args.args[0])
+ });
+ if let Some(ty) = trait_self_ty {
+ write!(f, "<")?;
+ ty.hir_fmt(f)?;
+ write!(f, " as ")?;
+ // Now format the path of the trait...
+ }
+
for (seg_idx, segment) in self.segments().iter().enumerate() {
if !matches!(self.kind(), PathKind::Plain) || seg_idx > 0 {
write!(f, "::")?;
@@ -1840,15 +1859,12 @@ impl HirDisplay for Path {
return Ok(());
}
- write!(f, "<")?;
let mut first = true;
- for arg in generic_args.args.iter() {
+ // Skip the `Self` bound if exists. It's handled outside the loop.
+ for arg in &generic_args.args[generic_args.has_self_type as usize..] {
if first {
first = false;
- if generic_args.has_self_type {
- // FIXME: Convert to `<Ty as Trait>` form.
- write!(f, "Self = ")?;
- }
+ write!(f, "<")?;
} else {
write!(f, ", ")?;
}
@@ -1857,6 +1873,7 @@ impl HirDisplay for Path {
for binding in generic_args.bindings.iter() {
if first {
first = false;
+ write!(f, "<")?;
} else {
write!(f, ", ")?;
}
@@ -1872,9 +1889,20 @@ impl HirDisplay for Path {
}
}
}
- write!(f, ">")?;
+
+ // There may be no generic arguments to print, in case of a trait having only a
+ // single `Self` bound which is converted to `<Ty as Trait>::Assoc`.
+ if !first {
+ write!(f, ">")?;
+ }
+
+ // Current position: `<Ty as Trait<Args>|`
+ if generic_args.has_self_type {
+ write!(f, ">")?;
+ }
}
}
+
Ok(())
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index b4915dbf0..78d3c667a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -194,7 +194,8 @@ pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum InferenceDiagnostic {
NoSuchField {
- expr: ExprId,
+ field: ExprOrPatId,
+ private: bool,
},
PrivateField {
expr: ExprId,
@@ -228,6 +229,11 @@ pub enum InferenceDiagnostic {
expected: usize,
found: usize,
},
+ MismatchedTupleStructPatArgCount {
+ pat: ExprOrPatId,
+ expected: usize,
+ found: usize,
+ },
ExpectedFunction {
call_expr: ExprId,
found: Ty,
@@ -1017,7 +1023,7 @@ impl<'a> InferenceContext<'a> {
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
let (resolution, unresolved) = if value_ns {
match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
- Some(ResolveValueResult::ValueNs(value)) => match value {
+ Some(ResolveValueResult::ValueNs(value, _)) => match value {
ValueNs::EnumVariantId(var) => {
let substs = ctx.substs_from_path(path, var.into(), true);
let ty = self.db.ty(var.parent.into());
@@ -1033,12 +1039,14 @@ impl<'a> InferenceContext<'a> {
ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
_ => return (self.err_ty(), None),
},
- Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
+ Some(ResolveValueResult::Partial(typens, unresolved, _)) => {
+ (typens, Some(unresolved))
+ }
None => return (self.err_ty(), None),
}
} else {
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
- Some(it) => it,
+ Some((it, idx, _)) => (it, idx),
None => return (self.err_ty(), None),
}
};
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
index 9e1c74b16..a116d4447 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
@@ -39,8 +39,14 @@ impl CastCheck {
}
fn check_ref_to_ptr_cast(expr_ty: Ty, cast_ty: Ty, table: &mut InferenceTable<'_>) -> bool {
- let Some((expr_inner_ty, _, _)) = expr_ty.as_reference() else { return false; };
- let Some((cast_inner_ty, _)) = cast_ty.as_raw_ptr() else { return false; };
- let TyKind::Array(expr_elt_ty, _) = expr_inner_ty.kind(Interner) else { return false; };
+ let Some((expr_inner_ty, _, _)) = expr_ty.as_reference() else {
+ return false;
+ };
+ let Some((cast_inner_ty, _)) = cast_ty.as_raw_ptr() else {
+ return false;
+ };
+ let TyKind::Array(expr_elt_ty, _) = expr_inner_ty.kind(Interner) else {
+ return false;
+ };
table.coerce(expr_elt_ty, cast_inner_ty).is_ok()
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
index 1781f6c58..13d6b5643 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
@@ -322,7 +322,7 @@ impl InferenceContext<'_> {
Expr::Path(p) => {
let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
if let Some(r) = resolver.resolve_path_in_value_ns(self.db.upcast(), p) {
- if let ResolveValueResult::ValueNs(v) = r {
+ if let ResolveValueResult::ValueNs(v, _) = r {
if let ValueNs::LocalBinding(b) = v {
return Some(HirPlace { local: b, projections: vec![] });
}
@@ -452,6 +452,8 @@ impl InferenceContext<'_> {
fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
match &self.body[tgt_expr] {
+ Expr::OffsetOf(_) => (),
+ Expr::InlineAsm(e) => self.walk_expr_without_adjust(e.e),
Expr::If { condition, then_branch, else_branch } => {
self.consume_expr(*condition);
self.consume_expr(*then_branch);
@@ -467,13 +469,13 @@ impl InferenceContext<'_> {
Statement::Let { pat, type_ref: _, initializer, else_branch } => {
if let Some(else_branch) = else_branch {
self.consume_expr(*else_branch);
- if let Some(initializer) = initializer {
- self.consume_expr(*initializer);
- }
- return;
}
if let Some(initializer) = initializer {
- self.walk_expr(*initializer);
+ if else_branch.is_some() {
+ self.consume_expr(*initializer);
+ } else {
+ self.walk_expr(*initializer);
+ }
if let Some(place) = self.place_of_expr(*initializer) {
self.consume_with_pat(place, *pat);
}
@@ -620,6 +622,7 @@ impl InferenceContext<'_> {
| Expr::Tuple { exprs, is_assignee_expr: _ } => {
self.consume_exprs(exprs.iter().copied())
}
+
Expr::Missing
| Expr::Continue { .. }
| Expr::Path(_)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index 8cbdae625..0c3c725a7 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -5,9 +5,7 @@ use std::{
mem,
};
-use chalk_ir::{
- cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyVariableKind,
-};
+use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex, Mutability, TyVariableKind};
use hir_def::{
generics::TypeOrConstParamData,
hir::{
@@ -516,9 +514,6 @@ impl InferenceContext<'_> {
}
Expr::RecordLit { path, fields, spread, .. } => {
let (ty, def_id) = self.resolve_variant(path.as_deref(), false);
- if let Some(variant) = def_id {
- self.write_variant_resolution(tgt_expr.into(), variant);
- }
if let Some(t) = expected.only_has_type(&mut self.table) {
self.unify(&ty, &t);
@@ -528,26 +523,56 @@ impl InferenceContext<'_> {
.as_adt()
.map(|(_, s)| s.clone())
.unwrap_or_else(|| Substitution::empty(Interner));
- let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
- let variant_data = def_id.map(|it| it.variant_data(self.db.upcast()));
- for field in fields.iter() {
- let field_def =
- variant_data.as_ref().and_then(|it| match it.field(&field.name) {
- Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }),
- None => {
- self.push_diagnostic(InferenceDiagnostic::NoSuchField {
- expr: field.expr,
- });
- None
- }
- });
- let field_ty = field_def.map_or(self.err_ty(), |it| {
- field_types[it.local_id].clone().substitute(Interner, &substs)
- });
- // Field type might have some unknown types
- // FIXME: we may want to emit a single type variable for all instance of type fields?
- let field_ty = self.insert_type_vars(field_ty);
- self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
+ if let Some(variant) = def_id {
+ self.write_variant_resolution(tgt_expr.into(), variant);
+ }
+ match def_id {
+ _ if fields.is_empty() => {}
+ Some(def) => {
+ let field_types = self.db.field_types(def);
+ let variant_data = def.variant_data(self.db.upcast());
+ let visibilities = self.db.field_visibilities(def);
+ for field in fields.iter() {
+ let field_def = {
+ match variant_data.field(&field.name) {
+ Some(local_id) => {
+ if !visibilities[local_id].is_visible_from(
+ self.db.upcast(),
+ self.resolver.module(),
+ ) {
+ self.push_diagnostic(
+ InferenceDiagnostic::NoSuchField {
+ field: field.expr.into(),
+ private: true,
+ },
+ );
+ }
+ Some(local_id)
+ }
+ None => {
+ self.push_diagnostic(InferenceDiagnostic::NoSuchField {
+ field: field.expr.into(),
+ private: false,
+ });
+ None
+ }
+ }
+ };
+ let field_ty = field_def.map_or(self.err_ty(), |it| {
+ field_types[it].clone().substitute(Interner, &substs)
+ });
+
+ // Field type might have some unknown types
+ // FIXME: we may want to emit a single type variable for all instance of type fields?
+ let field_ty = self.insert_type_vars(field_ty);
+ self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
+ }
+ }
+ None => {
+ for field in fields.iter() {
+ self.infer_expr_coerce(field.expr, &Expectation::None);
+ }
+ }
}
if let Some(expr) = spread {
self.infer_expr(*expr, &Expectation::has_type(ty.clone()));
@@ -750,7 +775,7 @@ impl InferenceContext<'_> {
self.resolve_associated_type_with_params(
self_ty,
self.resolve_ops_index_output(),
- &[GenericArgData::Ty(index_ty).intern(Interner)],
+ &[index_ty.cast(Interner)],
)
} else {
self.err_ty()
@@ -845,6 +870,11 @@ impl InferenceContext<'_> {
});
expected
}
+ Expr::OffsetOf(_) => TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
+ Expr::InlineAsm(it) => {
+ self.infer_expr_no_expect(it.e);
+ self.result.standard_types.unit.clone()
+ }
};
// use a new type variable if we got unknown here
let ty = self.insert_type_vars_shallow(ty);
@@ -1124,7 +1154,7 @@ impl InferenceContext<'_> {
Expr::Underscore => rhs_ty.clone(),
_ => {
// `lhs` is a place expression, a unit struct, or an enum variant.
- let lhs_ty = self.infer_expr(lhs, &Expectation::none());
+ let lhs_ty = self.infer_expr_inner(lhs, &Expectation::none());
// This is the only branch where this function may coerce any type.
// We are returning early to avoid the unifiability check below.
@@ -1721,16 +1751,13 @@ impl InferenceContext<'_> {
for (id, data) in def_generics.iter().skip(substs.len()) {
match data {
TypeOrConstParamData::TypeParamData(_) => {
- substs.push(GenericArgData::Ty(self.table.new_type_var()).intern(Interner))
- }
- TypeOrConstParamData::ConstParamData(_) => {
- substs.push(
- GenericArgData::Const(self.table.new_const_var(
- self.db.const_param_ty(ConstParamId::from_unchecked(id)),
- ))
- .intern(Interner),
- )
+ substs.push(self.table.new_type_var().cast(Interner))
}
+ TypeOrConstParamData::ConstParamData(_) => substs.push(
+ self.table
+ .new_const_var(self.db.const_param_ty(ConstParamId::from_unchecked(id)))
+ .cast(Interner),
+ ),
}
}
assert_eq!(substs.len(), total_len);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
index 396ca0044..b8a1af96f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/mutability.rs
@@ -35,6 +35,8 @@ impl InferenceContext<'_> {
fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutability) {
match &self.body[tgt_expr] {
Expr::Missing => (),
+ Expr::InlineAsm(e) => self.infer_mut_expr_without_adjust(e.e, Mutability::Not),
+ Expr::OffsetOf(_) => (),
&Expr::If { condition, then_branch, else_branch } => {
self.infer_mut_expr(condition, Mutability::Not);
self.infer_mut_expr(then_branch, Mutability::Not);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index 5da0ab76b..4e28ec060 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -15,7 +15,8 @@ use crate::{
infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
lower::lower_to_chalk_mutability,
primitive::UintTy,
- static_lifetime, Interner, Scalar, Substitution, Ty, TyBuilder, TyExt, TyKind,
+ static_lifetime, InferenceDiagnostic, Interner, Scalar, Substitution, Ty, TyBuilder, TyExt,
+ TyKind,
};
/// Used to generalize patterns and assignee expressions.
@@ -74,29 +75,68 @@ impl InferenceContext<'_> {
if let Some(variant) = def {
self.write_variant_resolution(id.into(), variant);
}
+ if let Some(var) = &var_data {
+ let cmp = if ellipsis.is_some() { usize::gt } else { usize::ne };
+
+ if cmp(&subs.len(), &var.fields().len()) {
+ self.push_diagnostic(InferenceDiagnostic::MismatchedTupleStructPatArgCount {
+ pat: id.into(),
+ expected: var.fields().len(),
+ found: subs.len(),
+ });
+ }
+ }
+
self.unify(&ty, expected);
let substs =
ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
- let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
- let (pre, post) = match ellipsis {
- Some(idx) => subs.split_at(idx),
- None => (subs, &[][..]),
- };
- let post_idx_offset = field_tys.iter().count().saturating_sub(post.len());
-
- let pre_iter = pre.iter().enumerate();
- let post_iter = (post_idx_offset..).zip(post.iter());
- for (i, &subpat) in pre_iter.chain(post_iter) {
- let expected_ty = var_data
- .as_ref()
- .and_then(|d| d.field(&Name::new_tuple_field(i)))
- .map_or(self.err_ty(), |field| {
- field_tys[field].clone().substitute(Interner, &substs)
- });
- let expected_ty = self.normalize_associated_types_in(expected_ty);
- T::infer(self, subpat, &expected_ty, default_bm);
+ match def {
+ _ if subs.len() == 0 => {}
+ Some(def) => {
+ let field_types = self.db.field_types(def);
+ let variant_data = def.variant_data(self.db.upcast());
+ let visibilities = self.db.field_visibilities(def);
+
+ let (pre, post) = match ellipsis {
+ Some(idx) => subs.split_at(idx),
+ None => (subs, &[][..]),
+ };
+ let post_idx_offset = field_types.iter().count().saturating_sub(post.len());
+
+ let pre_iter = pre.iter().enumerate();
+ let post_iter = (post_idx_offset..).zip(post.iter());
+
+ for (i, &subpat) in pre_iter.chain(post_iter) {
+ let field_def = {
+ match variant_data.field(&Name::new_tuple_field(i)) {
+ Some(local_id) => {
+ if !visibilities[local_id]
+ .is_visible_from(self.db.upcast(), self.resolver.module())
+ {
+ // FIXME(DIAGNOSE): private tuple field
+ }
+ Some(local_id)
+ }
+ None => None,
+ }
+ };
+
+ let expected_ty = field_def.map_or(self.err_ty(), |f| {
+ field_types[f].clone().substitute(Interner, &substs)
+ });
+ let expected_ty = self.normalize_associated_types_in(expected_ty);
+
+ T::infer(self, subpat, &expected_ty, default_bm);
+ }
+ }
+ None => {
+ let err_ty = self.err_ty();
+ for &inner in subs {
+ T::infer(self, inner, &err_ty, default_bm);
+ }
+ }
}
ty
@@ -109,7 +149,7 @@ impl InferenceContext<'_> {
expected: &Ty,
default_bm: T::BindingMode,
id: T,
- subs: impl Iterator<Item = (Name, T)>,
+ subs: impl Iterator<Item = (Name, T)> + ExactSizeIterator,
) -> Ty {
let (ty, def) = self.resolve_variant(path, false);
if let Some(variant) = def {
@@ -121,17 +161,51 @@ impl InferenceContext<'_> {
let substs =
ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
- let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
- let var_data = def.map(|it| it.variant_data(self.db.upcast()));
+ match def {
+ _ if subs.len() == 0 => {}
+ Some(def) => {
+ let field_types = self.db.field_types(def);
+ let variant_data = def.variant_data(self.db.upcast());
+ let visibilities = self.db.field_visibilities(def);
+
+ for (name, inner) in subs {
+ let field_def = {
+ match variant_data.field(&name) {
+ Some(local_id) => {
+ if !visibilities[local_id]
+ .is_visible_from(self.db.upcast(), self.resolver.module())
+ {
+ self.push_diagnostic(InferenceDiagnostic::NoSuchField {
+ field: inner.into(),
+ private: true,
+ });
+ }
+ Some(local_id)
+ }
+ None => {
+ self.push_diagnostic(InferenceDiagnostic::NoSuchField {
+ field: inner.into(),
+ private: false,
+ });
+ None
+ }
+ }
+ };
- for (name, inner) in subs {
- let expected_ty = var_data
- .as_ref()
- .and_then(|it| it.field(&name))
- .map_or(self.err_ty(), |f| field_tys[f].clone().substitute(Interner, &substs));
- let expected_ty = self.normalize_associated_types_in(expected_ty);
+ let expected_ty = field_def.map_or(self.err_ty(), |f| {
+ field_types[f].clone().substitute(Interner, &substs)
+ });
+ let expected_ty = self.normalize_associated_types_in(expected_ty);
- T::infer(self, inner, &expected_ty, default_bm);
+ T::infer(self, inner, &expected_ty, default_bm);
+ }
+ }
+ None => {
+ let err_ty = self.err_ty();
+ for (_, inner) in subs {
+ T::infer(self, inner, &err_ty, default_bm);
+ }
+ }
}
ty
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
index 79d9e21e7..c6bbf2f61 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
@@ -61,8 +61,8 @@ impl InferenceContext<'_> {
self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?;
match value_or_partial {
- ResolveValueResult::ValueNs(it) => (it, None),
- ResolveValueResult::Partial(def, remaining_index) => self
+ ResolveValueResult::ValueNs(it, _) => (it, None),
+ ResolveValueResult::Partial(def, remaining_index, _) => self
.resolve_assoc_item(def, path, remaining_index, id)
.map(|(it, substs)| (it, Some(substs)))?,
}
@@ -178,13 +178,30 @@ impl InferenceContext<'_> {
remaining_index: usize,
id: ExprOrPatId,
) -> Option<(ValueNs, Substitution)> {
- assert!(remaining_index < path.segments().len());
// there may be more intermediate segments between the resolved one and
// the end. Only the last segment needs to be resolved to a value; from
// the segments before that, we need to get either a type or a trait ref.
- let resolved_segment = path.segments().get(remaining_index - 1).unwrap();
- let remaining_segments = path.segments().skip(remaining_index);
+ let _d;
+ let (resolved_segment, remaining_segments) = match path {
+ Path::Normal { .. } => {
+ assert!(remaining_index < path.segments().len());
+ (
+ path.segments().get(remaining_index - 1).unwrap(),
+ path.segments().skip(remaining_index),
+ )
+ }
+ Path::LangItem(..) => (
+ PathSegment {
+ name: {
+ _d = hir_expand::name::known::Unknown;
+ &_d
+ },
+ args_and_bindings: None,
+ },
+ path.segments(),
+ ),
+ };
let is_before_last = remaining_segments.len() == 1;
match (def, is_before_last) {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
index 0fb71135b..0a68a9f3b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -10,7 +10,6 @@ use chalk_solve::infer::ParameterEnaVariableExt;
use either::Either;
use ena::unify::UnifyKey;
use hir_expand::name;
-use stdx::never;
use triomphe::Arc;
use super::{InferOk, InferResult, InferenceContext, TypeError};
@@ -92,15 +91,10 @@ pub(crate) fn unify(
let vars = Substitution::from_iter(
Interner,
tys.binders.iter(Interner).map(|it| match &it.kind {
- chalk_ir::VariableKind::Ty(_) => {
- GenericArgData::Ty(table.new_type_var()).intern(Interner)
- }
- chalk_ir::VariableKind::Lifetime => {
- GenericArgData::Ty(table.new_type_var()).intern(Interner)
- } // FIXME: maybe wrong?
- chalk_ir::VariableKind::Const(ty) => {
- GenericArgData::Const(table.new_const_var(ty.clone())).intern(Interner)
- }
+ chalk_ir::VariableKind::Ty(_) => table.new_type_var().cast(Interner),
+ // FIXME: maybe wrong?
+ chalk_ir::VariableKind::Lifetime => table.new_type_var().cast(Interner),
+ chalk_ir::VariableKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
}),
);
let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
@@ -111,10 +105,10 @@ pub(crate) fn unify(
// default any type vars that weren't unified back to their original bound vars
// (kind of hacky)
let find_var = |iv| {
- vars.iter(Interner).position(|v| match v.interned() {
- chalk_ir::GenericArgData::Ty(ty) => ty.inference_var(Interner),
- chalk_ir::GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
- chalk_ir::GenericArgData::Const(c) => c.inference_var(Interner),
+ vars.iter(Interner).position(|v| match v.data(Interner) {
+ GenericArgData::Ty(ty) => ty.inference_var(Interner),
+ GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
+ GenericArgData::Const(c) => c.inference_var(Interner),
} == Some(iv))
};
let fallback = |iv, kind, default, binder| match kind {
@@ -149,6 +143,9 @@ pub(crate) struct InferenceTable<'a> {
var_unification_table: ChalkInferenceTable,
type_variable_table: Vec<TypeVariableFlags>,
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
+ /// Double buffer used in [`Self::resolve_obligations_as_possible`] to cut down on
+ /// temporary allocations.
+ resolve_obligations_buffer: Vec<Canonicalized<InEnvironment<Goal>>>,
}
pub(crate) struct InferenceTableSnapshot {
@@ -165,6 +162,7 @@ impl<'a> InferenceTable<'a> {
var_unification_table: ChalkInferenceTable::new(),
type_variable_table: Vec::new(),
pending_obligations: Vec::new(),
+ resolve_obligations_buffer: Vec::new(),
}
}
@@ -516,10 +514,10 @@ impl<'a> InferenceTable<'a> {
pub(crate) fn resolve_obligations_as_possible(&mut self) {
let _span = profile::span("resolve_obligations_as_possible");
let mut changed = true;
- let mut obligations = Vec::new();
- while changed {
- changed = false;
+ let mut obligations = mem::take(&mut self.resolve_obligations_buffer);
+ while mem::take(&mut changed) {
mem::swap(&mut self.pending_obligations, &mut obligations);
+
for canonicalized in obligations.drain(..) {
if !self.check_changed(&canonicalized) {
self.pending_obligations.push(canonicalized);
@@ -534,6 +532,8 @@ impl<'a> InferenceTable<'a> {
self.register_obligation_in_env(uncanonical);
}
}
+ self.resolve_obligations_buffer = obligations;
+ self.resolve_obligations_buffer.clear();
}
pub(crate) fn fudge_inference<T: TypeFoldable<Interner>>(
@@ -611,9 +611,9 @@ impl<'a> InferenceTable<'a> {
fn check_changed(&mut self, canonicalized: &Canonicalized<InEnvironment<Goal>>) -> bool {
canonicalized.free_vars.iter().any(|var| {
let iv = match var.data(Interner) {
- chalk_ir::GenericArgData::Ty(ty) => ty.inference_var(Interner),
- chalk_ir::GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
- chalk_ir::GenericArgData::Const(c) => c.inference_var(Interner),
+ GenericArgData::Ty(ty) => ty.inference_var(Interner),
+ GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
+ GenericArgData::Const(c) => c.inference_var(Interner),
}
.expect("free var is not inference var");
if self.var_unification_table.probe_var(iv).is_some() {
@@ -690,14 +690,10 @@ impl<'a> InferenceTable<'a> {
.fill(|it| {
let arg = match it {
ParamKind::Type => self.new_type_var(),
- ParamKind::Const(ty) => {
- never!("Tuple with const parameter");
- return GenericArgData::Const(self.new_const_var(ty.clone()))
- .intern(Interner);
- }
+ ParamKind::Const(_) => unreachable!("Tuple with const parameter"),
};
arg_tys.push(arg.clone());
- GenericArgData::Ty(arg).intern(Interner)
+ arg.cast(Interner)
})
.build();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index b15339d44..1a6106c02 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -24,7 +24,7 @@ pub use self::{
macro_rules! user_error {
($it: expr) => {
- return Err(LayoutError::UserError(format!($it)))
+ return Err(LayoutError::UserError(format!($it).into()))
};
}
@@ -50,7 +50,7 @@ pub type Variants = hir_def::layout::Variants<RustcEnumVariantIdx>;
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum LayoutError {
- UserError(String),
+ UserError(Box<str>),
SizeOverflow,
TargetLayoutNotAvailable,
HasPlaceholder,
@@ -109,7 +109,8 @@ fn layout_of_simd_ty(
// * the homogeneous field type and the number of fields.
let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) {
// Extract the number of elements from the layout of the array field:
- let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields else {
+ let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
+ else {
user_error!("Array with non array layout");
};
@@ -233,9 +234,9 @@ pub fn layout_of_ty_query(
cx.univariant(dl, &fields, &ReprOptions::default(), kind).ok_or(LayoutError::Unknown)?
}
TyKind::Array(element, count) => {
- let count = try_const_usize(db, &count).ok_or(LayoutError::UserError(
- "unevaluated or mistyped const generic parameter".to_string(),
- ))? as u64;
+ let count = try_const_usize(db, &count).ok_or(LayoutError::UserError(Box::from(
+ "unevaluated or mistyped const generic parameter",
+ )))? as u64;
let element = db.layout_of_ty(element.clone(), trait_env.clone())?;
let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow)?;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
index 1c92e80f3..85ef649b8 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
@@ -163,7 +163,7 @@ fn repr_discr(
return Err(LayoutError::UserError(
"Integer::repr_discr: `#[repr]` hint too small for \
discriminant range of enum "
- .to_string(),
+ .into(),
));
}
return Ok((discr, ity.is_signed()));
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
index 333ad473a..ffdbb9de9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
@@ -212,14 +212,14 @@ fn recursive() {
}
check_fail(
r#"struct Goal(Goal);"#,
- LayoutError::UserError("infinite sized recursive type".to_string()),
+ LayoutError::UserError("infinite sized recursive type".into()),
);
check_fail(
r#"
struct Foo<T>(Foo<T>);
struct Goal(Foo<i32>);
"#,
- LayoutError::UserError("infinite sized recursive type".to_string()),
+ LayoutError::UserError("infinite sized recursive type".into()),
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs
index 576e7f3fc..bbe855a14 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests/closure.rs
@@ -255,3 +255,17 @@ fn ellipsis_pattern() {
}
}
}
+
+#[test]
+fn regression_15623() {
+ size_and_align_expr! {
+ let a = 2;
+ let b = 3;
+ let c = 5;
+ move || {
+ let 0 = a else { return b; };
+ let y = c;
+ y
+ }
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index b3ca2a222..405bb001b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -52,12 +52,14 @@ use hir_expand::name;
use la_arena::{Arena, Idx};
use mir::{MirEvalError, VTableMap};
use rustc_hash::FxHashSet;
+use syntax::ast::{make, ConstArg};
use traits::FnTrait;
use triomphe::Arc;
use utils::Generics;
use crate::{
- consteval::unknown_const, db::HirDatabase, infer::unify::InferenceTable, utils::generics,
+ consteval::unknown_const, db::HirDatabase, display::HirDisplay, infer::unify::InferenceTable,
+ utils::generics,
};
pub use autoderef::autoderef;
@@ -719,3 +721,16 @@ where
value.visit_with(&mut collector, DebruijnIndex::INNERMOST);
collector.placeholders.into_iter().collect()
}
+
+pub fn known_const_to_ast(konst: &Const, db: &dyn HirDatabase) -> Option<ConstArg> {
+ if let ConstValue::Concrete(c) = &konst.interned().value {
+ match c.interned {
+ ConstScalar::UnevaluatedConst(GeneralConstId::InTypeConstId(cid), _) => {
+ return Some(cid.source(db.upcast()));
+ }
+ ConstScalar::Unknown => return None,
+ _ => (),
+ }
+ }
+ Some(make::expr_const_value(konst.display(db).to_string().as_str()))
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 2837f400b..9a61f1535 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -58,10 +58,9 @@ use crate::{
InTypeConstIdMetadata,
},
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
- FnPointer, FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig,
- ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait,
- ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder,
- TyKind, WhereClause,
+ FnPointer, FnSig, FnSubst, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
+ QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
+ Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
};
#[derive(Debug)]
@@ -213,6 +212,19 @@ impl<'a> TyLoweringContext<'a> {
self.lower_ty_ext(type_ref).0
}
+ pub fn lower_const(&self, const_ref: &ConstRef, const_type: Ty) -> Const {
+ const_or_path_to_chalk(
+ self.db,
+ self.resolver,
+ self.owner,
+ const_type,
+ const_ref,
+ self.type_param_mode,
+ || self.generics(),
+ self.in_binders,
+ )
+ }
+
fn generics(&self) -> Generics {
generics(
self.db.upcast(),
@@ -242,17 +254,7 @@ impl<'a> TyLoweringContext<'a> {
}
TypeRef::Array(inner, len) => {
let inner_ty = self.lower_ty(inner);
- let const_len = const_or_path_to_chalk(
- self.db,
- self.resolver,
- self.owner,
- TyBuilder::usize(),
- len,
- self.type_param_mode,
- || self.generics(),
- self.in_binders,
- );
-
+ let const_len = self.lower_const(len, TyBuilder::usize());
TyKind::Array(inner_ty, const_len).intern(Interner)
}
TypeRef::Slice(inner) => {
@@ -391,11 +393,9 @@ impl<'a> TyLoweringContext<'a> {
let ty = {
let macro_call = macro_call.to_node(self.db.upcast());
let resolver = |path| {
- self.resolver.resolve_path_as_macro(
- self.db.upcast(),
- &path,
- Some(MacroSubNs::Bang),
- )
+ self.resolver
+ .resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
+ .map(|(it, _)| it)
};
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
{
@@ -447,7 +447,7 @@ impl<'a> TyLoweringContext<'a> {
return None;
}
let resolution = match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
- Some((it, None)) => it,
+ Some((it, None, _)) => it,
_ => return None,
};
match resolution {
@@ -627,7 +627,7 @@ impl<'a> TyLoweringContext<'a> {
return self.lower_ty_relative_path(ty, res, path.segments());
}
- let (resolution, remaining_index) =
+ let (resolution, remaining_index, _) =
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
Some(it) => it,
None => return (TyKind::Error.intern(Interner), None),
@@ -847,18 +847,7 @@ impl<'a> TyLoweringContext<'a> {
arg,
&mut (),
|_, type_ref| self.lower_ty(type_ref),
- |_, c, ty| {
- const_or_path_to_chalk(
- self.db,
- self.resolver,
- self.owner,
- ty,
- c,
- self.type_param_mode,
- || self.generics(),
- self.in_binders,
- )
- },
+ |_, const_ref, ty| self.lower_const(const_ref, ty),
) {
had_explicit_args = true;
substs.push(x);
@@ -1604,24 +1593,35 @@ pub(crate) fn generic_defaults_query(
.iter()
.enumerate()
.map(|(idx, (id, p))| {
- let p = match p {
- TypeOrConstParamData::TypeParamData(p) => p,
- TypeOrConstParamData::ConstParamData(_) => {
- // FIXME: implement const generic defaults
- let val = unknown_const_as_generic(
- db.const_param_ty(ConstParamId::from_unchecked(id)),
+ match p {
+ TypeOrConstParamData::TypeParamData(p) => {
+ let mut ty = p
+ .default
+ .as_ref()
+ .map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
+ // Each default can only refer to previous parameters.
+ // Type variable default referring to parameter coming
+ // after it is forbidden (FIXME: report diagnostic)
+ ty = fallback_bound_vars(ty, idx, parent_start_idx);
+ crate::make_binders(db, &generic_params, ty.cast(Interner))
+ }
+ TypeOrConstParamData::ConstParamData(p) => {
+ let mut val = p.default.as_ref().map_or_else(
+ || {
+ unknown_const_as_generic(
+ db.const_param_ty(ConstParamId::from_unchecked(id)),
+ )
+ },
+ |c| {
+ let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
+ c.cast(Interner)
+ },
);
- return make_binders(db, &generic_params, val);
+ // Each default can only refer to previous parameters, see above.
+ val = fallback_bound_vars(val, idx, parent_start_idx);
+ make_binders(db, &generic_params, val)
}
- };
- let mut ty =
- p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
-
- // Each default can only refer to previous parameters.
- // Type variable default referring to parameter coming
- // after it is forbidden (FIXME: report diagnostic)
- ty = fallback_bound_vars(ty, idx, parent_start_idx);
- crate::make_binders(db, &generic_params, ty.cast(Interner))
+ }
})
// FIXME: use `Arc::from_iter` when it becomes available
.collect::<Vec<_>>(),
@@ -1643,9 +1643,7 @@ pub(crate) fn generic_defaults_recover(
.iter_id()
.map(|id| {
let val = match id {
- Either::Left(_) => {
- GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
- }
+ Either::Left(_) => TyKind::Error.intern(Interner).cast(Interner),
Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
};
crate::make_binders(db, &generic_params, val)
@@ -1991,16 +1989,9 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
}
};
Some(match (arg, kind) {
- (GenericArg::Type(type_ref), ParamKind::Type) => {
- let ty = for_type(this, type_ref);
- GenericArgData::Ty(ty).intern(Interner)
- }
- (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
- GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
- }
- (GenericArg::Const(_), ParamKind::Type) => {
- GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
- }
+ (GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, type_ref).cast(Interner),
+ (GenericArg::Const(c), ParamKind::Const(c_ty)) => for_const(this, c, c_ty).cast(Interner),
+ (GenericArg::Const(_), ParamKind::Type) => TyKind::Error.intern(Interner).cast(Interner),
(GenericArg::Type(t), ParamKind::Const(c_ty)) => {
// We want to recover simple idents, which parser detects them
// as types. Maybe here is not the best place to do it, but
@@ -2010,9 +2001,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
if p.kind == PathKind::Plain {
if let [n] = p.segments() {
let c = ConstRef::Path(n.clone());
- return Some(
- GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
- );
+ return Some(for_const(this, &c, c_ty).cast(Interner));
}
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
index 4723c25ed..e953058cc 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir.rs
@@ -1,6 +1,6 @@
//! MIR definitions and implementation
-use std::{fmt::Display, iter};
+use std::{collections::hash_map::Entry, fmt::Display, iter};
use crate::{
consteval::usize_const,
@@ -37,6 +37,7 @@ pub use monomorphization::{
monomorphize_mir_body_bad, monomorphized_mir_body_for_closure_query,
monomorphized_mir_body_query, monomorphized_mir_body_recover,
};
+use rustc_hash::FxHashMap;
use smallvec::{smallvec, SmallVec};
use stdx::{impl_from, never};
use triomphe::Arc;
@@ -165,8 +166,8 @@ impl<V, T> ProjectionElem<V, T> {
TyKind::Adt(_, subst) => {
db.field_types(f.parent)[f.local_id].clone().substitute(Interner, subst)
}
- _ => {
- never!("Only adt has field");
+ ty => {
+ never!("Only adt has field, found {:?}", ty);
return TyKind::Error.intern(Interner);
}
},
@@ -223,35 +224,93 @@ impl<V, T> ProjectionElem<V, T> {
type PlaceElem = ProjectionElem<LocalId, Ty>;
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct ProjectionId(u32);
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ProjectionStore {
+ id_to_proj: FxHashMap<ProjectionId, Box<[PlaceElem]>>,
+ proj_to_id: FxHashMap<Box<[PlaceElem]>, ProjectionId>,
+}
+
+impl Default for ProjectionStore {
+ fn default() -> Self {
+ let mut this = Self { id_to_proj: Default::default(), proj_to_id: Default::default() };
+ // Ensure that [] will get the id 0 which is used in `ProjectionId::Empty`
+ this.intern(Box::new([]));
+ this
+ }
+}
+
+impl ProjectionStore {
+ fn shrink_to_fit(&mut self) {
+ self.id_to_proj.shrink_to_fit();
+ self.proj_to_id.shrink_to_fit();
+ }
+
+ fn intern_if_exist(&self, projection: &[PlaceElem]) -> Option<ProjectionId> {
+ self.proj_to_id.get(projection).copied()
+ }
+
+ fn intern(&mut self, projection: Box<[PlaceElem]>) -> ProjectionId {
+ let new_id = ProjectionId(self.proj_to_id.len() as u32);
+ match self.proj_to_id.entry(projection) {
+ Entry::Occupied(id) => *id.get(),
+ Entry::Vacant(e) => {
+ let key_clone = e.key().clone();
+ e.insert(new_id);
+ self.id_to_proj.insert(new_id, key_clone);
+ new_id
+ }
+ }
+ }
+}
+
+impl ProjectionId {
+ const EMPTY: ProjectionId = ProjectionId(0);
+
+ fn lookup(self, store: &ProjectionStore) -> &[PlaceElem] {
+ store.id_to_proj.get(&self).unwrap()
+ }
+
+ fn project(self, projection: PlaceElem, store: &mut ProjectionStore) -> ProjectionId {
+ let mut current = self.lookup(store).to_vec();
+ current.push(projection);
+ store.intern(current.into())
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Place {
pub local: LocalId,
- pub projection: Box<[PlaceElem]>,
+ pub projection: ProjectionId,
}
impl Place {
- fn is_parent(&self, child: &Place) -> bool {
- self.local == child.local && child.projection.starts_with(&self.projection)
+ fn is_parent(&self, child: &Place, store: &ProjectionStore) -> bool {
+ self.local == child.local
+ && child.projection.lookup(store).starts_with(&self.projection.lookup(store))
}
/// The place itself is not included
- fn iterate_over_parents(&self) -> impl Iterator<Item = Place> + '_ {
- (0..self.projection.len())
- .map(|x| &self.projection[0..x])
- .map(|x| Place { local: self.local, projection: x.to_vec().into() })
+ fn iterate_over_parents<'a>(
+ &'a self,
+ store: &'a ProjectionStore,
+ ) -> impl Iterator<Item = Place> + 'a {
+ let projection = self.projection.lookup(store);
+ (0..projection.len()).map(|x| &projection[0..x]).filter_map(move |x| {
+ Some(Place { local: self.local, projection: store.intern_if_exist(x)? })
+ })
}
- fn project(&self, projection: PlaceElem) -> Place {
- Place {
- local: self.local,
- projection: self.projection.iter().cloned().chain([projection]).collect(),
- }
+ fn project(&self, projection: PlaceElem, store: &mut ProjectionStore) -> Place {
+ Place { local: self.local, projection: self.projection.project(projection, store) }
}
}
impl From<LocalId> for Place {
fn from(local: LocalId) -> Self {
- Self { local, projection: vec![].into() }
+ Self { local, projection: ProjectionId::EMPTY }
}
}
@@ -368,7 +427,7 @@ pub enum TerminatorKind {
///
/// Only permitted in cleanup blocks. `Resume` is not permitted with `-C unwind=abort` after
/// deaggregation runs.
- Resume,
+ UnwindResume,
/// Indicates that the landing pad is finished and that the process should abort.
///
@@ -997,6 +1056,7 @@ pub struct BasicBlock {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MirBody {
+ pub projection_store: ProjectionStore,
pub basic_blocks: Arena<BasicBlock>,
pub locals: Arena<Local>,
pub start_block: BasicBlockId,
@@ -1009,11 +1069,15 @@ pub struct MirBody {
}
impl MirBody {
- fn walk_places(&mut self, mut f: impl FnMut(&mut Place)) {
- fn for_operand(op: &mut Operand, f: &mut impl FnMut(&mut Place)) {
+ fn walk_places(&mut self, mut f: impl FnMut(&mut Place, &mut ProjectionStore)) {
+ fn for_operand(
+ op: &mut Operand,
+ f: &mut impl FnMut(&mut Place, &mut ProjectionStore),
+ store: &mut ProjectionStore,
+ ) {
match op {
Operand::Copy(p) | Operand::Move(p) => {
- f(p);
+ f(p, store);
}
Operand::Constant(_) | Operand::Static(_) => (),
}
@@ -1022,30 +1086,30 @@ impl MirBody {
for statement in &mut block.statements {
match &mut statement.kind {
StatementKind::Assign(p, r) => {
- f(p);
+ f(p, &mut self.projection_store);
match r {
Rvalue::ShallowInitBoxWithAlloc(_) => (),
Rvalue::ShallowInitBox(o, _)
| Rvalue::UnaryOp(_, o)
| Rvalue::Cast(_, o, _)
| Rvalue::Repeat(o, _)
- | Rvalue::Use(o) => for_operand(o, &mut f),
+ | Rvalue::Use(o) => for_operand(o, &mut f, &mut self.projection_store),
Rvalue::CopyForDeref(p)
| Rvalue::Discriminant(p)
| Rvalue::Len(p)
- | Rvalue::Ref(_, p) => f(p),
+ | Rvalue::Ref(_, p) => f(p, &mut self.projection_store),
Rvalue::CheckedBinaryOp(_, o1, o2) => {
- for_operand(o1, &mut f);
- for_operand(o2, &mut f);
+ for_operand(o1, &mut f, &mut self.projection_store);
+ for_operand(o2, &mut f, &mut self.projection_store);
}
Rvalue::Aggregate(_, ops) => {
for op in ops.iter_mut() {
- for_operand(op, &mut f);
+ for_operand(op, &mut f, &mut self.projection_store);
}
}
}
}
- StatementKind::Deinit(p) => f(p),
+ StatementKind::Deinit(p) => f(p, &mut self.projection_store),
StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Nop => (),
@@ -1053,33 +1117,36 @@ impl MirBody {
}
match &mut block.terminator {
Some(x) => match &mut x.kind {
- TerminatorKind::SwitchInt { discr, .. } => for_operand(discr, &mut f),
+ TerminatorKind::SwitchInt { discr, .. } => {
+ for_operand(discr, &mut f, &mut self.projection_store)
+ }
TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::Goto { .. }
- | TerminatorKind::Resume
+ | TerminatorKind::UnwindResume
| TerminatorKind::GeneratorDrop
| TerminatorKind::Abort
| TerminatorKind::Return
| TerminatorKind::Unreachable => (),
TerminatorKind::Drop { place, .. } => {
- f(place);
+ f(place, &mut self.projection_store);
}
TerminatorKind::DropAndReplace { place, value, .. } => {
- f(place);
- for_operand(value, &mut f);
+ f(place, &mut self.projection_store);
+ for_operand(value, &mut f, &mut self.projection_store);
}
TerminatorKind::Call { func, args, destination, .. } => {
- for_operand(func, &mut f);
- args.iter_mut().for_each(|x| for_operand(x, &mut f));
- f(destination);
+ for_operand(func, &mut f, &mut self.projection_store);
+ args.iter_mut()
+ .for_each(|x| for_operand(x, &mut f, &mut self.projection_store));
+ f(destination, &mut self.projection_store);
}
TerminatorKind::Assert { cond, .. } => {
- for_operand(cond, &mut f);
+ for_operand(cond, &mut f, &mut self.projection_store);
}
TerminatorKind::Yield { value, resume_arg, .. } => {
- for_operand(value, &mut f);
- f(resume_arg);
+ for_operand(value, &mut f, &mut self.projection_store);
+ f(resume_arg, &mut self.projection_store);
}
},
None => (),
@@ -1096,7 +1163,9 @@ impl MirBody {
binding_locals,
param_locals,
closures,
+ projection_store,
} = self;
+ projection_store.shrink_to_fit();
basic_blocks.shrink_to_fit();
locals.shrink_to_fit();
binding_locals.shrink_to_fit();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
index ad98e8fa1..41fb12965 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/borrowck.rs
@@ -42,30 +42,27 @@ pub struct BorrowckResult {
fn all_mir_bodies(
db: &dyn HirDatabase,
def: DefWithBodyId,
-) -> Box<dyn Iterator<Item = Result<Arc<MirBody>, MirLowerError>> + '_> {
+ mut cb: impl FnMut(Arc<MirBody>),
+) -> Result<(), MirLowerError> {
fn for_closure(
db: &dyn HirDatabase,
c: ClosureId,
- ) -> Box<dyn Iterator<Item = Result<Arc<MirBody>, MirLowerError>> + '_> {
+ cb: &mut impl FnMut(Arc<MirBody>),
+ ) -> Result<(), MirLowerError> {
match db.mir_body_for_closure(c) {
Ok(body) => {
- let closures = body.closures.clone();
- Box::new(
- iter::once(Ok(body))
- .chain(closures.into_iter().flat_map(|it| for_closure(db, it))),
- )
+ cb(body.clone());
+ body.closures.iter().map(|&it| for_closure(db, it, cb)).collect()
}
- Err(e) => Box::new(iter::once(Err(e))),
+ Err(e) => Err(e),
}
}
match db.mir_body(def) {
Ok(body) => {
- let closures = body.closures.clone();
- Box::new(
- iter::once(Ok(body)).chain(closures.into_iter().flat_map(|it| for_closure(db, it))),
- )
+ cb(body.clone());
+ body.closures.iter().map(|&it| for_closure(db, it, &mut cb)).collect()
}
- Err(e) => Box::new(iter::once(Err(e))),
+ Err(e) => Err(e),
}
}
@@ -74,17 +71,15 @@ pub fn borrowck_query(
def: DefWithBodyId,
) -> Result<Arc<[BorrowckResult]>, MirLowerError> {
let _p = profile::span("borrowck_query");
- let r = all_mir_bodies(db, def)
- .map(|body| {
- let body = body?;
- Ok(BorrowckResult {
- mutability_of_locals: mutability_of_locals(db, &body),
- moved_out_of_ref: moved_out_of_ref(db, &body),
- mir_body: body,
- })
- })
- .collect::<Result<Vec<_>, MirLowerError>>()?;
- Ok(r.into())
+ let mut res = vec![];
+ all_mir_bodies(db, def, |body| {
+ res.push(BorrowckResult {
+ mutability_of_locals: mutability_of_locals(db, &body),
+ moved_out_of_ref: moved_out_of_ref(db, &body),
+ mir_body: body,
+ });
+ })?;
+ Ok(res.into())
}
fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> {
@@ -93,7 +88,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
Operand::Copy(p) | Operand::Move(p) => {
let mut ty: Ty = body.locals[p.local].ty.clone();
let mut is_dereference_of_ref = false;
- for proj in &*p.projection {
+ for proj in p.projection.lookup(&body.projection_store) {
if *proj == ProjectionElem::Deref && ty.as_reference().is_some() {
is_dereference_of_ref = true;
}
@@ -125,6 +120,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
Operand::Constant(_) | Operand::Static(_) => (),
};
for (_, block) in body.basic_blocks.iter() {
+ db.unwind_if_cancelled();
for statement in &block.statements {
match &statement.kind {
StatementKind::Assign(_, r) => match r {
@@ -160,7 +156,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::Goto { .. }
- | TerminatorKind::Resume
+ | TerminatorKind::UnwindResume
| TerminatorKind::GeneratorDrop
| TerminatorKind::Abort
| TerminatorKind::Return
@@ -183,6 +179,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
None => (),
}
}
+ result.shrink_to_fit();
result
}
@@ -199,7 +196,7 @@ enum ProjectionCase {
fn place_case(db: &dyn HirDatabase, body: &MirBody, lvalue: &Place) -> ProjectionCase {
let mut is_part_of = false;
let mut ty = body.locals[lvalue.local].ty.clone();
- for proj in lvalue.projection.iter() {
+ for proj in lvalue.projection.lookup(&body.projection_store).iter() {
match proj {
ProjectionElem::Deref if ty.as_adt().is_none() => return ProjectionCase::Indirect, // It's indirect in case of reference and raw
ProjectionElem::Deref // It's direct in case of `Box<T>`
@@ -258,7 +255,7 @@ fn ever_initialized_map(
for statement in &block.statements {
match &statement.kind {
StatementKind::Assign(p, _) => {
- if p.projection.len() == 0 && p.local == l {
+ if p.projection.lookup(&body.projection_store).len() == 0 && p.local == l {
is_ever_initialized = true;
}
}
@@ -277,21 +274,37 @@ fn ever_initialized_map(
);
return;
};
- let targets = match &terminator.kind {
- TerminatorKind::Goto { target } => vec![*target],
- TerminatorKind::SwitchInt { targets, .. } => targets.all_targets().to_vec(),
- TerminatorKind::Resume
+ let mut process = |target, is_ever_initialized| {
+ if !result[target].contains_idx(l) || !result[target][l] && is_ever_initialized {
+ result[target].insert(l, is_ever_initialized);
+ dfs(db, body, target, l, result);
+ }
+ };
+ match &terminator.kind {
+ TerminatorKind::Goto { target } => process(*target, is_ever_initialized),
+ TerminatorKind::SwitchInt { targets, .. } => {
+ targets.all_targets().iter().for_each(|&it| process(it, is_ever_initialized));
+ }
+ TerminatorKind::UnwindResume
| TerminatorKind::Abort
| TerminatorKind::Return
- | TerminatorKind::Unreachable => vec![],
+ | TerminatorKind::Unreachable => (),
TerminatorKind::Call { target, cleanup, destination, .. } => {
- if destination.projection.len() == 0 && destination.local == l {
+ if destination.projection.lookup(&body.projection_store).len() == 0
+ && destination.local == l
+ {
is_ever_initialized = true;
}
- target.into_iter().chain(cleanup.into_iter()).copied().collect()
+ target
+ .into_iter()
+ .chain(cleanup.into_iter())
+ .for_each(|&it| process(it, is_ever_initialized));
}
TerminatorKind::Drop { target, unwind, place: _ } => {
- Some(target).into_iter().chain(unwind.into_iter()).copied().collect()
+ iter::once(target)
+ .into_iter()
+ .chain(unwind.into_iter())
+ .for_each(|&it| process(it, is_ever_initialized));
}
TerminatorKind::DropAndReplace { .. }
| TerminatorKind::Assert { .. }
@@ -300,13 +313,7 @@ fn ever_initialized_map(
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. } => {
never!("We don't emit these MIR terminators yet");
- vec![]
- }
- };
- for target in targets {
- if !result[target].contains_idx(l) || !result[target][l] && is_ever_initialized {
- result[target].insert(l, is_ever_initialized);
- dfs(db, body, target, l, result);
+ ()
}
}
}
@@ -315,6 +322,7 @@ fn ever_initialized_map(
dfs(db, body, body.start_block, l, &mut result);
}
for l in body.locals.iter().map(|it| it.0) {
+ db.unwind_if_cancelled();
if !result[body.start_block].contains_idx(l) {
result[body.start_block].insert(l, false);
dfs(db, body, body.start_block, l, &mut result);
@@ -371,7 +379,7 @@ fn mutability_of_locals(
};
match &terminator.kind {
TerminatorKind::Goto { .. }
- | TerminatorKind::Resume
+ | TerminatorKind::UnwindResume
| TerminatorKind::Abort
| TerminatorKind::Return
| TerminatorKind::Unreachable
@@ -384,7 +392,7 @@ fn mutability_of_locals(
| TerminatorKind::Assert { .. }
| TerminatorKind::Yield { .. } => (),
TerminatorKind::Call { destination, .. } => {
- if destination.projection.len() == 0 {
+ if destination.projection.lookup(&body.projection_store).len() == 0 {
if ever_init_map.get(destination.local).copied().unwrap_or_default() {
push_mut_span(destination.local, MirSpan::Unknown);
} else {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index 9e30eed56..4364e0d32 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -10,7 +10,7 @@ use std::{
};
use base_db::{CrateId, FileId};
-use chalk_ir::Mutability;
+use chalk_ir::{cast::Cast, Mutability};
use either::Either;
use hir_def::{
builtin_type::BuiltinType,
@@ -40,14 +40,14 @@ use crate::{
name, static_lifetime,
traits::FnTrait,
utils::{detect_variant_from_bytes, ClosureSubst},
- CallableDefId, ClosureId, Const, ConstScalar, FnDefId, GenericArgData, Interner, MemoryMap,
- Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
+ CallableDefId, ClosureId, Const, ConstScalar, FnDefId, Interner, MemoryMap, Substitution,
+ TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
};
use super::{
return_slot, AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError,
- MirSpan, Operand, Place, PlaceElem, ProjectionElem, Rvalue, StatementKind, TerminatorKind,
- UnOp,
+ MirSpan, Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
+ TerminatorKind, UnOp,
};
mod shim;
@@ -215,9 +215,7 @@ impl Interval {
}
fn write_from_interval(&self, memory: &mut Evaluator<'_>, interval: Interval) -> Result<()> {
- // FIXME: this could be more efficient
- let bytes = &interval.get(memory)?.to_vec();
- memory.write_memory(self.addr, bytes)
+ memory.copy_from_interval(self.addr, interval)
}
fn slice(self, range: Range<usize>) -> Interval {
@@ -341,7 +339,7 @@ pub enum MirEvalError {
InvalidVTableId(usize),
CoerceUnsizedError(Ty),
LangItemNotFound(LangItem),
- BrokenLayout(Layout),
+ BrokenLayout(Box<Layout>),
}
impl MirEvalError {
@@ -410,7 +408,7 @@ impl MirEvalError {
err.pretty_print(f, db, span_formatter)?;
}
MirEvalError::ConstEvalError(name, err) => {
- MirLowerError::ConstEvalError(name.clone(), err.clone()).pretty_print(
+ MirLowerError::ConstEvalError((**name).into(), err.clone()).pretty_print(
f,
db,
span_formatter,
@@ -485,17 +483,18 @@ struct DropFlags {
}
impl DropFlags {
- fn add_place(&mut self, p: Place) {
- if p.iterate_over_parents().any(|it| self.need_drop.contains(&it)) {
+ fn add_place(&mut self, p: Place, store: &ProjectionStore) {
+ if p.iterate_over_parents(store).any(|it| self.need_drop.contains(&it)) {
return;
}
- self.need_drop.retain(|it| !p.is_parent(it));
+ self.need_drop.retain(|it| !p.is_parent(it, store));
self.need_drop.insert(p);
}
- fn remove_place(&mut self, p: &Place) -> bool {
+ fn remove_place(&mut self, p: &Place, store: &ProjectionStore) -> bool {
// FIXME: replace parents with parts
- if let Some(parent) = p.iterate_over_parents().find(|it| self.need_drop.contains(&it)) {
+ if let Some(parent) = p.iterate_over_parents(store).find(|it| self.need_drop.contains(&it))
+ {
self.need_drop.remove(&parent);
return true;
}
@@ -656,7 +655,7 @@ impl Evaluator<'_> {
let mut addr = locals.ptr[p.local].addr;
let mut ty: Ty = locals.body.locals[p.local].ty.clone();
let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
- for proj in &*p.projection {
+ for proj in p.projection.lookup(&locals.body.projection_store) {
let prev_ty = ty.clone();
ty = self.projected_ty(ty, proj.clone());
match proj {
@@ -837,7 +836,9 @@ impl Evaluator<'_> {
let addr = self.place_addr(l, &locals)?;
let result = self.eval_rvalue(r, &mut locals)?.to_vec(&self)?;
self.write_memory(addr, &result)?;
- locals.drop_flags.add_place(l.clone());
+ locals
+ .drop_flags
+ .add_place(l.clone(), &locals.body.projection_store);
}
StatementKind::Deinit(_) => not_supported!("de-init statement"),
StatementKind::StorageLive(_)
@@ -889,7 +890,9 @@ impl Evaluator<'_> {
)?,
it => not_supported!("unknown function type {it:?}"),
};
- locals.drop_flags.add_place(destination.clone());
+ locals
+ .drop_flags
+ .add_place(destination.clone(), &locals.body.projection_store);
if let Some(stack_frame) = stack_frame {
self.code_stack.push(my_stack_frame);
current_block_idx = stack_frame.locals.body.start_block;
@@ -970,7 +973,7 @@ impl Evaluator<'_> {
) -> Result<()> {
let mut remain_args = body.param_locals.len();
for ((l, interval), value) in locals.ptr.iter().skip(1).zip(args) {
- locals.drop_flags.add_place(l.into());
+ locals.drop_flags.add_place(l.into(), &locals.body.projection_store);
match value {
IntervalOrOwned::Owned(value) => interval.write_from_bytes(self, &value)?,
IntervalOrOwned::Borrowed(value) => interval.write_from_interval(self, value)?,
@@ -1629,7 +1632,7 @@ impl Evaluator<'_> {
if let Some((offset, size, value)) = tag {
match result.get_mut(offset..offset + size) {
Some(it) => it.copy_from_slice(&value.to_le_bytes()[0..size]),
- None => return Err(MirEvalError::BrokenLayout(variant_layout.clone())),
+ None => return Err(MirEvalError::BrokenLayout(Box::new(variant_layout.clone()))),
}
}
for (i, op) in values.enumerate() {
@@ -1637,7 +1640,7 @@ impl Evaluator<'_> {
let op = op.get(&self)?;
match result.get_mut(offset..offset + op.len()) {
Some(it) => it.copy_from_slice(op),
- None => return Err(MirEvalError::BrokenLayout(variant_layout.clone())),
+ None => return Err(MirEvalError::BrokenLayout(Box::new(variant_layout.clone()))),
}
}
Ok(result)
@@ -1646,7 +1649,7 @@ impl Evaluator<'_> {
fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> {
Ok(match it {
Operand::Copy(p) | Operand::Move(p) => {
- locals.drop_flags.remove_place(p);
+ locals.drop_flags.remove_place(p, &locals.body.projection_store);
self.eval_place(p, locals)?
}
Operand::Static(st) => {
@@ -1760,6 +1763,48 @@ impl Evaluator<'_> {
Ok(())
}
+ fn copy_from_interval(&mut self, addr: Address, r: Interval) -> Result<()> {
+ if r.size == 0 {
+ return Ok(());
+ }
+
+ let oob = || MirEvalError::UndefinedBehavior("out of bounds memory write".to_string());
+
+ match (addr, r.addr) {
+ (Stack(dst), Stack(src)) => {
+ if self.stack.len() < src + r.size || self.stack.len() < dst + r.size {
+ return Err(oob());
+ }
+ self.stack.copy_within(src..src + r.size, dst)
+ }
+ (Heap(dst), Heap(src)) => {
+ if self.stack.len() < src + r.size || self.stack.len() < dst + r.size {
+ return Err(oob());
+ }
+ self.heap.copy_within(src..src + r.size, dst)
+ }
+ (Stack(dst), Heap(src)) => {
+ self.stack
+ .get_mut(dst..dst + r.size)
+ .ok_or_else(oob)?
+ .copy_from_slice(self.heap.get(src..src + r.size).ok_or_else(oob)?);
+ }
+ (Heap(dst), Stack(src)) => {
+ self.heap
+ .get_mut(dst..dst + r.size)
+ .ok_or_else(oob)?
+ .copy_from_slice(self.stack.get(src..src + r.size).ok_or_else(oob)?);
+ }
+ _ => {
+ return Err(MirEvalError::UndefinedBehavior(format!(
+ "invalid memory write at address {addr:?}"
+ )))
+ }
+ }
+
+ Ok(())
+ }
+
fn size_align_of(&self, ty: &Ty, locals: &Locals) -> Result<Option<(usize, usize)>> {
if let Some(layout) = self.layout_cache.borrow().get(ty) {
return Ok(layout
@@ -2007,7 +2052,28 @@ impl Evaluator<'_> {
}
}
AdtId::UnionId(_) => (),
- AdtId::EnumId(_) => (),
+ AdtId::EnumId(e) => {
+ if let Some((variant, layout)) = detect_variant_from_bytes(
+ &layout,
+ self.db,
+ self.trait_env.clone(),
+ self.read_memory(addr, layout.size.bytes_usize())?,
+ e,
+ ) {
+ let ev = EnumVariantId { parent: e, local_id: variant };
+ for (i, (_, ty)) in self.db.field_types(ev.into()).iter().enumerate() {
+ let offset = layout.fields.offset(i).bytes_usize();
+ let ty = ty.clone().substitute(Interner, subst);
+ self.patch_addresses(
+ patch_map,
+ old_vtable,
+ addr.offset(offset),
+ &ty,
+ locals,
+ )?;
+ }
+ }
+ }
},
TyKind::Tuple(_, subst) => {
for (id, ty) in subst.iter(Interner).enumerate() {
@@ -2248,7 +2314,7 @@ impl Evaluator<'_> {
interval: args_for_target[0].interval.slice(0..self.ptr_size()),
ty: ty.clone(),
};
- let ty = GenericArgData::Ty(ty.clone()).intern(Interner);
+ let ty = ty.clone().cast(Interner);
let generics_for_target = Substitution::from_iter(
Interner,
generic_args.iter(Interner).enumerate().map(|(i, it)| {
@@ -2447,7 +2513,7 @@ impl Evaluator<'_> {
fn drop_place(&mut self, place: &Place, locals: &mut Locals, span: MirSpan) -> Result<()> {
let (addr, ty, metadata) = self.place_addr_and_ty_and_metadata(place, locals)?;
- if !locals.drop_flags.remove_place(place) {
+ if !locals.drop_flags.remove_place(place, &locals.body.projection_store) {
return Ok(());
}
let metadata = match metadata {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
index b2e29fd34..803ef631f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -4,7 +4,10 @@
use std::cmp;
use chalk_ir::TyKind;
-use hir_def::resolver::HasResolver;
+use hir_def::{
+ builtin_type::{BuiltinInt, BuiltinUint},
+ resolver::HasResolver,
+};
use hir_expand::mod_path::ModPath;
use super::*;
@@ -136,7 +139,10 @@ impl Evaluator<'_> {
not_supported!("wrong generic arg kind for clone");
};
// Clone has special impls for tuples and function pointers
- if matches!(self_ty.kind(Interner), TyKind::Function(_) | TyKind::Tuple(..)) {
+ if matches!(
+ self_ty.kind(Interner),
+ TyKind::Function(_) | TyKind::Tuple(..) | TyKind::Closure(..)
+ ) {
self.exec_clone(def, args, self_ty.clone(), locals, destination, span)?;
return Ok(true);
}
@@ -167,32 +173,26 @@ impl Evaluator<'_> {
return destination
.write_from_interval(self, Interval { addr, size: destination.size });
}
+ TyKind::Closure(id, subst) => {
+ let [arg] = args else {
+ not_supported!("wrong arg count for clone");
+ };
+ let addr = Address::from_bytes(arg.get(self)?)?;
+ let (closure_owner, _) = self.db.lookup_intern_closure((*id).into());
+ let infer = self.db.infer(closure_owner);
+ let (captures, _) = infer.closure_info(id);
+ let layout = self.layout(&self_ty)?;
+ let ty_iter = captures.iter().map(|c| c.ty(subst));
+ self.exec_clone_for_fields(ty_iter, layout, addr, def, locals, destination, span)?;
+ }
TyKind::Tuple(_, subst) => {
let [arg] = args else {
not_supported!("wrong arg count for clone");
};
let addr = Address::from_bytes(arg.get(self)?)?;
let layout = self.layout(&self_ty)?;
- for (i, ty) in subst.iter(Interner).enumerate() {
- let ty = ty.assert_ty_ref(Interner);
- let size = self.layout(ty)?.size.bytes_usize();
- let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
- let arg = IntervalAndTy {
- interval: Interval { addr: tmp, size: self.ptr_size() },
- ty: TyKind::Ref(Mutability::Not, static_lifetime(), ty.clone())
- .intern(Interner),
- };
- let offset = layout.fields.offset(i).bytes_usize();
- self.write_memory(tmp, &addr.offset(offset).to_bytes())?;
- self.exec_clone(
- def,
- &[arg],
- ty.clone(),
- locals,
- destination.slice(offset..offset + size),
- span,
- )?;
- }
+ let ty_iter = subst.iter(Interner).map(|ga| ga.assert_ty_ref(Interner).clone());
+ self.exec_clone_for_fields(ty_iter, layout, addr, def, locals, destination, span)?;
}
_ => {
self.exec_fn_with_args(
@@ -209,6 +209,37 @@ impl Evaluator<'_> {
Ok(())
}
+ fn exec_clone_for_fields(
+ &mut self,
+ ty_iter: impl Iterator<Item = Ty>,
+ layout: Arc<Layout>,
+ addr: Address,
+ def: FunctionId,
+ locals: &Locals,
+ destination: Interval,
+ span: MirSpan,
+ ) -> Result<()> {
+ for (i, ty) in ty_iter.enumerate() {
+ let size = self.layout(&ty)?.size.bytes_usize();
+ let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
+ let arg = IntervalAndTy {
+ interval: Interval { addr: tmp, size: self.ptr_size() },
+ ty: TyKind::Ref(Mutability::Not, static_lifetime(), ty.clone()).intern(Interner),
+ };
+ let offset = layout.fields.offset(i).bytes_usize();
+ self.write_memory(tmp, &addr.offset(offset).to_bytes())?;
+ self.exec_clone(
+ def,
+ &[arg],
+ ty,
+ locals,
+ destination.slice(offset..offset + size),
+ span,
+ )?;
+ }
+ Ok(())
+ }
+
fn exec_alloc_fn(
&mut self,
alloc_fn: &str,
@@ -272,21 +303,36 @@ impl Evaluator<'_> {
BeginPanic => Err(MirEvalError::Panic("<unknown-panic-payload>".to_string())),
PanicFmt => {
let message = (|| {
- let resolver = self.db.crate_def_map(self.crate_id).crate_root().resolver(self.db.upcast());
+ let resolver = self
+ .db
+ .crate_def_map(self.crate_id)
+ .crate_root()
+ .resolver(self.db.upcast());
let Some(format_fn) = resolver.resolve_path_in_value_ns_fully(
self.db.upcast(),
- &hir_def::path::Path::from_known_path_with_no_generic(ModPath::from_segments(
- hir_expand::mod_path::PathKind::Abs,
- [name![std], name![fmt], name![format]].into_iter(),
- )),
+ &hir_def::path::Path::from_known_path_with_no_generic(
+ ModPath::from_segments(
+ hir_expand::mod_path::PathKind::Abs,
+ [name![std], name![fmt], name![format]].into_iter(),
+ ),
+ ),
) else {
not_supported!("std::fmt::format not found");
};
- let hir_def::resolver::ValueNs::FunctionId(format_fn) = format_fn else { not_supported!("std::fmt::format is not a function") };
- let message_string = self.interpret_mir(self.db.mir_body(format_fn.into()).map_err(|e| MirEvalError::MirLowerError(format_fn, e))?, args.map(|x| IntervalOrOwned::Owned(x.clone())))?;
- let addr = Address::from_bytes(&message_string[self.ptr_size()..2 * self.ptr_size()])?;
+ let hir_def::resolver::ValueNs::FunctionId(format_fn) = format_fn else {
+ not_supported!("std::fmt::format is not a function")
+ };
+ let message_string = self.interpret_mir(
+ self.db
+ .mir_body(format_fn.into())
+ .map_err(|e| MirEvalError::MirLowerError(format_fn, e))?,
+ args.map(|x| IntervalOrOwned::Owned(x.clone())),
+ )?;
+ let addr =
+ Address::from_bytes(&message_string[self.ptr_size()..2 * self.ptr_size()])?;
let size = from_bytes!(usize, message_string[2 * self.ptr_size()..]);
- Ok(std::string::String::from_utf8_lossy(self.read_memory(addr, size)?).into_owned())
+ Ok(std::string::String::from_utf8_lossy(self.read_memory(addr, size)?)
+ .into_owned())
})()
.unwrap_or_else(|e| format!("Failed to render panic format args: {e:?}"));
Err(MirEvalError::Panic(message))
@@ -455,9 +501,7 @@ impl Evaluator<'_> {
}
"syscall" => {
let Some((id, rest)) = args.split_first() else {
- return Err(MirEvalError::TypeError(
- "syscall arg1 is not provided",
- ));
+ return Err(MirEvalError::TypeError("syscall arg1 is not provided"));
};
let id = from_bytes!(i64, id.get(self)?);
self.exec_syscall(id, rest, destination, locals, span)
@@ -473,6 +517,38 @@ impl Evaluator<'_> {
self.write_memory_using_ref(destination.addr, destination.size)?.fill(0);
Ok(())
}
+ "getenv" => {
+ let [name] = args else {
+ return Err(MirEvalError::TypeError("libc::write args are not provided"));
+ };
+ let mut name_buf = vec![];
+ let name = {
+ let mut index = Address::from_bytes(name.get(self)?)?;
+ loop {
+ let byte = self.read_memory(index, 1)?[0];
+ index = index.offset(1);
+ if byte == 0 {
+ break;
+ }
+ name_buf.push(byte);
+ }
+ String::from_utf8_lossy(&name_buf)
+ };
+ let value = self.db.crate_graph()[self.crate_id].env.get(&name);
+ match value {
+ None => {
+ // Write null as fail
+ self.write_memory_using_ref(destination.addr, destination.size)?.fill(0);
+ }
+ Some(mut value) => {
+ value.push('\0');
+ let addr = self.heap_allocate(value.len(), 1)?;
+ self.write_memory(addr, value.as_bytes())?;
+ self.write_memory(destination.addr, &addr.to_bytes())?;
+ }
+ }
+ Ok(())
+ }
_ => not_supported!("unknown external function {as_str}"),
}
}
@@ -650,7 +726,8 @@ impl Evaluator<'_> {
}
match name {
"size_of" => {
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
};
@@ -658,14 +735,17 @@ impl Evaluator<'_> {
destination.write_from_bytes(self, &size.to_le_bytes()[0..destination.size])
}
"min_align_of" | "pref_align_of" => {
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner)) else {
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ else {
return Err(MirEvalError::TypeError("align_of generic arg is not provided"));
};
let align = self.layout(ty)?.align.abi.bytes();
destination.write_from_bytes(self, &align.to_le_bytes()[0..destination.size])
}
"size_of_val" => {
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
return Err(MirEvalError::TypeError("size_of_val generic arg is not provided"));
};
@@ -681,8 +761,12 @@ impl Evaluator<'_> {
}
}
"min_align_of_val" => {
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner)) else {
- return Err(MirEvalError::TypeError("min_align_of_val generic arg is not provided"));
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ else {
+ return Err(MirEvalError::TypeError(
+ "min_align_of_val generic arg is not provided",
+ ));
};
let [arg] = args else {
return Err(MirEvalError::TypeError("min_align_of_val args are not provided"));
@@ -696,7 +780,8 @@ impl Evaluator<'_> {
}
}
"type_name" => {
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
return Err(MirEvalError::TypeError("type_name generic arg is not provided"));
};
@@ -719,7 +804,8 @@ impl Evaluator<'_> {
.write_from_bytes(self, &len.to_le_bytes())
}
"needs_drop" => {
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
return Err(MirEvalError::TypeError("size_of generic arg is not provided"));
};
@@ -771,9 +857,12 @@ impl Evaluator<'_> {
let lhs = i128::from_le_bytes(pad16(lhs.get(self)?, false));
let rhs = i128::from_le_bytes(pad16(rhs.get(self)?, false));
let ans = lhs.wrapping_sub(rhs);
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
- return Err(MirEvalError::TypeError("ptr_offset_from generic arg is not provided"));
+ return Err(MirEvalError::TypeError(
+ "ptr_offset_from generic arg is not provided",
+ ));
};
let size = self.size_of_sized(ty, locals, "ptr_offset_from arg")? as i128;
let ans = ans / size;
@@ -880,7 +969,8 @@ impl Evaluator<'_> {
"copy_nonoverlapping args are not provided",
));
};
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
return Err(MirEvalError::TypeError(
"copy_nonoverlapping generic arg is not provided",
@@ -899,9 +989,45 @@ impl Evaluator<'_> {
let [ptr, offset] = args else {
return Err(MirEvalError::TypeError("offset args are not provided"));
};
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
- else {
- return Err(MirEvalError::TypeError("offset generic arg is not provided"));
+ let ty = if name == "offset" {
+ let Some(ty0) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ else {
+ return Err(MirEvalError::TypeError("offset generic arg is not provided"));
+ };
+ let Some(ty1) =
+ generic_args.as_slice(Interner).get(1).and_then(|it| it.ty(Interner))
+ else {
+ return Err(MirEvalError::TypeError("offset generic arg is not provided"));
+ };
+ if !matches!(
+ ty1.as_builtin(),
+ Some(
+ BuiltinType::Int(BuiltinInt::Isize)
+ | BuiltinType::Uint(BuiltinUint::Usize)
+ )
+ ) {
+ return Err(MirEvalError::TypeError(
+ "offset generic arg is not usize or isize",
+ ));
+ }
+ match ty0.as_raw_ptr() {
+ Some((ty, _)) => ty,
+ None => {
+ return Err(MirEvalError::TypeError(
+ "offset generic arg is not a raw pointer",
+ ));
+ }
+ }
+ } else {
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ else {
+ return Err(MirEvalError::TypeError(
+ "arith_offset generic arg is not provided",
+ ));
+ };
+ ty
};
let ptr = u128::from_le_bytes(pad16(ptr.get(self)?, false));
let offset = u128::from_le_bytes(pad16(offset.get(self)?, false));
@@ -1019,7 +1145,8 @@ impl Evaluator<'_> {
let [arg] = args else {
return Err(MirEvalError::TypeError("discriminant_value arg is not provided"));
};
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
return Err(MirEvalError::TypeError(
"discriminant_value generic arg is not provided",
@@ -1073,17 +1200,32 @@ impl Evaluator<'_> {
let addr = Address::from_bytes(arg.interval.get(self)?)?;
destination.write_from_interval(self, Interval { addr, size: destination.size })
}
+ "write_via_move" => {
+ let [ptr, val] = args else {
+ return Err(MirEvalError::TypeError("write_via_move args are not provided"));
+ };
+ let dst = Address::from_bytes(ptr.get(self)?)?;
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ else {
+ return Err(MirEvalError::TypeError(
+ "write_via_copy generic arg is not provided",
+ ));
+ };
+ let size = self.size_of_sized(ty, locals, "write_via_move ptr type")?;
+ Interval { addr: dst, size }.write_from_interval(self, val.interval)?;
+ Ok(())
+ }
"write_bytes" => {
let [dst, val, count] = args else {
return Err(MirEvalError::TypeError("write_bytes args are not provided"));
};
let count = from_bytes!(usize, count.get(self)?);
let val = from_bytes!(u8, val.get(self)?);
- let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ let Some(ty) =
+ generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
else {
- return Err(MirEvalError::TypeError(
- "write_bytes generic arg is not provided",
- ));
+ return Err(MirEvalError::TypeError("write_bytes generic arg is not provided"));
};
let dst = Address::from_bytes(dst.get(self)?)?;
let size = self.size_of_sized(ty, locals, "copy_nonoverlapping ptr type")?;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
index ec7463104..519006624 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
@@ -45,7 +45,9 @@ impl Evaluator<'_> {
};
match try_const_usize(self.db, len) {
Some(len) => {
- let Some(ty) = subst.as_slice(Interner).get(0).and_then(|it| it.ty(Interner)) else {
+ let Some(ty) =
+ subst.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+ else {
return Err(MirEvalError::TypeError("simd type with no ty param"));
};
Ok((len as usize, ty.clone()))
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
index 46165cf3d..ff30dc6da 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
@@ -730,6 +730,48 @@ fn main() {
}
#[test]
+fn posix_getenv() {
+ check_pass(
+ r#"
+//- /main.rs env:foo=bar
+
+type c_char = u8;
+
+extern "C" {
+ pub fn getenv(s: *const c_char) -> *mut c_char;
+}
+
+fn should_not_reach() {
+ _ // FIXME: replace this function with panic when that works
+}
+
+fn main() {
+ let result = getenv(b"foo\0" as *const _);
+ if *result != b'b' {
+ should_not_reach();
+ }
+ let result = (result as usize + 1) as *const c_char;
+ if *result != b'a' {
+ should_not_reach();
+ }
+ let result = (result as usize + 1) as *const c_char;
+ if *result != b'r' {
+ should_not_reach();
+ }
+ let result = (result as usize + 1) as *const c_char;
+ if *result != 0 {
+ should_not_reach();
+ }
+ let result = getenv(b"not found\0" as *const _);
+ if result as usize != 0 {
+ should_not_reach();
+ }
+}
+"#,
+ );
+}
+
+#[test]
fn posix_tls() {
check_pass(
r#"
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 718df8331..dd2dba717 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -15,7 +15,7 @@ use hir_def::{
path::Path,
resolver::{resolver_for_expr, HasResolver, ResolveValueResult, ValueNs},
AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId,
- TraitId, TypeOrConstParamId,
+ Lookup, TraitId, TypeOrConstParamId,
};
use hir_expand::name::Name;
use la_arena::ArenaMap;
@@ -71,7 +71,7 @@ struct MirLowerCtx<'a> {
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MirLowerError {
- ConstEvalError(String, Box<ConstEvalError>),
+ ConstEvalError(Box<str>, Box<ConstEvalError>),
LayoutError(LayoutError),
IncompleteExpr,
IncompletePattern,
@@ -84,7 +84,7 @@ pub enum MirLowerError {
UnsizedTemporary(Ty),
MissingFunctionDefinition(DefWithBodyId, ExprId),
TypeMismatch(TypeMismatch),
- /// This should be never happen. Type mismatch should catch everything.
+ /// This should never happen. Type mismatch should catch everything.
TypeError(&'static str),
NotSupported(String),
ContinueWithoutLoop,
@@ -244,6 +244,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
let locals = Arena::new();
let binding_locals: ArenaMap<BindingId, LocalId> = ArenaMap::new();
let mir = MirBody {
+ projection_store: ProjectionStore::default(),
basic_blocks,
locals,
start_block,
@@ -370,9 +371,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
mut current: BasicBlockId,
) -> Result<Option<BasicBlockId>> {
match &self.body.exprs[expr_id] {
+ Expr::OffsetOf(_) => {
+ not_supported!("builtin#offset_of")
+ }
+ Expr::InlineAsm(_) => {
+ not_supported!("builtin#asm")
+ }
Expr::Missing => {
if let DefWithBodyId::FunctionId(f) = self.owner {
- let assoc = self.db.lookup_intern_function(f);
+ let assoc = f.lookup(self.db.upcast());
if let ItemContainerId::TraitId(t) = assoc.container {
let name = &self.db.function_data(f).name;
return Err(MirLowerError::TraitFunctionDefinition(t, name.clone()));
@@ -803,36 +810,34 @@ impl<'ctx> MirLowerCtx<'ctx> {
current = c;
operands[u32::from(field_id.into_raw()) as usize] = Some(op);
}
- self.push_assignment(
- current,
- place,
- Rvalue::Aggregate(
- AggregateKind::Adt(variant_id, subst),
- match spread_place {
- Some(sp) => operands
- .into_iter()
- .enumerate()
- .map(|(i, it)| match it {
- Some(it) => it,
- None => {
- let p =
- sp.project(ProjectionElem::Field(FieldId {
- parent: variant_id,
- local_id: LocalFieldId::from_raw(
- RawIdx::from(i as u32),
- ),
- }));
- Operand::Copy(p)
- }
- })
- .collect(),
- None => operands.into_iter().collect::<Option<_>>().ok_or(
- MirLowerError::TypeError("missing field in record literal"),
- )?,
- },
- ),
- expr_id.into(),
+ let rvalue = Rvalue::Aggregate(
+ AggregateKind::Adt(variant_id, subst),
+ match spread_place {
+ Some(sp) => operands
+ .into_iter()
+ .enumerate()
+ .map(|(i, it)| match it {
+ Some(it) => it,
+ None => {
+ let p = sp.project(
+ ProjectionElem::Field(FieldId {
+ parent: variant_id,
+ local_id: LocalFieldId::from_raw(RawIdx::from(
+ i as u32,
+ )),
+ }),
+ &mut self.result.projection_store,
+ );
+ Operand::Copy(p)
+ }
+ })
+ .collect(),
+ None => operands.into_iter().collect::<Option<_>>().ok_or(
+ MirLowerError::TypeError("missing field in record literal"),
+ )?,
+ },
);
+ self.push_assignment(current, place, rvalue, expr_id.into());
Ok(Some(current))
}
VariantId::UnionId(union_id) => {
@@ -841,10 +846,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
};
let local_id =
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
- let place = place.project(PlaceElem::Field(FieldId {
- parent: union_id.into(),
- local_id,
- }));
+ let place = place.project(
+ PlaceElem::Field(FieldId { parent: union_id.into(), local_id }),
+ &mut self.result.projection_store,
+ );
self.lower_expr_to_place(*expr, place, current)
}
}
@@ -898,7 +903,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
else {
return Ok(None);
};
- let p = place.project(ProjectionElem::Deref);
+ let p = place.project(ProjectionElem::Deref, &mut self.result.projection_store);
self.push_assignment(current, p, operand.into(), expr_id.into());
Ok(Some(current))
}
@@ -1120,27 +1125,31 @@ impl<'ctx> MirLowerCtx<'ctx> {
for capture in captures.iter() {
let p = Place {
local: self.binding_local(capture.place.local)?,
- projection: capture
- .place
- .projections
- .clone()
- .into_iter()
- .map(|it| match it {
- ProjectionElem::Deref => ProjectionElem::Deref,
- ProjectionElem::Field(it) => ProjectionElem::Field(it),
- ProjectionElem::TupleOrClosureField(it) => {
- ProjectionElem::TupleOrClosureField(it)
- }
- ProjectionElem::ConstantIndex { offset, from_end } => {
- ProjectionElem::ConstantIndex { offset, from_end }
- }
- ProjectionElem::Subslice { from, to } => {
- ProjectionElem::Subslice { from, to }
- }
- ProjectionElem::OpaqueCast(it) => ProjectionElem::OpaqueCast(it),
- ProjectionElem::Index(it) => match it {},
- })
- .collect(),
+ projection: self.result.projection_store.intern(
+ capture
+ .place
+ .projections
+ .clone()
+ .into_iter()
+ .map(|it| match it {
+ ProjectionElem::Deref => ProjectionElem::Deref,
+ ProjectionElem::Field(it) => ProjectionElem::Field(it),
+ ProjectionElem::TupleOrClosureField(it) => {
+ ProjectionElem::TupleOrClosureField(it)
+ }
+ ProjectionElem::ConstantIndex { offset, from_end } => {
+ ProjectionElem::ConstantIndex { offset, from_end }
+ }
+ ProjectionElem::Subslice { from, to } => {
+ ProjectionElem::Subslice { from, to }
+ }
+ ProjectionElem::OpaqueCast(it) => {
+ ProjectionElem::OpaqueCast(it)
+ }
+ ProjectionElem::Index(it) => match it {},
+ })
+ .collect(),
+ ),
};
match &capture.kind {
CaptureKind::ByRef(bk) => {
@@ -1201,7 +1210,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
let Some(values) = elements
.iter()
.map(|it| {
- let Some((o, c)) = self.lower_expr_to_some_operand(*it, current)? else {
+ let Some((o, c)) = self.lower_expr_to_some_operand(*it, current)?
+ else {
return Ok(None);
};
current = c;
@@ -1244,6 +1254,40 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
}
+ fn lower_destructing_assignment(
+ &mut self,
+ mut current: BasicBlockId,
+ lhs: ExprId,
+ rhs: Place,
+ span: MirSpan,
+ ) -> Result<Option<BasicBlockId>> {
+ match &self.body.exprs[lhs] {
+ Expr::Tuple { exprs, is_assignee_expr: _ } => {
+ for (i, expr) in exprs.iter().enumerate() {
+ let rhs = rhs.project(
+ ProjectionElem::TupleOrClosureField(i),
+ &mut self.result.projection_store,
+ );
+ let Some(c) = self.lower_destructing_assignment(current, *expr, rhs, span)?
+ else {
+ return Ok(None);
+ };
+ current = c;
+ }
+ Ok(Some(current))
+ }
+ Expr::Underscore => Ok(Some(current)),
+ _ => {
+ let Some((lhs_place, current)) = self.lower_expr_as_place(current, lhs, false)?
+ else {
+ return Ok(None);
+ };
+ self.push_assignment(current, lhs_place, Operand::Copy(rhs).into(), span);
+ Ok(Some(current))
+ }
+ }
+ }
+
fn lower_assignment(
&mut self,
current: BasicBlockId,
@@ -1251,17 +1295,22 @@ impl<'ctx> MirLowerCtx<'ctx> {
rhs: ExprId,
span: MirSpan,
) -> Result<Option<BasicBlockId>> {
- let Some((rhs_op, current)) =
- self.lower_expr_to_some_operand(rhs, current)?
- else {
+ let Some((rhs_op, current)) = self.lower_expr_to_some_operand(rhs, current)? else {
return Ok(None);
};
if matches!(&self.body.exprs[lhs], Expr::Underscore) {
return Ok(Some(current));
}
- let Some((lhs_place, current)) =
- self.lower_expr_as_place(current, lhs, false)?
- else {
+ if matches!(
+ &self.body.exprs[lhs],
+ Expr::Tuple { .. } | Expr::RecordLit { .. } | Expr::Call { .. }
+ ) {
+ let temp = self.temp(self.expr_ty_after_adjustments(rhs), current, rhs.into())?;
+ let temp = Place::from(temp);
+ self.push_assignment(current, temp.clone(), rhs_op.into(), span);
+ return self.lower_destructing_assignment(current, lhs, temp, span);
+ }
+ let Some((lhs_place, current)) = self.lower_expr_as_place(current, lhs, false)? else {
return Ok(None);
};
self.push_assignment(current, lhs_place, rhs_op.into(), span);
@@ -1276,17 +1325,21 @@ impl<'ctx> MirLowerCtx<'ctx> {
placeholder_subst
}
- fn push_field_projection(&self, place: &mut Place, expr_id: ExprId) -> Result<()> {
+ fn push_field_projection(&mut self, place: &mut Place, expr_id: ExprId) -> Result<()> {
if let Expr::Field { expr, name } = &self.body[expr_id] {
if let TyKind::Tuple(..) = self.expr_ty_after_adjustments(*expr).kind(Interner) {
let index = name
.as_tuple_index()
.ok_or(MirLowerError::TypeError("named field on tuple"))?;
- *place = place.project(ProjectionElem::TupleOrClosureField(index))
+ *place = place.project(
+ ProjectionElem::TupleOrClosureField(index),
+ &mut self.result.projection_store,
+ )
} else {
let field =
self.infer.field_resolution(expr_id).ok_or(MirLowerError::UnresolvedField)?;
- *place = place.project(ProjectionElem::Field(field));
+ *place =
+ place.project(ProjectionElem::Field(field), &mut self.result.projection_store);
}
} else {
not_supported!("")
@@ -1308,14 +1361,14 @@ impl<'ctx> MirLowerCtx<'ctx> {
.resolve_path_in_value_ns(self.db.upcast(), c)
.ok_or_else(unresolved_name)?;
match pr {
- ResolveValueResult::ValueNs(v) => {
+ ResolveValueResult::ValueNs(v, _) => {
if let ValueNs::ConstId(c) = v {
self.lower_const_to_operand(Substitution::empty(Interner), c.into(), ty)
} else {
not_supported!("bad path in range pattern");
}
}
- ResolveValueResult::Partial(_, _) => {
+ ResolveValueResult::Partial(_, _, _) => {
not_supported!("associated constants in range pattern")
}
}
@@ -1403,7 +1456,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
let name = const_id.name(self.db.upcast());
self.db
.const_eval(const_id.into(), subst, None)
- .map_err(|e| MirLowerError::ConstEvalError(name, Box::new(e)))?
+ .map_err(|e| MirLowerError::ConstEvalError(name.into(), Box::new(e)))?
};
Ok(Operand::Constant(c))
}
@@ -1800,7 +1853,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
data.name.display(self.db.upcast()),
data.variants[variant.local_id].name.display(self.db.upcast())
);
- Err(MirLowerError::ConstEvalError(name, Box::new(e)))
+ Err(MirLowerError::ConstEvalError(name.into(), Box::new(e)))
}
}
}
@@ -1948,13 +2001,14 @@ pub fn mir_body_for_closure_query(
FnTrait::FnOnce => vec![],
FnTrait::FnMut | FnTrait::Fn => vec![ProjectionElem::Deref],
};
- ctx.result.walk_places(|p| {
+ ctx.result.walk_places(|p, store| {
if let Some(it) = upvar_map.get(&p.local) {
let r = it.iter().find(|it| {
- if p.projection.len() < it.0.place.projections.len() {
+ if p.projection.lookup(&store).len() < it.0.place.projections.len() {
return false;
}
- for (it, y) in p.projection.iter().zip(it.0.place.projections.iter()) {
+ for (it, y) in p.projection.lookup(&store).iter().zip(it.0.place.projections.iter())
+ {
match (it, y) {
(ProjectionElem::Deref, ProjectionElem::Deref) => (),
(ProjectionElem::Field(it), ProjectionElem::Field(y)) if it == y => (),
@@ -1972,13 +2026,18 @@ pub fn mir_body_for_closure_query(
p.local = closure_local;
let mut next_projs = closure_projection.clone();
next_projs.push(PlaceElem::TupleOrClosureField(it.1));
- let prev_projs = mem::take(&mut p.projection);
+ let prev_projs = p.projection;
if it.0.kind != CaptureKind::ByValue {
next_projs.push(ProjectionElem::Deref);
}
- next_projs
- .extend(prev_projs.iter().cloned().skip(it.0.place.projections.len()));
- p.projection = next_projs.into();
+ next_projs.extend(
+ prev_projs
+ .lookup(&store)
+ .iter()
+ .cloned()
+ .skip(it.0.place.projections.len()),
+ );
+ p.projection = store.intern(next_projs.into());
}
None => err = Some(p.clone()),
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
index 213f151ab..8c078eb4a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs
@@ -70,7 +70,7 @@ impl MirLowerCtx<'_> {
else {
return Ok(None);
};
- it.0 = it.0.project(ProjectionElem::Deref);
+ it.0 = it.0.project(ProjectionElem::Deref, &mut self.result.projection_store);
Ok(Some(it))
}
Adjust::Deref(Some(od)) => {
@@ -152,7 +152,10 @@ impl MirLowerCtx<'_> {
Operand::Static(s).into(),
expr_id.into(),
);
- Ok(Some((temp.project(ProjectionElem::Deref), current)))
+ Ok(Some((
+ temp.project(ProjectionElem::Deref, &mut self.result.projection_store),
+ current,
+ )))
}
_ => try_rvalue(self),
}
@@ -203,7 +206,7 @@ impl MirLowerCtx<'_> {
else {
return Ok(None);
};
- r = r.project(ProjectionElem::Deref);
+ r = r.project(ProjectionElem::Deref, &mut self.result.projection_store);
Ok(Some((r, current)))
}
_ => try_rvalue(self),
@@ -267,7 +270,8 @@ impl MirLowerCtx<'_> {
else {
return Ok(None);
};
- p_base = p_base.project(ProjectionElem::Index(l_index));
+ p_base = p_base
+ .project(ProjectionElem::Index(l_index), &mut self.result.projection_store);
Ok(Some((p_base, current)))
}
_ => try_rvalue(self),
@@ -308,7 +312,7 @@ impl MirLowerCtx<'_> {
else {
return Ok(None);
};
- result = result.project(ProjectionElem::Deref);
+ result = result.project(ProjectionElem::Deref, &mut self.result.projection_store);
Ok(Some((result, current)))
}
@@ -363,7 +367,7 @@ impl MirLowerCtx<'_> {
else {
return Ok(None);
};
- result = result.project(ProjectionElem::Deref);
+ result = result.project(ProjectionElem::Deref, &mut self.result.projection_store);
Ok(Some((result, current)))
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
index 3354cbd76..270f75ad9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -81,13 +81,16 @@ impl MirLowerCtx<'_> {
mode: MatchingMode,
) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
let cnt = self.infer.pat_adjustments.get(&pattern).map(|x| x.len()).unwrap_or_default();
- cond_place.projection = cond_place
- .projection
- .iter()
- .cloned()
- .chain((0..cnt).map(|_| ProjectionElem::Deref))
- .collect::<Vec<_>>()
- .into();
+ cond_place.projection = self.result.projection_store.intern(
+ cond_place
+ .projection
+ .lookup(&self.result.projection_store)
+ .iter()
+ .cloned()
+ .chain((0..cnt).map(|_| ProjectionElem::Deref))
+ .collect::<Vec<_>>()
+ .into(),
+ );
Ok(match &self.body.pats[pattern] {
Pat::Missing => return Err(MirLowerError::IncompletePattern),
Pat::Wild => (current, current_else),
@@ -262,20 +265,23 @@ impl MirLowerCtx<'_> {
}
}
for (i, &pat) in prefix.iter().enumerate() {
- let next_place = (&mut cond_place).project(ProjectionElem::ConstantIndex {
- offset: i as u64,
- from_end: false,
- });
+ let next_place = (&mut cond_place).project(
+ ProjectionElem::ConstantIndex { offset: i as u64, from_end: false },
+ &mut self.result.projection_store,
+ );
(current, current_else) =
self.pattern_match_inner(current, current_else, next_place, pat, mode)?;
}
if let Some(slice) = slice {
if mode == MatchingMode::Bind {
if let Pat::Bind { id, subpat: _ } = self.body[*slice] {
- let next_place = (&mut cond_place).project(ProjectionElem::Subslice {
- from: prefix.len() as u64,
- to: suffix.len() as u64,
- });
+ let next_place = (&mut cond_place).project(
+ ProjectionElem::Subslice {
+ from: prefix.len() as u64,
+ to: suffix.len() as u64,
+ },
+ &mut self.result.projection_store,
+ );
(current, current_else) = self.pattern_match_binding(
id,
next_place,
@@ -287,10 +293,10 @@ impl MirLowerCtx<'_> {
}
}
for (i, &pat) in suffix.iter().enumerate() {
- let next_place = (&mut cond_place).project(ProjectionElem::ConstantIndex {
- offset: i as u64,
- from_end: true,
- });
+ let next_place = (&mut cond_place).project(
+ ProjectionElem::ConstantIndex { offset: i as u64, from_end: true },
+ &mut self.result.projection_store,
+ );
(current, current_else) =
self.pattern_match_inner(current, current_else, next_place, pat, mode)?;
}
@@ -323,7 +329,7 @@ impl MirLowerCtx<'_> {
break 'b (c, x.1);
}
}
- if let ResolveValueResult::ValueNs(v) = pr {
+ if let ResolveValueResult::ValueNs(v, _) = pr {
if let ValueNs::ConstId(c) = v {
break 'b (c, Substitution::empty(Interner));
}
@@ -412,13 +418,11 @@ impl MirLowerCtx<'_> {
mode,
)?
}
- Pat::Ref { pat, mutability: _ } => self.pattern_match_inner(
- current,
- current_else,
- cond_place.project(ProjectionElem::Deref),
- *pat,
- mode,
- )?,
+ Pat::Ref { pat, mutability: _ } => {
+ let cond_place =
+ cond_place.project(ProjectionElem::Deref, &mut self.result.projection_store);
+ self.pattern_match_inner(current, current_else, cond_place, *pat, mode)?
+ }
Pat::Box { .. } => not_supported!("box pattern"),
Pat::ConstBlock(_) => not_supported!("const block pattern"),
})
@@ -594,7 +598,7 @@ impl MirLowerCtx<'_> {
mode: MatchingMode,
) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
for (proj, arg) in args {
- let cond_place = cond_place.project(proj);
+ let cond_place = cond_place.project(proj, &mut self.result.projection_store);
(current, current_else) =
self.pattern_match_inner(current, current_else, cond_place, arg, mode)?;
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
index c565228d9..df16d0d82 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/monomorphization.rs
@@ -265,7 +265,7 @@ impl Filler<'_> {
self.fill_operand(discr)?;
}
TerminatorKind::Goto { .. }
- | TerminatorKind::Resume
+ | TerminatorKind::UnwindResume
| TerminatorKind::Abort
| TerminatorKind::Return
| TerminatorKind::Unreachable
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
index 781ffaeca..0108859ff 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
@@ -329,7 +329,7 @@ impl<'a> MirPrettyCtx<'a> {
}
}
}
- f(self, p.local, &p.projection);
+ f(self, p.local, &p.projection.lookup(&self.body.projection_store));
}
fn operand(&mut self, r: &Operand) {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
index 2ad7946c8..8140c4107 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs
@@ -3,55 +3,6 @@ use expect_test::expect;
use super::{check, check_infer, check_no_mismatches, check_types};
#[test]
-fn infer_box() {
- check_types(
- r#"
-//- /main.rs crate:main deps:std
-fn test() {
- let x = box 1;
- let t = (x, box x, box &1, box [1]);
- t;
-} //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; 1]>)
-
-//- /std.rs crate:std
-#[prelude_import] use prelude::*;
-mod prelude {}
-
-mod boxed {
- #[lang = "owned_box"]
- pub struct Box<T: ?Sized> {
- inner: *mut T,
- }
-}
-"#,
- );
-}
-
-#[test]
-fn infer_box_with_allocator() {
- check_types(
- r#"
-//- /main.rs crate:main deps:std
-fn test() {
- let x = box 1;
- let t = (x, box x, box &1, box [1]);
- t;
-} //^ (Box<i32, {unknown}>, Box<Box<i32, {unknown}>, {unknown}>, Box<&i32, {unknown}>, Box<[i32; 1], {unknown}>)
-
-//- /std.rs crate:std
-#[prelude_import] use prelude::*;
-mod boxed {
- #[lang = "owned_box"]
- pub struct Box<T: ?Sized, A: Allocator> {
- inner: *mut T,
- allocator: A,
- }
-}
-"#,
- );
-}
-
-#[test]
fn infer_adt_self() {
check_types(
r#"
@@ -2763,8 +2714,8 @@ impl<T> [T] {
}
fn test() {
- let vec = <[_]>::into_vec(box [1i32]);
- let v: Vec<Box<dyn B>> = <[_]> :: into_vec(box [box Astruct]);
+ let vec = <[_]>::into_vec(#[rustc_box] Box::new([1i32]));
+ let v: Vec<Box<dyn B>> = <[_]> :: into_vec(#[rustc_box] Box::new([#[rustc_box] Box::new(Astruct)]));
}
trait B{}
@@ -2774,20 +2725,20 @@ impl B for Astruct {}
expect![[r#"
604..608 'self': Box<[T], A>
637..669 '{ ... }': Vec<T, A>
- 683..796 '{ ...t]); }': ()
+ 683..853 '{ ...])); }': ()
693..696 'vec': Vec<i32, Global>
699..714 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
- 699..726 '<[_]>:...1i32])': Vec<i32, Global>
- 715..725 'box [1i32]': Box<[i32; 1], Global>
- 719..725 '[1i32]': [i32; 1]
- 720..724 '1i32': i32
- 736..737 'v': Vec<Box<dyn B, Global>, Global>
- 757..774 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
- 757..793 '<[_]> ...ruct])': Vec<Box<dyn B, Global>, Global>
- 775..792 'box [b...truct]': Box<[Box<dyn B, Global>; 1], Global>
- 779..792 '[box Astruct]': [Box<dyn B, Global>; 1]
- 780..791 'box Astruct': Box<Astruct, Global>
- 784..791 'Astruct': Astruct
+ 699..745 '<[_]>:...i32]))': Vec<i32, Global>
+ 715..744 '#[rust...1i32])': Box<[i32; 1], Global>
+ 737..743 '[1i32]': [i32; 1]
+ 738..742 '1i32': i32
+ 755..756 'v': Vec<Box<dyn B, Global>, Global>
+ 776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
+ 776..850 '<[_]> ...ct)]))': Vec<Box<dyn B, Global>, Global>
+ 794..849 '#[rust...uct)])': Box<[Box<dyn B, Global>; 1], Global>
+ 816..848 '[#[rus...ruct)]': [Box<dyn B, Global>; 1]
+ 817..847 '#[rust...truct)': Box<Astruct, Global>
+ 839..846 'Astruct': Astruct
"#]],
)
}
@@ -3649,3 +3600,30 @@ fn main() {
"#,
);
}
+
+#[test]
+fn offset_of() {
+ check_types(
+ r#"
+fn main() {
+ builtin#offset_of((,), 0);
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^ usize
+}
+"#,
+ );
+}
+
+#[test]
+fn builtin_format_args() {
+ check(
+ r#"
+//- minicore: fmt
+fn main() {
+ let are = "are";
+ let count = 10;
+ builtin#format_args("hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!");
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type: Arguments<'_>
+}
+"#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
index 542df8b34..d36b885ec 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
@@ -162,16 +162,16 @@ unsafe impl Allocator for Global {}
#[lang = "owned_box"]
#[fundamental]
-pub struct Box<T: ?Sized, A: Allocator = Global>;
+pub struct Box<T: ?Sized, A: Allocator = Global>(T);
impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
fn send() -> Box<dyn Future<Output = ()> + Send + 'static>{
- box async move {}
+ Box(async move {})
}
fn not_send() -> Box<dyn Future<Output = ()> + 'static> {
- box async move {}
+ Box(async move {})
}
"#,
);
@@ -3057,7 +3057,7 @@ impl<T: ?Sized> core::ops::Deref for Box<T> {
fn foo() {
let s = None;
- let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
+ let f: Box<dyn FnOnce(&Option<i32>)> = Box { inner: &mut (|ps| {}) };
f(&s);
}"#,
expect![[r#"
@@ -3068,19 +3068,19 @@ fn foo() {
186..197 '*self.inner': T
187..191 'self': &Box<T>
187..197 'self.inner': *mut T
- 218..308 '{ ...&s); }': ()
+ 218..324 '{ ...&s); }': ()
228..229 's': Option<i32>
232..236 'None': Option<i32>
246..247 'f': Box<dyn FnOnce(&Option<i32>)>
- 281..294 'box (|ps| {})': Box<impl Fn(&Option<i32>)>
- 286..293 '|ps| {}': impl Fn(&Option<i32>)
- 287..289 'ps': &Option<i32>
- 291..293 '{}': ()
- 300..301 'f': Box<dyn FnOnce(&Option<i32>)>
- 300..305 'f(&s)': ()
- 302..304 '&s': &Option<i32>
- 303..304 's': Option<i32>
- 281..294: expected Box<dyn FnOnce(&Option<i32>)>, got Box<impl Fn(&Option<i32>)>
+ 281..310 'Box { ... {}) }': Box<dyn FnOnce(&Option<i32>)>
+ 294..308 '&mut (|ps| {})': &mut impl Fn(&Option<i32>)
+ 300..307 '|ps| {}': impl Fn(&Option<i32>)
+ 301..303 'ps': &Option<i32>
+ 305..307 '{}': ()
+ 316..317 'f': Box<dyn FnOnce(&Option<i32>)>
+ 316..321 'f(&s)': ()
+ 318..320 '&s': &Option<i32>
+ 319..320 's': Option<i32>
"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs
index 0f2fb2c81..796490abd 100644
--- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs
@@ -1,38 +1,27 @@
//! Attributes & documentation for hir types.
use hir_def::{
- attr::{AttrsWithOwner, Documentation},
+ attr::AttrsWithOwner,
item_scope::ItemInNs,
- path::ModPath,
- resolver::HasResolver,
- AttrDefId, GenericParamId, ModuleDefId,
+ path::{ModPath, Path},
+ per_ns::Namespace,
+ resolver::{HasResolver, Resolver, TypeNs},
+ AssocItemId, AttrDefId, ModuleDefId,
};
-use hir_expand::hygiene::Hygiene;
+use hir_expand::{hygiene::Hygiene, name::Name};
use hir_ty::db::HirDatabase;
use syntax::{ast, AstNode};
use crate::{
- Adt, AssocItem, Const, ConstParam, Enum, ExternCrateDecl, Field, Function, GenericParam, Impl,
- LifetimeParam, Macro, Module, ModuleDef, Static, Struct, Trait, TraitAlias, TypeAlias,
- TypeParam, Union, Variant,
+ Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
+ Field, Function, GenericParam, Impl, LifetimeParam, Macro, Module, ModuleDef, Static, Struct,
+ Trait, TraitAlias, TypeAlias, TypeParam, Union, Variant, VariantDef,
};
pub trait HasAttrs {
fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner;
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>;
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>,
- ) -> Option<ModuleDef>;
-}
-
-#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
-pub enum Namespace {
- Types,
- Values,
- Macros,
+ #[doc(hidden)]
+ fn attr_id(self) -> AttrDefId;
}
macro_rules! impl_has_attrs {
@@ -42,13 +31,8 @@ macro_rules! impl_has_attrs {
let def = AttrDefId::$def_id(self.into());
db.attrs_with_owner(def)
}
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- let def = AttrDefId::$def_id(self.into());
- db.attrs(def).docs()
- }
- fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
- let def = AttrDefId::$def_id(self.into());
- resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
+ fn attr_id(self) -> AttrDefId {
+ AttrDefId::$def_id(self.into())
}
}
)*};
@@ -68,6 +52,7 @@ impl_has_attrs![
(Module, ModuleId),
(GenericParam, GenericParamId),
(Impl, ImplId),
+ (ExternCrateDecl, ExternCrateId),
];
macro_rules! impl_has_attrs_enum {
@@ -76,11 +61,8 @@ macro_rules! impl_has_attrs_enum {
fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
$enum::$variant(self).attrs(db)
}
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- $enum::$variant(self).docs(db)
- }
- fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
- $enum::$variant(self).resolve_doc_path(db, link, ns)
+ fn attr_id(self) -> AttrDefId {
+ $enum::$variant(self).attr_id()
}
}
)*};
@@ -97,70 +79,35 @@ impl HasAttrs for AssocItem {
AssocItem::TypeAlias(it) => it.attrs(db),
}
}
-
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- match self {
- AssocItem::Function(it) => it.docs(db),
- AssocItem::Const(it) => it.docs(db),
- AssocItem::TypeAlias(it) => it.docs(db),
- }
- }
-
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>,
- ) -> Option<ModuleDef> {
+ fn attr_id(self) -> AttrDefId {
match self {
- AssocItem::Function(it) => it.resolve_doc_path(db, link, ns),
- AssocItem::Const(it) => it.resolve_doc_path(db, link, ns),
- AssocItem::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
+ AssocItem::Function(it) => it.attr_id(),
+ AssocItem::Const(it) => it.attr_id(),
+ AssocItem::TypeAlias(it) => it.attr_id(),
}
}
}
-impl HasAttrs for ExternCrateDecl {
- fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
- let def = AttrDefId::ExternCrateId(self.into());
- db.attrs_with_owner(def)
- }
- fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
- let crate_docs = self.resolved_crate(db)?.root_module().attrs(db).docs().map(String::from);
- let def = AttrDefId::ExternCrateId(self.into());
- let decl_docs = db.attrs(def).docs().map(String::from);
- match (decl_docs, crate_docs) {
- (None, None) => None,
- (Some(decl_docs), None) => Some(decl_docs),
- (None, Some(crate_docs)) => Some(crate_docs),
- (Some(mut decl_docs), Some(crate_docs)) => {
- decl_docs.push('\n');
- decl_docs.push('\n');
- decl_docs += &crate_docs;
- Some(decl_docs)
- }
- }
- .map(Documentation::new)
- }
- fn resolve_doc_path(
- self,
- db: &dyn HirDatabase,
- link: &str,
- ns: Option<Namespace>,
- ) -> Option<ModuleDef> {
- let def = AttrDefId::ExternCrateId(self.into());
- resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
- }
+/// Resolves the item `link` points to in the scope of `def`.
+pub fn resolve_doc_path_on(
+ db: &dyn HirDatabase,
+ def: impl HasAttrs,
+ link: &str,
+ ns: Option<Namespace>,
+) -> Option<DocLinkDef> {
+ // AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
+ // AttrDefId::EnumVariantId(it) => it.parent.resolver(db.upcast()),
+
+ resolve_doc_path_on_(db, link, def.attr_id(), ns)
}
-/// Resolves the item `link` points to in the scope of `def`.
-fn resolve_doc_path(
+fn resolve_doc_path_on_(
db: &dyn HirDatabase,
- def: AttrDefId,
link: &str,
+ attr_id: AttrDefId,
ns: Option<Namespace>,
-) -> Option<ModuleDefId> {
- let resolver = match def {
+) -> Option<DocLinkDef> {
+ let resolver = match attr_id {
AttrDefId::ModuleId(it) => it.resolver(db.upcast()),
AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
AttrDefId::AdtId(it) => it.resolver(db.upcast()),
@@ -176,16 +123,110 @@ fn resolve_doc_path(
AttrDefId::UseId(it) => it.resolver(db.upcast()),
AttrDefId::MacroId(it) => it.resolver(db.upcast()),
AttrDefId::ExternCrateId(it) => it.resolver(db.upcast()),
- AttrDefId::GenericParamId(it) => match it {
- GenericParamId::TypeParamId(it) => it.parent(),
- GenericParamId::ConstParamId(it) => it.parent(),
- GenericParamId::LifetimeParamId(it) => it.parent,
+ AttrDefId::GenericParamId(_) => return None,
+ };
+
+ let mut modpath = modpath_from_str(db, link)?;
+
+ let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
+ if resolved.is_none() {
+ let last_name = modpath.pop_segment()?;
+ resolve_assoc_or_field(db, resolver, modpath, last_name, ns)
+ } else {
+ let def = match ns {
+ Some(Namespace::Types) => resolved.take_types(),
+ Some(Namespace::Values) => resolved.take_values(),
+ Some(Namespace::Macros) => resolved.take_macros().map(ModuleDefId::MacroId),
+ None => resolved.iter_items().next().map(|(it, _)| match it {
+ ItemInNs::Types(it) => it,
+ ItemInNs::Values(it) => it,
+ ItemInNs::Macros(it) => ModuleDefId::MacroId(it),
+ }),
+ };
+ Some(DocLinkDef::ModuleDef(def?.into()))
+ }
+}
+
+fn resolve_assoc_or_field(
+ db: &dyn HirDatabase,
+ resolver: Resolver,
+ path: ModPath,
+ name: Name,
+ ns: Option<Namespace>,
+) -> Option<DocLinkDef> {
+ let path = Path::from_known_path_with_no_generic(path);
+ // FIXME: This does not handle `Self` on trait definitions, which we should resolve to the
+ // trait itself.
+ let base_def = resolver.resolve_path_in_type_ns_fully(db.upcast(), &path)?;
+
+ let ty = match base_def {
+ TypeNs::SelfType(id) => Impl::from(id).self_ty(db),
+ TypeNs::GenericParam(_) => {
+ // Even if this generic parameter has some trait bounds, rustdoc doesn't
+ // resolve `name` to trait items.
+ return None;
+ }
+ TypeNs::AdtId(id) | TypeNs::AdtSelfType(id) => Adt::from(id).ty(db),
+ TypeNs::EnumVariantId(id) => {
+ // Enum variants don't have path candidates.
+ let variant = Variant::from(id);
+ return resolve_field(db, variant.into(), name, ns);
+ }
+ TypeNs::TypeAliasId(id) => {
+ let alias = TypeAlias::from(id);
+ if alias.as_assoc_item(db).is_some() {
+ // We don't normalize associated type aliases, so we have nothing to
+ // resolve `name` to.
+ return None;
+ }
+ alias.ty(db)
+ }
+ TypeNs::BuiltinType(id) => BuiltinType::from(id).ty(db),
+ TypeNs::TraitId(id) => {
+ // Doc paths in this context may only resolve to an item of this trait
+ // (i.e. no items of its supertraits), so we need to handle them here
+ // independently of others.
+ return db.trait_data(id).items.iter().find(|it| it.0 == name).map(|(_, assoc_id)| {
+ let def = match *assoc_id {
+ AssocItemId::FunctionId(it) => ModuleDef::Function(it.into()),
+ AssocItemId::ConstId(it) => ModuleDef::Const(it.into()),
+ AssocItemId::TypeAliasId(it) => ModuleDef::TypeAlias(it.into()),
+ };
+ DocLinkDef::ModuleDef(def)
+ });
+ }
+ TypeNs::TraitAliasId(_) => {
+ // XXX: Do these get resolved?
+ return None;
}
- .resolver(db.upcast()),
};
- let modpath = {
- // FIXME: this is not how we should get a mod path here
+ // FIXME: Resolve associated items here, e.g. `Option::map`. Note that associated items take
+ // precedence over fields.
+
+ let variant_def = match ty.as_adt()? {
+ Adt::Struct(it) => it.into(),
+ Adt::Union(it) => it.into(),
+ Adt::Enum(_) => return None,
+ };
+ resolve_field(db, variant_def, name, ns)
+}
+
+fn resolve_field(
+ db: &dyn HirDatabase,
+ def: VariantDef,
+ name: Name,
+ ns: Option<Namespace>,
+) -> Option<DocLinkDef> {
+ if let Some(Namespace::Types | Namespace::Macros) = ns {
+ return None;
+ }
+ def.fields(db).into_iter().find(|f| f.name(db) == name).map(DocLinkDef::Field)
+}
+
+fn modpath_from_str(db: &dyn HirDatabase, link: &str) -> Option<ModPath> {
+ // FIXME: this is not how we should get a mod path here.
+ let try_get_modpath = |link: &str| {
let ast_path = ast::SourceFile::parse(&format!("type T = {link};"))
.syntax_node()
.descendants()
@@ -193,23 +234,20 @@ fn resolve_doc_path(
if ast_path.syntax().text() != link {
return None;
}
- ModPath::from_src(db.upcast(), ast_path, &Hygiene::new_unhygienic())?
+ ModPath::from_src(db.upcast(), ast_path, &Hygiene::new_unhygienic())
};
- let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
- let resolved = if resolved.is_none() {
- resolver.resolve_module_path_in_trait_assoc_items(db.upcast(), &modpath)?
- } else {
- resolved
- };
- match ns {
- Some(Namespace::Types) => resolved.take_types(),
- Some(Namespace::Values) => resolved.take_values(),
- Some(Namespace::Macros) => resolved.take_macros().map(ModuleDefId::MacroId),
- None => resolved.iter_items().next().map(|it| match it {
- ItemInNs::Types(it) => it,
- ItemInNs::Values(it) => it,
- ItemInNs::Macros(it) => ModuleDefId::MacroId(it),
- }),
+ let full = try_get_modpath(link);
+ if full.is_some() {
+ return full;
}
+
+ // Tuple field names cannot be a part of `ModPath` usually, but rustdoc can
+ // resolve doc paths like `TupleStruct::0`.
+ // FIXME: Find a better way to handle these.
+ let (base, maybe_tuple_field) = link.rsplit_once("::")?;
+ let tuple_field = Name::new_tuple_field(maybe_tuple_field.parse().ok()?);
+ let mut modpath = try_get_modpath(base)?;
+ modpath.push_segment(tuple_field);
+ Some(modpath)
}
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index 80c3bcdca..479138b67 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -43,6 +43,7 @@ diagnostics![
MacroExpansionParseError,
MalformedDerive,
MismatchedArgCount,
+ MismatchedTupleStructPatArgCount,
MissingFields,
MissingMatchArms,
MissingUnsafe,
@@ -172,7 +173,8 @@ pub struct MalformedDerive {
#[derive(Debug)]
pub struct NoSuchField {
- pub field: InFile<AstPtr<ast::RecordExprField>>,
+ pub field: InFile<Either<AstPtr<ast::RecordExprField>, AstPtr<ast::RecordPatField>>>,
+ pub private: bool,
}
#[derive(Debug)]
@@ -183,6 +185,13 @@ pub struct PrivateAssocItem {
}
#[derive(Debug)]
+pub struct MismatchedTupleStructPatArgCount {
+ pub expr_or_pat: InFile<Either<AstPtr<ast::Expr>, AstPtr<ast::Pat>>>,
+ pub expected: usize,
+ pub found: usize,
+}
+
+#[derive(Debug)]
pub struct ExpectedFunction {
pub call: InFile<AstPtr<ast::Expr>>,
pub found: Type,
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 9dfb98e45..ac171026d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -8,7 +8,6 @@ use hir_def::{
type_ref::{TypeBound, TypeRef},
AdtId, GenericDefId,
};
-use hir_expand::name;
use hir_ty::{
display::{
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
@@ -19,8 +18,9 @@ use hir_ty::{
use crate::{
Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Enum, ExternCrateDecl, Field,
- Function, GenericParam, HasCrate, HasVisibility, LifetimeParam, Macro, Module, Static, Struct,
- Trait, TraitAlias, TyBuilder, Type, TypeAlias, TypeOrConstParam, TypeParam, Union, Variant,
+ Function, GenericParam, HasCrate, HasVisibility, LifetimeParam, Macro, Module, SelfParam,
+ Static, Struct, Trait, TraitAlias, TyBuilder, Type, TypeAlias, TypeOrConstParam, TypeParam,
+ Union, Variant,
};
impl HirDisplay for Function {
@@ -57,37 +57,21 @@ impl HirDisplay for Function {
f.write_char('(')?;
- let write_self_param = |ty: &TypeRef, f: &mut HirFormatter<'_>| match ty {
- TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
- TypeRef::Reference(inner, lifetime, mut_) if matches!(&**inner, TypeRef::Path(p) if p.is_self_type()) =>
- {
- f.write_char('&')?;
- if let Some(lifetime) = lifetime {
- write!(f, "{} ", lifetime.name.display(f.db.upcast()))?;
- }
- if let hir_def::type_ref::Mutability::Mut = mut_ {
- f.write_str("mut ")?;
- }
- f.write_str("self")
- }
- _ => {
- f.write_str("self: ")?;
- ty.hir_fmt(f)
- }
- };
-
let mut first = true;
+ let mut skip_self = 0;
+ if let Some(self_param) = self.self_param(db) {
+ self_param.hir_fmt(f)?;
+ first = false;
+ skip_self = 1;
+ }
+
// FIXME: Use resolved `param.ty` once we no longer discard lifetimes
- for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)) {
+ for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
let local = param.as_local(db).map(|it| it.name(db));
if !first {
f.write_str(", ")?;
} else {
first = false;
- if local == Some(name!(self)) {
- write_self_param(type_ref, f)?;
- continue;
- }
}
match local {
Some(name) => write!(f, "{}: ", name.display(f.db.upcast()))?,
@@ -137,6 +121,31 @@ impl HirDisplay for Function {
}
}
+impl HirDisplay for SelfParam {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
+ let data = f.db.function_data(self.func);
+ let param = data.params.first().unwrap();
+ match &**param {
+ TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
+ TypeRef::Reference(inner, lifetime, mut_) if matches!(&**inner, TypeRef::Path(p) if p.is_self_type()) =>
+ {
+ f.write_char('&')?;
+ if let Some(lifetime) = lifetime {
+ write!(f, "{} ", lifetime.name.display(f.db.upcast()))?;
+ }
+ if let hir_def::type_ref::Mutability::Mut = mut_ {
+ f.write_str("mut ")?;
+ }
+ f.write_str("self")
+ }
+ ty => {
+ f.write_str("self: ")?;
+ ty.hir_fmt(f)
+ }
+ }
+ }
+}
+
impl HirDisplay for Adt {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
match self {
@@ -357,6 +366,11 @@ fn write_generic_params(
delim(f)?;
write!(f, "const {}: ", name.display(f.db.upcast()))?;
c.ty.hir_fmt(f)?;
+
+ if let Some(default) = &c.default {
+ f.write_str(" = ")?;
+ write!(f, "{}", default.display(f.db.upcast()))?;
+ }
}
}
}
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index bf041b61f..b215ed38f 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -63,12 +63,13 @@ use hir_ty::{
all_super_traits, autoderef,
consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
diagnostics::BodyValidationDiagnostic,
+ known_const_to_ast,
layout::{Layout as TyLayout, RustcEnumVariantIdx, TagEncoding},
method_resolution::{self, TyFingerprint},
mir::{self, interpret_mir},
primitive::UintTy,
traits::FnTrait,
- AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
+ AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, ValueTyDefId,
WhereClause,
@@ -87,13 +88,14 @@ use triomphe::Arc;
use crate::db::{DefDatabase, HirDatabase};
pub use crate::{
- attrs::{HasAttrs, Namespace},
+ attrs::{resolve_doc_path_on, HasAttrs},
diagnostics::{
AnyDiagnostic, BreakOutsideOfLoop, CaseType, ExpectedFunction, InactiveCode,
IncoherentImpl, IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError,
- MacroExpansionParseError, MalformedDerive, MismatchedArgCount, MissingFields,
- MissingMatchArms, MissingUnsafe, MovedOutOfRef, NeedMut, NoSuchField, PrivateAssocItem,
- PrivateField, ReplaceFilterMapNextWithFindMap, TypeMismatch, TypedHole, UndeclaredLabel,
+ MacroExpansionParseError, MalformedDerive, MismatchedArgCount,
+ MismatchedTupleStructPatArgCount, MissingFields, MissingMatchArms, MissingUnsafe,
+ MovedOutOfRef, NeedMut, NoSuchField, PrivateAssocItem, PrivateField,
+ ReplaceFilterMapNextWithFindMap, TypeMismatch, TypedHole, UndeclaredLabel,
UnimplementedBuiltinMacro, UnreachableLabel, UnresolvedExternCrate, UnresolvedField,
UnresolvedImport, UnresolvedMacroCall, UnresolvedMethodCall, UnresolvedModule,
UnresolvedProcMacro, UnusedMut,
@@ -114,13 +116,14 @@ pub use crate::{
pub use {
cfg::{CfgAtom, CfgExpr, CfgOptions},
hir_def::{
- attr::{builtin::AttributeTemplate, Attrs, AttrsWithOwner, Documentation},
+ attr::{builtin::AttributeTemplate, AttrSourceMap, Attrs, AttrsWithOwner},
data::adt::StructKind,
find_path::PrefixKind,
import_map,
lang_item::LangItem,
nameres::{DefMap, ModuleSource},
path::{ModPath, PathKind},
+ per_ns::Namespace,
type_ref::{Mutability, TypeRef},
visibility::Visibility,
// FIXME: This is here since some queries take it as input that are used
@@ -128,7 +131,7 @@ pub use {
{AdtId, ModuleDefId},
},
hir_expand::{
- attrs::Attr,
+ attrs::{Attr, AttrId},
name::{known, Name},
ExpandResult, HirFileId, InFile, MacroFile, Origin,
},
@@ -561,8 +564,8 @@ impl Module {
emit_def_diagnostic(db, acc, diag);
}
- for decl in self.declarations(db) {
- match decl {
+ for def in self.declarations(db) {
+ match def {
ModuleDef::Module(m) => {
// Only add diagnostics from inline modules
if def_map[m.id.local_id].origin.is_inline() {
@@ -573,7 +576,7 @@ impl Module {
for diag in db.trait_data_with_diagnostics(t.id).1.iter() {
emit_def_diagnostic(db, acc, diag);
}
- acc.extend(decl.diagnostics(db))
+ acc.extend(def.diagnostics(db))
}
ModuleDef::Adt(adt) => {
match adt {
@@ -597,10 +600,10 @@ impl Module {
}
}
}
- acc.extend(decl.diagnostics(db))
+ acc.extend(def.diagnostics(db))
}
ModuleDef::Macro(m) => emit_macro_def_diagnostics(db, acc, m),
- _ => acc.extend(decl.diagnostics(db)),
+ _ => acc.extend(def.diagnostics(db)),
}
}
self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m));
@@ -719,20 +722,18 @@ fn emit_def_diagnostic_(
) {
match diag {
DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates } => {
- let decl = declaration.to_node(db.upcast());
+ let decl = declaration.to_ptr(db.upcast());
acc.push(
UnresolvedModule {
- decl: InFile::new(declaration.file_id, AstPtr::new(&decl)),
+ decl: InFile::new(declaration.file_id, decl),
candidates: candidates.clone(),
}
.into(),
)
}
DefDiagnosticKind::UnresolvedExternCrate { ast } => {
- let item = ast.to_node(db.upcast());
- acc.push(
- UnresolvedExternCrate { decl: InFile::new(ast.file_id, AstPtr::new(&item)) }.into(),
- );
+ let item = ast.to_ptr(db.upcast());
+ acc.push(UnresolvedExternCrate { decl: InFile::new(ast.file_id, item) }.into());
}
DefDiagnosticKind::UnresolvedImport { id, index } => {
@@ -747,14 +748,10 @@ fn emit_def_diagnostic_(
}
DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
- let item = ast.to_node(db.upcast());
+ let item = ast.to_ptr(db.upcast());
acc.push(
- InactiveCode {
- node: ast.with_value(SyntaxNodePtr::new(&item).into()),
- cfg: cfg.clone(),
- opts: opts.clone(),
- }
- .into(),
+ InactiveCode { node: ast.with_value(item), cfg: cfg.clone(), opts: opts.clone() }
+ .into(),
);
}
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
@@ -1273,7 +1270,7 @@ impl Adt {
.fill(|x| {
let r = it.next().unwrap_or_else(|| TyKind::Error.intern(Interner));
match x {
- ParamKind::Type => GenericArgData::Ty(r).intern(Interner),
+ ParamKind::Type => r.cast(Interner),
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
}
})
@@ -1450,6 +1447,7 @@ impl DefWithBody {
}
pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>) {
+ db.unwind_if_cancelled();
let krate = self.module(db).id.krate();
let (body, source_map) = db.body_with_source_map(self.into());
@@ -1505,11 +1503,19 @@ impl DefWithBody {
let infer = db.infer(self.into());
let source_map = Lazy::new(|| db.body_with_source_map(self.into()).1);
let expr_syntax = |expr| source_map.expr_syntax(expr).expect("unexpected synthetic");
+ let pat_syntax = |pat| source_map.pat_syntax(pat).expect("unexpected synthetic");
for d in &infer.diagnostics {
match d {
- &hir_ty::InferenceDiagnostic::NoSuchField { expr } => {
- let field = source_map.field_syntax(expr);
- acc.push(NoSuchField { field }.into())
+ &hir_ty::InferenceDiagnostic::NoSuchField { field: expr, private } => {
+ let expr_or_pat = match expr {
+ ExprOrPatId::ExprId(expr) => {
+ source_map.field_syntax(expr).map(Either::Left)
+ }
+ ExprOrPatId::PatId(pat) => {
+ source_map.pat_field_syntax(pat).map(Either::Right)
+ }
+ };
+ acc.push(NoSuchField { field: expr_or_pat, private }.into())
}
&hir_ty::InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
acc.push(
@@ -1525,10 +1531,7 @@ impl DefWithBody {
&hir_ty::InferenceDiagnostic::PrivateAssocItem { id, item } => {
let expr_or_pat = match id {
ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(Either::Left),
- ExprOrPatId::PatId(pat) => source_map
- .pat_syntax(pat)
- .expect("unexpected synthetic")
- .map(Either::Right),
+ ExprOrPatId::PatId(pat) => pat_syntax(pat).map(Either::Right),
};
let item = item.into();
acc.push(PrivateAssocItem { expr_or_pat, item }.into())
@@ -1600,6 +1603,23 @@ impl DefWithBody {
.into(),
)
}
+ &hir_ty::InferenceDiagnostic::MismatchedTupleStructPatArgCount {
+ pat,
+ expected,
+ found,
+ } => {
+ let expr_or_pat = match pat {
+ ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(Either::Left),
+ ExprOrPatId::PatId(pat) => source_map
+ .pat_syntax(pat)
+ .expect("unexpected synthetic")
+ .map(|it| it.unwrap_left())
+ .map(Either::Right),
+ };
+ acc.push(
+ MismatchedTupleStructPatArgCount { expr_or_pat, expected, found }.into(),
+ )
+ }
}
}
for (pat_or_expr, mismatch) in infer.type_mismatches() {
@@ -2096,14 +2116,6 @@ impl SelfParam {
.unwrap_or(Access::Owned)
}
- pub fn display(self, db: &dyn HirDatabase) -> &'static str {
- match self.access(db) {
- Access::Shared => "&self",
- Access::Exclusive => "&mut self",
- Access::Owned => "self",
- }
- }
-
pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>> {
let InFile { file_id, value } = Function::from(self.func).source(db)?;
value
@@ -3142,12 +3154,8 @@ impl TypeParam {
}
pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
- let params = db.generic_defaults(self.id.parent());
- let local_idx = hir_ty::param_idx(db, self.id.into())?;
+ let ty = generic_arg_from_param(db, self.id.into())?;
let resolver = self.id.parent().resolver(db.upcast());
- let ty = params.get(local_idx)?.clone();
- let subst = TyBuilder::placeholder_subst(db, self.id.parent());
- let ty = ty.substitute(Interner, &subst);
match ty.data(Interner) {
GenericArgData::Ty(it) => {
Some(Type::new_with_resolver_inner(db, &resolver, it.clone()))
@@ -3209,6 +3217,19 @@ impl ConstParam {
pub fn ty(self, db: &dyn HirDatabase) -> Type {
Type::new(db, self.id.parent(), db.const_param_ty(self.id))
}
+
+ pub fn default(self, db: &dyn HirDatabase) -> Option<ast::ConstArg> {
+ let arg = generic_arg_from_param(db, self.id.into())?;
+ known_const_to_ast(arg.constant(Interner)?, db)
+ }
+}
+
+fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg> {
+ let params = db.generic_defaults(id.parent);
+ let local_idx = hir_ty::param_idx(db, id)?;
+ let ty = params.get(local_idx)?.clone();
+ let subst = TyBuilder::placeholder_subst(db, id.parent);
+ Some(ty.substitute(Interner, &subst))
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -3716,7 +3737,7 @@ impl Type {
.fill(|x| {
let r = it.next().unwrap();
match x {
- ParamKind::Type => GenericArgData::Ty(r).intern(Interner),
+ ParamKind::Type => r.cast(Interner),
ParamKind::Const(ty) => {
// FIXME: this code is not covered in tests.
unknown_const_as_generic(ty.clone())
@@ -3749,9 +3770,7 @@ impl Type {
.fill(|it| {
// FIXME: this code is not covered in tests.
match it {
- ParamKind::Type => {
- GenericArgData::Ty(args.next().unwrap().ty.clone()).intern(Interner)
- }
+ ParamKind::Type => args.next().unwrap().ty.clone().cast(Interner),
ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
}
})
@@ -4414,14 +4433,13 @@ impl Callable {
Other => CallableKind::Other,
}
}
- pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(ast::SelfParam, Type)> {
+ pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(SelfParam, Type)> {
let func = match self.callee {
Callee::Def(CallableDefId::FunctionId(it)) if self.is_bound_method => it,
_ => return None,
};
- let src = func.lookup(db.upcast()).source(db.upcast());
- let param_list = src.value.param_list()?;
- Some((param_list.self_param()?, self.ty.derived(self.sig.params()[0].clone())))
+ let func = Function { id: func };
+ Some((func.self_param(db)?, self.ty.derived(self.sig.params()[0].clone())))
}
pub fn n_params(&self) -> usize {
self.sig.params().len() - if self.is_bound_method { 1 } else { 0 }
@@ -4844,3 +4862,10 @@ pub enum ItemContainer {
ExternBlock(),
Crate(CrateId),
}
+
+/// Subset of `ide_db::Definition` that doc links can resolve to.
+pub enum DocLinkDef {
+ ModuleDef(ModuleDef),
+ Field(Field),
+ SelfType(Trait),
+}
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index e99d2984c..a42e0978b 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -127,148 +127,24 @@ impl<DB> fmt::Debug for Semantics<'_, DB> {
}
}
+impl<'db, DB> ops::Deref for Semantics<'db, DB> {
+ type Target = SemanticsImpl<'db>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.imp
+ }
+}
+
impl<'db, DB: HirDatabase> Semantics<'db, DB> {
pub fn new(db: &DB) -> Semantics<'_, DB> {
let impl_ = SemanticsImpl::new(db);
Semantics { db, imp: impl_ }
}
- pub fn parse(&self, file_id: FileId) -> ast::SourceFile {
- self.imp.parse(file_id)
- }
-
- pub fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode {
- self.imp.parse_or_expand(file_id)
- }
-
- pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
- self.imp.expand(macro_call)
- }
-
- /// If `item` has an attribute macro attached to it, expands it.
- pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
- self.imp.expand_attr_macro(item)
- }
-
- pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Attr) -> Option<SyntaxNode> {
- self.imp.expand_derive_as_pseudo_attr_macro(attr)
- }
-
- pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option<Vec<Option<Macro>>> {
- self.imp.resolve_derive_macro(derive)
- }
-
- pub fn expand_derive_macro(&self, derive: &ast::Attr) -> Option<Vec<SyntaxNode>> {
- self.imp.expand_derive_macro(derive)
- }
-
- pub fn is_attr_macro_call(&self, item: &ast::Item) -> bool {
- self.imp.is_attr_macro_call(item)
- }
-
- pub fn is_derive_annotated(&self, item: &ast::Adt) -> bool {
- self.imp.is_derive_annotated(item)
- }
-
- pub fn speculative_expand(
- &self,
- actual_macro_call: &ast::MacroCall,
- speculative_args: &ast::TokenTree,
- token_to_map: SyntaxToken,
- ) -> Option<(SyntaxNode, SyntaxToken)> {
- self.imp.speculative_expand(actual_macro_call, speculative_args, token_to_map)
- }
-
- pub fn speculative_expand_attr_macro(
- &self,
- actual_macro_call: &ast::Item,
- speculative_args: &ast::Item,
- token_to_map: SyntaxToken,
- ) -> Option<(SyntaxNode, SyntaxToken)> {
- self.imp.speculative_expand_attr(actual_macro_call, speculative_args, token_to_map)
- }
-
- pub fn speculative_expand_derive_as_pseudo_attr_macro(
- &self,
- actual_macro_call: &ast::Attr,
- speculative_args: &ast::Attr,
- token_to_map: SyntaxToken,
- ) -> Option<(SyntaxNode, SyntaxToken)> {
- self.imp.speculative_expand_derive_as_pseudo_attr_macro(
- actual_macro_call,
- speculative_args,
- token_to_map,
- )
- }
-
- /// Descend the token into macrocalls to its first mapped counterpart.
- pub fn descend_into_macros_single(&self, token: SyntaxToken) -> SyntaxToken {
- self.imp.descend_into_macros_single(token)
- }
-
- /// Descend the token into macrocalls to all its mapped counterparts.
- pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
- self.imp.descend_into_macros(token)
- }
-
- /// Descend the token into macrocalls to all its mapped counterparts that have the same text as the input token.
- ///
- /// Returns the original non descended token if none of the mapped counterparts have the same text.
- pub fn descend_into_macros_with_same_text(
- &self,
- token: SyntaxToken,
- ) -> SmallVec<[SyntaxToken; 1]> {
- self.imp.descend_into_macros_with_same_text(token)
- }
-
- pub fn descend_into_macros_with_kind_preference(&self, token: SyntaxToken) -> SyntaxToken {
- self.imp.descend_into_macros_with_kind_preference(token)
- }
-
- /// Maps a node down by mapping its first and last token down.
- pub fn descend_node_into_attributes<N: AstNode>(&self, node: N) -> SmallVec<[N; 1]> {
- self.imp.descend_node_into_attributes(node)
- }
-
- /// Search for a definition's source and cache its syntax tree
- pub fn source<Def: HasSource>(&self, def: Def) -> Option<InFile<Def::Ast>>
- where
- Def::Ast: AstNode,
- {
- self.imp.source(def)
- }
-
pub fn hir_file_for(&self, syntax_node: &SyntaxNode) -> HirFileId {
self.imp.find_file(syntax_node).file_id
}
- /// Attempts to map the node out of macro expanded files returning the original file range.
- /// If upmapping is not possible, this will fall back to the range of the macro call of the
- /// macro file the node resides in.
- pub fn original_range(&self, node: &SyntaxNode) -> FileRange {
- self.imp.original_range(node)
- }
-
- /// Attempts to map the node out of macro expanded files returning the original file range.
- pub fn original_range_opt(&self, node: &SyntaxNode) -> Option<FileRange> {
- self.imp.original_range_opt(node)
- }
-
- /// Attempts to map the node out of macro expanded files.
- /// This only work for attribute expansions, as other ones do not have nodes as input.
- pub fn original_ast_node<N: AstNode>(&self, node: N) -> Option<N> {
- self.imp.original_ast_node(node)
- }
- /// Attempts to map the node out of macro expanded files.
- /// This only work for attribute expansions, as other ones do not have nodes as input.
- pub fn original_syntax_node(&self, node: &SyntaxNode) -> Option<SyntaxNode> {
- self.imp.original_syntax_node(node)
- }
-
- pub fn diagnostics_display_range(&self, diagnostics: InFile<SyntaxNodePtr>) -> FileRange {
- self.imp.diagnostics_display_range(diagnostics)
- }
-
pub fn token_ancestors_with_macros(
&self,
token: SyntaxToken,
@@ -276,19 +152,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
token.parent().into_iter().flat_map(move |it| self.ancestors_with_macros(it))
}
- /// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
- pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
- self.imp.ancestors_with_macros(node)
- }
-
- pub fn ancestors_at_offset_with_macros(
- &self,
- node: &SyntaxNode,
- offset: TextSize,
- ) -> impl Iterator<Item = SyntaxNode> + '_ {
- self.imp.ancestors_at_offset_with_macros(node, offset)
- }
-
/// Find an AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
/// search up until it is of the target AstNode type
pub fn find_node_at_offset_with_macros<N: AstNode>(
@@ -319,53 +182,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.descend_node_at_offset(node, offset).filter_map(|mut it| it.find_map(N::cast))
}
- pub fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
- self.imp.resolve_lifetime_param(lifetime)
- }
-
- pub fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
- self.imp.resolve_label(lifetime)
- }
-
- pub fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
- self.imp.resolve_type(ty)
- }
-
- pub fn resolve_trait(&self, trait_: &ast::Path) -> Option<Trait> {
- self.imp.resolve_trait(trait_)
- }
-
- pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment>> {
- self.imp.expr_adjustments(expr)
- }
-
- pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
- self.imp.type_of_expr(expr)
- }
-
- pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<TypeInfo> {
- self.imp.type_of_pat(pat)
- }
-
- /// It also includes the changes that binding mode makes in the type. For example in
- /// `let ref x @ Some(_) = None` the result of `type_of_pat` is `Option<T>` but the result
- /// of this function is `&mut Option<T>`
- pub fn type_of_binding_in_pat(&self, pat: &ast::IdentPat) -> Option<Type> {
- self.imp.type_of_binding_in_pat(pat)
- }
-
- pub fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
- self.imp.type_of_self(param)
- }
-
- pub fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> {
- self.imp.pattern_adjustments(pat)
- }
-
- pub fn binding_mode_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingMode> {
- self.imp.binding_mode_of_pat(pat)
- }
-
pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
self.imp.resolve_method_call(call).map(Function::from)
}
@@ -400,61 +216,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.resolve_try_expr(try_expr).map(Function::from)
}
- pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
- self.imp.resolve_method_call_as_callable(call)
- }
-
- pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
- self.imp.resolve_field(field)
- }
-
- pub fn resolve_record_field(
- &self,
- field: &ast::RecordExprField,
- ) -> Option<(Field, Option<Local>, Type)> {
- self.imp.resolve_record_field(field)
- }
-
- pub fn resolve_record_pat_field(&self, field: &ast::RecordPatField) -> Option<(Field, Type)> {
- self.imp.resolve_record_pat_field(field)
- }
-
- pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
- self.imp.resolve_macro_call(macro_call)
- }
-
- pub fn is_unsafe_macro_call(&self, macro_call: &ast::MacroCall) -> bool {
- self.imp.is_unsafe_macro_call(macro_call)
- }
-
- pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<Macro> {
- self.imp.resolve_attr_macro_call(item)
- }
-
- pub fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
- self.imp.resolve_path(path)
- }
-
pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantDef> {
self.imp.resolve_variant(record_lit).map(VariantDef::from)
}
- pub fn resolve_bind_pat_to_const(&self, pat: &ast::IdentPat) -> Option<ModuleDef> {
- self.imp.resolve_bind_pat_to_const(pat)
- }
-
- pub fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> {
- self.imp.record_literal_missing_fields(literal)
- }
-
- pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> {
- self.imp.record_pattern_missing_fields(pattern)
- }
-
- pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
- self.imp.to_def(src)
- }
-
pub fn to_module_def(&self, file: FileId) -> Option<Module> {
self.imp.to_module_def(file).next()
}
@@ -462,39 +227,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
pub fn to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> {
self.imp.to_module_def(file)
}
-
- pub fn scope(&self, node: &SyntaxNode) -> Option<SemanticsScope<'db>> {
- self.imp.scope(node)
- }
-
- pub fn scope_at_offset(
- &self,
- node: &SyntaxNode,
- offset: TextSize,
- ) -> Option<SemanticsScope<'db>> {
- self.imp.scope_at_offset(node, offset)
- }
-
- pub fn assert_contains_node(&self, node: &SyntaxNode) {
- self.imp.assert_contains_node(node)
- }
-
- pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool {
- self.imp.is_unsafe_method_call(method_call_expr)
- }
-
- pub fn is_unsafe_ref_expr(&self, ref_expr: &ast::RefExpr) -> bool {
- self.imp.is_unsafe_ref_expr(ref_expr)
- }
-
- pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
- self.imp.is_unsafe_ident_pat(ident_pat)
- }
-
- /// Returns `true` if the `node` is inside an `unsafe` context.
- pub fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
- self.imp.is_inside_unsafe(expr)
- }
}
impl<'db> SemanticsImpl<'db> {
@@ -508,32 +240,33 @@ impl<'db> SemanticsImpl<'db> {
}
}
- fn parse(&self, file_id: FileId) -> ast::SourceFile {
+ pub fn parse(&self, file_id: FileId) -> ast::SourceFile {
let tree = self.db.parse(file_id).tree();
self.cache(tree.syntax().clone(), file_id.into());
tree
}
- fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode {
+ pub fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode {
let node = self.db.parse_or_expand(file_id);
self.cache(node.clone(), file_id);
node
}
- fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
+ pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
let sa = self.analyze_no_infer(macro_call.syntax())?;
let file_id = sa.expand(self.db, InFile::new(sa.file_id, macro_call))?;
let node = self.parse_or_expand(file_id);
Some(node)
}
- fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
+ /// If `item` has an attribute macro attached to it, expands it.
+ pub fn expand_attr_macro(&self, item: &ast::Item) -> Option<SyntaxNode> {
let src = self.wrap_node_infile(item.clone());
let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(src))?;
Some(self.parse_or_expand(macro_call_id.as_file()))
}
- fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Attr) -> Option<SyntaxNode> {
+ pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Attr) -> Option<SyntaxNode> {
let adt = attr.syntax().parent().and_then(ast::Adt::cast)?;
let src = self.wrap_node_infile(attr.clone());
let call_id = self.with_ctx(|ctx| {
@@ -542,7 +275,7 @@ impl<'db> SemanticsImpl<'db> {
Some(self.parse_or_expand(call_id.as_file()))
}
- fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<Option<Macro>>> {
+ pub fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<Option<Macro>>> {
let calls = self.derive_macro_calls(attr)?;
self.with_ctx(|ctx| {
Some(
@@ -556,7 +289,7 @@ impl<'db> SemanticsImpl<'db> {
})
}
- fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<SyntaxNode>> {
+ pub fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<SyntaxNode>> {
let res: Vec<_> = self
.derive_macro_calls(attr)?
.into_iter()
@@ -581,19 +314,21 @@ impl<'db> SemanticsImpl<'db> {
})
}
- fn is_derive_annotated(&self, adt: &ast::Adt) -> bool {
+ pub fn is_derive_annotated(&self, adt: &ast::Adt) -> bool {
let file_id = self.find_file(adt.syntax()).file_id;
let adt = InFile::new(file_id, adt);
self.with_ctx(|ctx| ctx.has_derives(adt))
}
- fn is_attr_macro_call(&self, item: &ast::Item) -> bool {
+ pub fn is_attr_macro_call(&self, item: &ast::Item) -> bool {
let file_id = self.find_file(item.syntax()).file_id;
let src = InFile::new(file_id, item.clone());
self.with_ctx(|ctx| ctx.item_to_macro_call(src).is_some())
}
- fn speculative_expand(
+ /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the
+ /// expansion. `token_to_map` should be a token from the `speculative args` node.
+ pub fn speculative_expand(
&self,
actual_macro_call: &ast::MacroCall,
speculative_args: &ast::TokenTree,
@@ -606,7 +341,7 @@ impl<'db> SemanticsImpl<'db> {
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
resolver
.resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
- .map(|it| macro_id_to_def_id(self.db.upcast(), it))
+ .map(|(it, _)| macro_id_to_def_id(self.db.upcast(), it))
})?;
hir_expand::db::expand_speculative(
self.db.upcast(),
@@ -616,7 +351,9 @@ impl<'db> SemanticsImpl<'db> {
)
}
- fn speculative_expand_attr(
+ /// Expand the macro call with a different item as the input, mapping the `token_to_map` down into the
+ /// expansion. `token_to_map` should be a token from the `speculative args` node.
+ pub fn speculative_expand_attr_macro(
&self,
actual_macro_call: &ast::Item,
speculative_args: &ast::Item,
@@ -632,7 +369,7 @@ impl<'db> SemanticsImpl<'db> {
)
}
- fn speculative_expand_derive_as_pseudo_attr_macro(
+ pub fn speculative_expand_derive_as_pseudo_attr_macro(
&self,
actual_macro_call: &ast::Attr,
speculative_args: &ast::Attr,
@@ -651,8 +388,9 @@ impl<'db> SemanticsImpl<'db> {
)
}
- // This might not be the correct way to do this, but it works for now
- fn descend_node_into_attributes<N: AstNode>(&self, node: N) -> SmallVec<[N; 1]> {
+ /// Maps a node down by mapping its first and last token down.
+ pub fn descend_node_into_attributes<N: AstNode>(&self, node: N) -> SmallVec<[N; 1]> {
+ // This might not be the correct way to do this, but it works for now
let mut res = smallvec![];
let tokens = (|| {
let first = skip_trivia_token(node.syntax().first_token()?, Direction::Next)?;
@@ -665,7 +403,7 @@ impl<'db> SemanticsImpl<'db> {
};
if first == last {
- self.descend_into_macros_impl(first, &mut |InFile { value, .. }| {
+ self.descend_into_macros_impl(first, 0.into(), &mut |InFile { value, .. }| {
if let Some(node) = value.parent_ancestors().find_map(N::cast) {
res.push(node)
}
@@ -674,7 +412,7 @@ impl<'db> SemanticsImpl<'db> {
} else {
// Descend first and last token, then zip them to look for the node they belong to
let mut scratch: SmallVec<[_; 1]> = smallvec![];
- self.descend_into_macros_impl(first, &mut |token| {
+ self.descend_into_macros_impl(first, 0.into(), &mut |token| {
scratch.push(token);
false
});
@@ -682,6 +420,7 @@ impl<'db> SemanticsImpl<'db> {
let mut scratch = scratch.into_iter();
self.descend_into_macros_impl(
last,
+ 0.into(),
&mut |InFile { value: last, file_id: last_fid }| {
if let Some(InFile { value: first, file_id: first_fid }) = scratch.next() {
if first_fid == last_fid {
@@ -705,19 +444,33 @@ impl<'db> SemanticsImpl<'db> {
res
}
- fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
+ /// Descend the token into its macro call if it is part of one, returning the tokens in the
+ /// expansion that it is associated with. If `offset` points into the token's range, it will
+ /// be considered for the mapping in case of inline format args.
+ pub fn descend_into_macros(
+ &self,
+ token: SyntaxToken,
+ offset: TextSize,
+ ) -> SmallVec<[SyntaxToken; 1]> {
let mut res = smallvec![];
- self.descend_into_macros_impl(token, &mut |InFile { value, .. }| {
+ self.descend_into_macros_impl(token, offset, &mut |InFile { value, .. }| {
res.push(value);
false
});
res
}
- fn descend_into_macros_with_same_text(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
+ /// Descend the token into macrocalls to all its mapped counterparts that have the same text as the input token.
+ ///
+ /// Returns the original non descended token if none of the mapped counterparts have the same text.
+ pub fn descend_into_macros_with_same_text(
+ &self,
+ token: SyntaxToken,
+ offset: TextSize,
+ ) -> SmallVec<[SyntaxToken; 1]> {
let text = token.text();
let mut res = smallvec![];
- self.descend_into_macros_impl(token.clone(), &mut |InFile { value, .. }| {
+ self.descend_into_macros_impl(token.clone(), offset, &mut |InFile { value, .. }| {
if value.text() == text {
res.push(value);
}
@@ -729,7 +482,11 @@ impl<'db> SemanticsImpl<'db> {
res
}
- fn descend_into_macros_with_kind_preference(&self, token: SyntaxToken) -> SyntaxToken {
+ pub fn descend_into_macros_with_kind_preference(
+ &self,
+ token: SyntaxToken,
+ offset: TextSize,
+ ) -> SyntaxToken {
let fetch_kind = |token: &SyntaxToken| match token.parent() {
Some(node) => match node.kind() {
kind @ (SyntaxKind::NAME | SyntaxKind::NAME_REF) => {
@@ -741,7 +498,7 @@ impl<'db> SemanticsImpl<'db> {
};
let preferred_kind = fetch_kind(&token);
let mut res = None;
- self.descend_into_macros_impl(token.clone(), &mut |InFile { value, .. }| {
+ self.descend_into_macros_impl(token.clone(), offset, &mut |InFile { value, .. }| {
if fetch_kind(&value) == preferred_kind {
res = Some(value);
true
@@ -755,9 +512,12 @@ impl<'db> SemanticsImpl<'db> {
res.unwrap_or(token)
}
- fn descend_into_macros_single(&self, token: SyntaxToken) -> SyntaxToken {
+ /// Descend the token into its macro call if it is part of one, returning the token in the
+ /// expansion that it is associated with. If `offset` points into the token's range, it will
+ /// be considered for the mapping in case of inline format args.
+ pub fn descend_into_macros_single(&self, token: SyntaxToken, offset: TextSize) -> SyntaxToken {
let mut res = token.clone();
- self.descend_into_macros_impl(token, &mut |InFile { value, .. }| {
+ self.descend_into_macros_impl(token, offset, &mut |InFile { value, .. }| {
res = value;
true
});
@@ -767,9 +527,13 @@ impl<'db> SemanticsImpl<'db> {
fn descend_into_macros_impl(
&self,
token: SyntaxToken,
+ // FIXME: We might want this to be Option<TextSize> to be able to opt out of subrange
+ // mapping, specifically for node downmapping
+ offset: TextSize,
f: &mut dyn FnMut(InFile<SyntaxToken>) -> bool,
) {
let _p = profile::span("descend_into_macros");
+ let relative_token_offset = token.text_range().start().checked_sub(offset);
let parent = match token.parent() {
Some(it) => it,
None => return,
@@ -796,7 +560,12 @@ impl<'db> SemanticsImpl<'db> {
self.cache(value, file_id);
}
- let mapped_tokens = expansion_info.map_token_down(self.db.upcast(), item, token)?;
+ let mapped_tokens = expansion_info.map_token_down(
+ self.db.upcast(),
+ item,
+ token,
+ relative_token_offset,
+ )?;
let len = stack.len();
// requeue the tokens we got from mapping our current token down
@@ -943,7 +712,7 @@ impl<'db> SemanticsImpl<'db> {
offset: TextSize,
) -> impl Iterator<Item = impl Iterator<Item = SyntaxNode> + '_> + '_ {
node.token_at_offset(offset)
- .map(move |token| self.descend_into_macros(token))
+ .map(move |token| self.descend_into_macros(token, offset))
.map(|descendants| {
descendants.into_iter().map(move |it| self.token_ancestors_with_macros(it))
})
@@ -956,17 +725,23 @@ impl<'db> SemanticsImpl<'db> {
})
}
- fn original_range(&self, node: &SyntaxNode) -> FileRange {
+ /// Attempts to map the node out of macro expanded files returning the original file range.
+ /// If upmapping is not possible, this will fall back to the range of the macro call of the
+ /// macro file the node resides in.
+ pub fn original_range(&self, node: &SyntaxNode) -> FileRange {
let node = self.find_file(node);
node.original_file_range(self.db.upcast())
}
- fn original_range_opt(&self, node: &SyntaxNode) -> Option<FileRange> {
+ /// Attempts to map the node out of macro expanded files returning the original file range.
+ pub fn original_range_opt(&self, node: &SyntaxNode) -> Option<FileRange> {
let node = self.find_file(node);
node.original_file_range_opt(self.db.upcast())
}
- fn original_ast_node<N: AstNode>(&self, node: N) -> Option<N> {
+ /// Attempts to map the node out of macro expanded files.
+ /// This only work for attribute expansions, as other ones do not have nodes as input.
+ pub fn original_ast_node<N: AstNode>(&self, node: N) -> Option<N> {
self.wrap_node_infile(node).original_ast_node(self.db.upcast()).map(
|InFile { file_id, value }| {
self.cache(find_root(value.syntax()), file_id);
@@ -975,7 +750,9 @@ impl<'db> SemanticsImpl<'db> {
)
}
- fn original_syntax_node(&self, node: &SyntaxNode) -> Option<SyntaxNode> {
+ /// Attempts to map the node out of macro expanded files.
+ /// This only work for attribute expansions, as other ones do not have nodes as input.
+ pub fn original_syntax_node(&self, node: &SyntaxNode) -> Option<SyntaxNode> {
let InFile { file_id, .. } = self.find_file(node);
InFile::new(file_id, node).original_syntax_node(self.db.upcast()).map(
|InFile { file_id, value }| {
@@ -985,7 +762,7 @@ impl<'db> SemanticsImpl<'db> {
)
}
- fn diagnostics_display_range(&self, src: InFile<SyntaxNodePtr>) -> FileRange {
+ pub fn diagnostics_display_range(&self, src: InFile<SyntaxNodePtr>) -> FileRange {
let root = self.parse_or_expand(src.file_id);
let node = src.map(|it| it.to_node(&root));
node.as_ref().original_file_range(self.db.upcast())
@@ -998,7 +775,8 @@ impl<'db> SemanticsImpl<'db> {
token.parent().into_iter().flat_map(move |parent| self.ancestors_with_macros(parent))
}
- fn ancestors_with_macros(
+ /// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
+ pub fn ancestors_with_macros(
&self,
node: SyntaxNode,
) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
@@ -1016,7 +794,7 @@ impl<'db> SemanticsImpl<'db> {
.map(|it| it.value)
}
- fn ancestors_at_offset_with_macros(
+ pub fn ancestors_at_offset_with_macros(
&self,
node: &SyntaxNode,
offset: TextSize,
@@ -1026,7 +804,7 @@ impl<'db> SemanticsImpl<'db> {
.kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
}
- fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
+ pub fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
let text = lifetime.text();
let lifetime_param = lifetime.syntax().ancestors().find_map(|syn| {
let gpl = ast::AnyHasGenericParams::cast(syn)?.generic_param_list()?;
@@ -1037,7 +815,7 @@ impl<'db> SemanticsImpl<'db> {
ToDef::to_def(self, src)
}
- fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
+ pub fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
let text = lifetime.text();
let label = lifetime.syntax().ancestors().find_map(|syn| {
let label = match_ast! {
@@ -1059,7 +837,7 @@ impl<'db> SemanticsImpl<'db> {
ToDef::to_def(self, src)
}
- fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
+ pub fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
let analyze = self.analyze(ty.syntax())?;
let ctx = LowerCtx::with_file_id(self.db.upcast(), analyze.file_id);
let ty = hir_ty::TyLoweringContext::new(
@@ -1071,7 +849,7 @@ impl<'db> SemanticsImpl<'db> {
Some(Type::new_with_resolver(self.db, &analyze.resolver, ty))
}
- fn resolve_trait(&self, path: &ast::Path) -> Option<Trait> {
+ pub fn resolve_trait(&self, path: &ast::Path) -> Option<Trait> {
let analyze = self.analyze(path.syntax())?;
let hygiene = hir_expand::hygiene::Hygiene::new(self.db.upcast(), analyze.file_id);
let ctx = LowerCtx::with_hygiene(self.db.upcast(), &hygiene);
@@ -1082,7 +860,7 @@ impl<'db> SemanticsImpl<'db> {
}
}
- fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment>> {
+ pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment>> {
let mutability = |m| match m {
hir_ty::Mutability::Not => Mutability::Shared,
hir_ty::Mutability::Mut => Mutability::Mut,
@@ -1126,33 +904,36 @@ impl<'db> SemanticsImpl<'db> {
})
}
- fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
+ pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
self.analyze(expr.syntax())?
.type_of_expr(self.db, expr)
.map(|(ty, coerced)| TypeInfo { original: ty, adjusted: coerced })
}
- fn type_of_pat(&self, pat: &ast::Pat) -> Option<TypeInfo> {
+ pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<TypeInfo> {
self.analyze(pat.syntax())?
.type_of_pat(self.db, pat)
.map(|(ty, coerced)| TypeInfo { original: ty, adjusted: coerced })
}
- fn type_of_binding_in_pat(&self, pat: &ast::IdentPat) -> Option<Type> {
+ /// It also includes the changes that binding mode makes in the type. For example in
+ /// `let ref x @ Some(_) = None` the result of `type_of_pat` is `Option<T>` but the result
+ /// of this function is `&mut Option<T>`
+ pub fn type_of_binding_in_pat(&self, pat: &ast::IdentPat) -> Option<Type> {
self.analyze(pat.syntax())?.type_of_binding_in_pat(self.db, pat)
}
- fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
+ pub fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
self.analyze(param.syntax())?.type_of_self(self.db, param)
}
- fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> {
+ pub fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> {
self.analyze(pat.syntax())
.and_then(|it| it.pattern_adjustments(self.db, pat))
.unwrap_or_default()
}
- fn binding_mode_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingMode> {
+ pub fn binding_mode_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingMode> {
self.analyze(pat.syntax())?.binding_mode_of_pat(self.db, pat)
}
@@ -1187,32 +968,32 @@ impl<'db> SemanticsImpl<'db> {
self.analyze(try_expr.syntax())?.resolve_try_expr(self.db, try_expr)
}
- fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
+ pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
self.analyze(call.syntax())?.resolve_method_call_as_callable(self.db, call)
}
- fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
+ pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
self.analyze(field.syntax())?.resolve_field(self.db, field)
}
- fn resolve_record_field(
+ pub fn resolve_record_field(
&self,
field: &ast::RecordExprField,
) -> Option<(Field, Option<Local>, Type)> {
self.analyze(field.syntax())?.resolve_record_field(self.db, field)
}
- fn resolve_record_pat_field(&self, field: &ast::RecordPatField) -> Option<(Field, Type)> {
+ pub fn resolve_record_pat_field(&self, field: &ast::RecordPatField) -> Option<(Field, Type)> {
self.analyze(field.syntax())?.resolve_record_pat_field(self.db, field)
}
- fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
+ pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
let sa = self.analyze(macro_call.syntax())?;
let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call);
sa.resolve_macro_call(self.db, macro_call)
}
- fn is_unsafe_macro_call(&self, macro_call: &ast::MacroCall) -> bool {
+ pub fn is_unsafe_macro_call(&self, macro_call: &ast::MacroCall) -> bool {
let sa = match self.analyze(macro_call.syntax()) {
Some(it) => it,
None => return false,
@@ -1221,7 +1002,7 @@ impl<'db> SemanticsImpl<'db> {
sa.is_unsafe_macro_call(self.db, macro_call)
}
- fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<Macro> {
+ pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<Macro> {
let item_in_file = self.wrap_node_infile(item.clone());
let id = self.with_ctx(|ctx| {
let macro_call_id = ctx.item_to_macro_call(item_in_file)?;
@@ -1230,7 +1011,7 @@ impl<'db> SemanticsImpl<'db> {
Some(Macro { id })
}
- fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
+ pub fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
self.analyze(path.syntax())?.resolve_path(self.db, path)
}
@@ -1238,17 +1019,17 @@ impl<'db> SemanticsImpl<'db> {
self.analyze(record_lit.syntax())?.resolve_variant(self.db, record_lit)
}
- fn resolve_bind_pat_to_const(&self, pat: &ast::IdentPat) -> Option<ModuleDef> {
+ pub fn resolve_bind_pat_to_const(&self, pat: &ast::IdentPat) -> Option<ModuleDef> {
self.analyze(pat.syntax())?.resolve_bind_pat_to_const(self.db, pat)
}
- fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> {
+ pub fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> {
self.analyze(literal.syntax())
.and_then(|it| it.record_literal_missing_fields(self.db, literal))
.unwrap_or_default()
}
- fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> {
+ pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> {
self.analyze(pattern.syntax())
.and_then(|it| it.record_pattern_missing_fields(self.db, pattern))
.unwrap_or_default()
@@ -1260,7 +1041,7 @@ impl<'db> SemanticsImpl<'db> {
f(&mut ctx)
}
- fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
+ pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
let src = self.find_file(src.syntax()).with_value(src).cloned();
T::to_def(self, src)
}
@@ -1269,7 +1050,7 @@ impl<'db> SemanticsImpl<'db> {
self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
}
- fn scope(&self, node: &SyntaxNode) -> Option<SemanticsScope<'db>> {
+ pub fn scope(&self, node: &SyntaxNode) -> Option<SemanticsScope<'db>> {
self.analyze_no_infer(node).map(|SourceAnalyzer { file_id, resolver, .. }| SemanticsScope {
db: self.db,
file_id,
@@ -1277,7 +1058,11 @@ impl<'db> SemanticsImpl<'db> {
})
}
- fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> Option<SemanticsScope<'db>> {
+ pub fn scope_at_offset(
+ &self,
+ node: &SyntaxNode,
+ offset: TextSize,
+ ) -> Option<SemanticsScope<'db>> {
self.analyze_with_offset_no_infer(node, offset).map(
|SourceAnalyzer { file_id, resolver, .. }| SemanticsScope {
db: self.db,
@@ -1287,7 +1072,8 @@ impl<'db> SemanticsImpl<'db> {
)
}
- fn source<Def: HasSource>(&self, def: Def) -> Option<InFile<Def::Ast>>
+ /// Search for a definition's source and cache its syntax tree
+ pub fn source<Def: HasSource>(&self, def: Def) -> Option<InFile<Def::Ast>>
where
Def::Ast: AstNode,
{
@@ -1352,7 +1138,7 @@ impl<'db> SemanticsImpl<'db> {
assert!(prev == None || prev == Some(file_id))
}
- fn assert_contains_node(&self, node: &SyntaxNode) {
+ pub fn assert_contains_node(&self, node: &SyntaxNode) {
self.find_file(node);
}
@@ -1388,7 +1174,7 @@ impl<'db> SemanticsImpl<'db> {
InFile::new(file_id, node)
}
- fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool {
+ pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool {
method_call_expr
.receiver()
.and_then(|expr| {
@@ -1411,7 +1197,7 @@ impl<'db> SemanticsImpl<'db> {
.unwrap_or(false)
}
- fn is_unsafe_ref_expr(&self, ref_expr: &ast::RefExpr) -> bool {
+ pub fn is_unsafe_ref_expr(&self, ref_expr: &ast::RefExpr) -> bool {
ref_expr
.expr()
.and_then(|expr| {
@@ -1430,7 +1216,7 @@ impl<'db> SemanticsImpl<'db> {
// more than it should with the current implementation.
}
- fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
+ pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
if ident_pat.ref_token().is_none() {
return false;
}
@@ -1473,7 +1259,8 @@ impl<'db> SemanticsImpl<'db> {
.unwrap_or(false)
}
- fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
+ /// Returns `true` if the `node` is inside an `unsafe` context.
+ pub fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
let Some(enclosing_item) =
expr.syntax().ancestors().find_map(Either::<ast::Item, ast::Variant>::cast)
else {
@@ -1683,6 +1470,14 @@ impl SemanticsScope<'_> {
|name, id| cb(name, id.into()),
)
}
+
+ pub fn extern_crates(&self) -> impl Iterator<Item = (Name, Module)> + '_ {
+ self.resolver.extern_crates_in_scope().map(|(name, id)| (name, Module { id }))
+ }
+
+ pub fn extern_crate_decls(&self) -> impl Iterator<Item = Name> + '_ {
+ self.resolver.extern_crate_decls_in_scope(self.db.upcast())
+ }
}
#[derive(Debug)]
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 3499daf11..f29fb1edf 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -487,7 +487,7 @@ impl SourceAnalyzer {
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
self.resolver
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Bang))
- .map(|it| it.into())
+ .map(|(it, _)| it.into())
}
pub(crate) fn resolve_bind_pat_to_const(
@@ -760,7 +760,7 @@ impl SourceAnalyzer {
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
self.resolver
.resolve_path_as_macro(db.upcast(), &path, Some(MacroSubNs::Bang))
- .map(|it| macro_id_to_def_id(db.upcast(), it))
+ .map(|(it, _)| macro_id_to_def_id(db.upcast(), it))
})?;
Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
}
@@ -966,6 +966,7 @@ pub(crate) fn resolve_hir_path_as_attr_macro(
) -> Option<Macro> {
resolver
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Attr))
+ .map(|(it, _)| it)
.map(Into::into)
}
@@ -983,7 +984,7 @@ fn resolve_hir_path_(
res.map(|ty_ns| (ty_ns, path.segments().first()))
}
None => {
- let (ty, remaining_idx) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
+ let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
match remaining_idx {
Some(remaining_idx) => {
if remaining_idx + 1 == path.segments().len() {
@@ -1067,7 +1068,7 @@ fn resolve_hir_path_(
let macros = || {
resolver
.resolve_path_as_macro(db.upcast(), path.mod_path()?, None)
- .map(|def| PathResolution::Def(ModuleDef::Macro(def.into())))
+ .map(|(def, _)| PathResolution::Def(ModuleDef::Macro(def.into())))
};
if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }
diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
index 43d957412..ca7874c36 100644
--- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
@@ -2,8 +2,10 @@
use base_db::FileRange;
use hir_def::{
- src::HasSource, AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, Lookup, MacroId,
- ModuleDefId, ModuleId, TraitId,
+ item_scope::ItemInNs,
+ src::{HasChildSource, HasSource},
+ AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, Lookup, MacroId, ModuleDefId, ModuleId,
+ TraitId,
};
use hir_expand::{HirFileId, InFile};
use hir_ty::db::HirDatabase;
@@ -167,6 +169,40 @@ impl<'a> SymbolCollector<'a> {
self.collect_from_impl(impl_id);
}
+ // Record renamed imports.
+ // In case it imports multiple items under different namespaces we just pick one arbitrarily
+ // for now.
+ for id in scope.imports() {
+ let loc = id.import.lookup(self.db.upcast());
+ loc.id.item_tree(self.db.upcast());
+ let source = id.import.child_source(self.db.upcast());
+ let Some(use_tree_src) = source.value.get(id.idx) else { continue };
+ let Some(rename) = use_tree_src.rename() else { continue };
+ let Some(name) = rename.name() else { continue };
+
+ let res = scope.fully_resolve_import(self.db.upcast(), id);
+ res.iter_items().for_each(|(item, _)| {
+ let def = match item {
+ ItemInNs::Types(def) | ItemInNs::Values(def) => def,
+ ItemInNs::Macros(def) => ModuleDefId::from(def),
+ }
+ .into();
+ let dec_loc = DeclarationLocation {
+ hir_file_id: source.file_id,
+ ptr: SyntaxNodePtr::new(use_tree_src.syntax()),
+ name_ptr: SyntaxNodePtr::new(name.syntax()),
+ };
+
+ self.symbols.push(FileSymbol {
+ name: name.text().into(),
+ def,
+ container_name: self.current_container_name.clone(),
+ loc: dec_loc,
+ is_alias: false,
+ });
+ });
+ }
+
for const_id in scope.unnamed_consts() {
self.collect_from_body(const_id);
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index 6aca716bb..c0e5429a2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -422,7 +422,7 @@ impl<'x, 'y, T, V, U: Default> Trait<'x, 'y, T, V, U> for () {
check_assist(
add_missing_default_members,
r#"
-struct Bar<const: N: bool> {
+struct Bar<const N: usize> {
bar: [i32, N]
}
@@ -439,7 +439,7 @@ impl<const X: usize, Y, Z> Foo<X, Z> for S<Y> {
$0
}"#,
r#"
-struct Bar<const: N: bool> {
+struct Bar<const N: usize> {
bar: [i32, N]
}
@@ -484,6 +484,107 @@ impl<X> Foo<42, {20 + 22}, X> for () {
}
#[test]
+ fn test_const_substitution_with_defaults() {
+ check_assist(
+ add_missing_default_members,
+ r#"
+trait Foo<T, const N: usize = 42, const M: bool = false, const P: char = 'a'> {
+ fn get_n(&self) -> usize { N }
+ fn get_m(&self) -> bool { M }
+ fn get_p(&self) -> char { P }
+ fn get_array(&self, arg: &T) -> [bool; N] { [M; N] }
+}
+
+impl<X> Foo<X> for () {
+ $0
+}"#,
+ r#"
+trait Foo<T, const N: usize = 42, const M: bool = false, const P: char = 'a'> {
+ fn get_n(&self) -> usize { N }
+ fn get_m(&self) -> bool { M }
+ fn get_p(&self) -> char { P }
+ fn get_array(&self, arg: &T) -> [bool; N] { [M; N] }
+}
+
+impl<X> Foo<X> for () {
+ $0fn get_n(&self) -> usize { 42 }
+
+ fn get_m(&self) -> bool { false }
+
+ fn get_p(&self) -> char { 'a' }
+
+ fn get_array(&self, arg: &X) -> [bool; 42] { [false; 42] }
+}"#,
+ );
+ }
+
+ #[test]
+ fn test_const_substitution_with_defaults_2() {
+ check_assist(
+ add_missing_impl_members,
+ r#"
+mod m {
+ pub const LEN: usize = 42;
+ pub trait Foo<const M: usize = LEN, const N: usize = M, T = [bool; N]> {
+ fn get_t(&self) -> T;
+ }
+}
+
+impl m::Foo for () {
+ $0
+}"#,
+ r#"
+mod m {
+ pub const LEN: usize = 42;
+ pub trait Foo<const M: usize = LEN, const N: usize = M, T = [bool; N]> {
+ fn get_t(&self) -> T;
+ }
+}
+
+impl m::Foo for () {
+ fn get_t(&self) -> [bool; m::LEN] {
+ ${0:todo!()}
+ }
+}"#,
+ )
+ }
+
+ #[test]
+ fn test_const_substitution_with_defaults_3() {
+ check_assist(
+ add_missing_default_members,
+ r#"
+mod m {
+ pub const VAL: usize = 0;
+
+ pub trait Foo<const N: usize = {40 + 2}, const M: usize = {VAL + 1}> {
+ fn get_n(&self) -> usize { N }
+ fn get_m(&self) -> usize { M }
+ }
+}
+
+impl m::Foo for () {
+ $0
+}"#,
+ r#"
+mod m {
+ pub const VAL: usize = 0;
+
+ pub trait Foo<const N: usize = {40 + 2}, const M: usize = {VAL + 1}> {
+ fn get_n(&self) -> usize { N }
+ fn get_m(&self) -> usize { M }
+ }
+}
+
+impl m::Foo for () {
+ $0fn get_n(&self) -> usize { {40 + 2} }
+
+ fn get_m(&self) -> usize { {m::VAL + 1} }
+}"#,
+ )
+ }
+
+ #[test]
fn test_cursor_after_empty_impl_def() {
check_assist(
add_missing_impl_members,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
index 57cfa17cc..66bc2f6da 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
@@ -1,6 +1,10 @@
use std::collections::VecDeque;
-use syntax::ast::{self, AstNode};
+use syntax::{
+ ast::{self, AstNode, Expr::BinExpr},
+ ted::{self, Position},
+ SyntaxKind,
+};
use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists};
@@ -23,121 +27,117 @@ use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKin
// }
// ```
pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
- let expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
- let op = expr.op_kind()?;
- let op_range = expr.op_token()?.text_range();
+ let mut bin_expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
+ let op = bin_expr.op_kind()?;
+ let op_range = bin_expr.op_token()?.text_range();
- let opposite_op = match op {
- ast::BinaryOp::LogicOp(ast::LogicOp::And) => "||",
- ast::BinaryOp::LogicOp(ast::LogicOp::Or) => "&&",
- _ => return None,
- };
-
- let cursor_in_range = op_range.contains_range(ctx.selection_trimmed());
- if !cursor_in_range {
+ // Is the cursor on the expression's logical operator?
+ if !op_range.contains_range(ctx.selection_trimmed()) {
return None;
}
- let mut expr = expr;
-
// Walk up the tree while we have the same binary operator
- while let Some(parent_expr) = expr.syntax().parent().and_then(ast::BinExpr::cast) {
- match expr.op_kind() {
+ while let Some(parent_expr) = bin_expr.syntax().parent().and_then(ast::BinExpr::cast) {
+ match parent_expr.op_kind() {
Some(parent_op) if parent_op == op => {
- expr = parent_expr;
+ bin_expr = parent_expr;
}
_ => break,
}
}
- let mut expr_stack = vec![expr.clone()];
- let mut terms = Vec::new();
- let mut op_ranges = Vec::new();
-
- // Find all the children with the same binary operator
- while let Some(expr) = expr_stack.pop() {
- let mut traverse_bin_expr_arm = |expr| {
- if let ast::Expr::BinExpr(bin_expr) = expr {
- if let Some(expr_op) = bin_expr.op_kind() {
- if expr_op == op {
- expr_stack.push(bin_expr);
- } else {
- terms.push(ast::Expr::BinExpr(bin_expr));
- }
+ let op = bin_expr.op_kind()?;
+ let inv_token = match op {
+ ast::BinaryOp::LogicOp(ast::LogicOp::And) => SyntaxKind::PIPE2,
+ ast::BinaryOp::LogicOp(ast::LogicOp::Or) => SyntaxKind::AMP2,
+ _ => return None,
+ };
+
+ let demorganed = bin_expr.clone_subtree().clone_for_update();
+
+ ted::replace(demorganed.op_token()?, ast::make::token(inv_token));
+ let mut exprs = VecDeque::from(vec![
+ (bin_expr.lhs()?, demorganed.lhs()?),
+ (bin_expr.rhs()?, demorganed.rhs()?),
+ ]);
+
+ while let Some((expr, dm)) = exprs.pop_front() {
+ if let BinExpr(bin_expr) = &expr {
+ if let BinExpr(cbin_expr) = &dm {
+ if op == bin_expr.op_kind()? {
+ ted::replace(cbin_expr.op_token()?, ast::make::token(inv_token));
+ exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?));
+ exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?));
} else {
- terms.push(ast::Expr::BinExpr(bin_expr));
+ let mut inv = invert_boolean_expression(expr);
+ if inv.needs_parens_in(dm.syntax().parent()?) {
+ inv = ast::make::expr_paren(inv).clone_for_update();
+ }
+ ted::replace(dm.syntax(), inv.syntax());
}
} else {
- terms.push(expr);
+ return None;
}
- };
-
- op_ranges.extend(expr.op_token().map(|t| t.text_range()));
- traverse_bin_expr_arm(expr.lhs()?);
- traverse_bin_expr_arm(expr.rhs()?);
+ } else {
+ let mut inv = invert_boolean_expression(dm.clone_subtree()).clone_for_update();
+ if inv.needs_parens_in(dm.syntax().parent()?) {
+ inv = ast::make::expr_paren(inv).clone_for_update();
+ }
+ ted::replace(dm.syntax(), inv.syntax());
+ }
}
+ let dm_lhs = demorganed.lhs()?;
+
acc.add(
AssistId("apply_demorgan", AssistKind::RefactorRewrite),
"Apply De Morgan's law",
op_range,
|edit| {
- terms.sort_by_key(|t| t.syntax().text_range().start());
- let mut terms = VecDeque::from(terms);
-
- let paren_expr = expr.syntax().parent().and_then(ast::ParenExpr::cast);
-
+ let paren_expr = bin_expr.syntax().parent().and_then(ast::ParenExpr::cast);
let neg_expr = paren_expr
.clone()
.and_then(|paren_expr| paren_expr.syntax().parent())
.and_then(ast::PrefixExpr::cast)
.and_then(|prefix_expr| {
- if prefix_expr.op_kind().unwrap() == ast::UnaryOp::Not {
+ if prefix_expr.op_kind()? == ast::UnaryOp::Not {
Some(prefix_expr)
} else {
None
}
});
- for op_range in op_ranges {
- edit.replace(op_range, opposite_op);
- }
-
if let Some(paren_expr) = paren_expr {
- for term in terms {
- let range = term.syntax().text_range();
- let not_term = invert_boolean_expression(term);
-
- edit.replace(range, not_term.syntax().text());
- }
-
if let Some(neg_expr) = neg_expr {
cov_mark::hit!(demorgan_double_negation);
- edit.replace(neg_expr.op_token().unwrap().text_range(), "");
+ edit.replace_ast(ast::Expr::PrefixExpr(neg_expr), demorganed.into());
} else {
cov_mark::hit!(demorgan_double_parens);
- edit.replace(paren_expr.l_paren_token().unwrap().text_range(), "!(");
+ ted::insert_all_raw(
+ Position::before(dm_lhs.syntax()),
+ vec![
+ syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::BANG)),
+ syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::L_PAREN)),
+ ],
+ );
+
+ ted::append_child_raw(
+ demorganed.syntax(),
+ syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::R_PAREN)),
+ );
+
+ edit.replace_ast(ast::Expr::ParenExpr(paren_expr), demorganed.into());
}
} else {
- if let Some(lhs) = terms.pop_front() {
- let lhs_range = lhs.syntax().text_range();
- let not_lhs = invert_boolean_expression(lhs);
-
- edit.replace(lhs_range, format!("!({not_lhs}"));
- }
-
- if let Some(rhs) = terms.pop_back() {
- let rhs_range = rhs.syntax().text_range();
- let not_rhs = invert_boolean_expression(rhs);
-
- edit.replace(rhs_range, format!("{not_rhs})"));
- }
-
- for term in terms {
- let term_range = term.syntax().text_range();
- let not_term = invert_boolean_expression(term);
- edit.replace(term_range, not_term.to_string());
- }
+ ted::insert_all_raw(
+ Position::before(dm_lhs.syntax()),
+ vec![
+ syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::BANG)),
+ syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::L_PAREN)),
+ ],
+ );
+ ted::append_child_raw(demorganed.syntax(), ast::make::token(SyntaxKind::R_PAREN));
+ edit.replace_ast(bin_expr, demorganed);
}
},
)
@@ -145,9 +145,8 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
#[cfg(test)]
mod tests {
- use crate::tests::{check_assist, check_assist_not_applicable};
-
use super::*;
+ use crate::tests::{check_assist, check_assist_not_applicable};
#[test]
fn demorgan_handles_leq() {
@@ -213,7 +212,7 @@ fn f() { !(S <= S || S < S) }
#[test]
fn demorgan_doesnt_double_negation() {
cov_mark::check!(demorgan_double_negation);
- check_assist(apply_demorgan, "fn f() { !(x ||$0 x) }", "fn f() { (!x && !x) }")
+ check_assist(apply_demorgan, "fn f() { !(x ||$0 x) }", "fn f() { !x && !x }")
}
#[test]
@@ -222,13 +221,38 @@ fn f() { !(S <= S || S < S) }
check_assist(apply_demorgan, "fn f() { (x ||$0 x) }", "fn f() { !(!x && !x) }")
}
- // https://github.com/rust-lang/rust-analyzer/issues/10963
+ // FIXME : This needs to go.
+ // // https://github.com/rust-lang/rust-analyzer/issues/10963
+ // #[test]
+ // fn demorgan_doesnt_hang() {
+ // check_assist(
+ // apply_demorgan,
+ // "fn f() { 1 || 3 &&$0 4 || 5 }",
+ // "fn f() { !(!1 || !3 || !4) || 5 }",
+ // )
+ // }
+
+ #[test]
+ fn demorgan_keep_pars_for_op_precedence() {
+ check_assist(
+ apply_demorgan,
+ "fn main() {
+ let _ = !(!a ||$0 !(b || c));
+}
+",
+ "fn main() {
+ let _ = a && (b || c);
+}
+",
+ );
+ }
+
#[test]
- fn demorgan_doesnt_hang() {
+ fn demorgan_removes_pars_in_eq_precedence() {
check_assist(
apply_demorgan,
- "fn f() { 1 || 3 &&$0 4 || 5 }",
- "fn f() { !(!1 || !3 || !4) || 5 }",
+ "fn() { let x = a && !(!b |$0| !c); }",
+ "fn() { let x = a && b && c; }",
)
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs
new file mode 100644
index 000000000..45c1f0cca
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bind_unused_param.rs
@@ -0,0 +1,159 @@
+use crate::assist_context::{AssistContext, Assists};
+use ide_db::{
+ assists::{AssistId, AssistKind},
+ defs::Definition,
+ LineIndexDatabase,
+};
+use syntax::{
+ ast::{self, edit_in_place::Indent},
+ AstNode,
+};
+
+// Assist: bind_unused_param
+//
+// Binds unused function parameter to an underscore.
+//
+// ```
+// fn some_function(x: i32$0) {}
+// ```
+// ->
+// ```
+// fn some_function(x: i32) {
+// let _ = x;
+// }
+// ```
+pub(crate) fn bind_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+ let param: ast::Param = ctx.find_node_at_offset()?;
+
+ let Some(ast::Pat::IdentPat(ident_pat)) = param.pat() else { return None };
+
+ let param_def = {
+ let local = ctx.sema.to_def(&ident_pat)?;
+ Definition::Local(local)
+ };
+ if param_def.usages(&ctx.sema).at_least_one() {
+ cov_mark::hit!(keep_used);
+ return None;
+ }
+
+ let func = param.syntax().ancestors().find_map(ast::Fn::cast)?;
+ let stmt_list = func.body()?.stmt_list()?;
+ let l_curly_range = stmt_list.l_curly_token()?.text_range();
+ let r_curly_range = stmt_list.r_curly_token()?.text_range();
+
+ acc.add(
+ AssistId("bind_unused_param", AssistKind::QuickFix),
+ &format!("Bind as `let _ = {};`", &ident_pat),
+ param.syntax().text_range(),
+ |builder| {
+ let line_index = ctx.db().line_index(ctx.file_id());
+
+ let indent = func.indent_level();
+ let text_indent = indent + 1;
+ let mut text = format!("\n{text_indent}let _ = {ident_pat};");
+
+ let left_line = line_index.line_col(l_curly_range.end()).line;
+ let right_line = line_index.line_col(r_curly_range.start()).line;
+
+ if left_line == right_line {
+ cov_mark::hit!(single_line);
+ text.push_str(&format!("\n{indent}"));
+ }
+
+ builder.insert(l_curly_range.end(), text);
+ },
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::{check_assist, check_assist_not_applicable};
+
+ use super::*;
+
+ #[test]
+ fn bind_unused_empty_block() {
+ cov_mark::check!(single_line);
+ check_assist(
+ bind_unused_param,
+ r#"
+fn foo($0y: i32) {}
+"#,
+ r#"
+fn foo(y: i32) {
+ let _ = y;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn bind_unused_empty_block_with_newline() {
+ check_assist(
+ bind_unused_param,
+ r#"
+fn foo($0y: i32) {
+}
+"#,
+ r#"
+fn foo(y: i32) {
+ let _ = y;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn bind_unused_generic() {
+ check_assist(
+ bind_unused_param,
+ r#"
+fn foo<T>($0y: T)
+where T : Default {
+}
+"#,
+ r#"
+fn foo<T>(y: T)
+where T : Default {
+ let _ = y;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn trait_impl() {
+ check_assist(
+ bind_unused_param,
+ r#"
+trait Trait {
+ fn foo(x: i32);
+}
+impl Trait for () {
+ fn foo($0x: i32) {}
+}
+"#,
+ r#"
+trait Trait {
+ fn foo(x: i32);
+}
+impl Trait for () {
+ fn foo(x: i32) {
+ let _ = x;
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn keep_used() {
+ cov_mark::check!(keep_used);
+ check_assist_not_applicable(
+ bind_unused_param,
+ r#"
+fn foo(x: i32, $0y: i32) { y; }
+"#,
+ );
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
index 1af52c592..d231708c5 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
@@ -103,7 +103,6 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
cond,
ast::Expr::BinExpr(_)
| ast::Expr::BlockExpr(_)
- | ast::Expr::BoxExpr(_)
| ast::Expr::BreakExpr(_)
| ast::Expr::CastExpr(_)
| ast::Expr::ClosureExpr(_)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
index fe1cb6fce..76f021ed9 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
@@ -161,9 +161,9 @@ fn process_struct_name_reference(
let path_segment = name_ref.syntax().parent().and_then(ast::PathSegment::cast)?;
// A `PathSegment` always belongs to a `Path`, so there's at least one `Path` at this point.
let full_path =
- path_segment.syntax().parent()?.ancestors().map_while(ast::Path::cast).last().unwrap();
+ path_segment.syntax().parent()?.ancestors().map_while(ast::Path::cast).last()?;
- if full_path.segment().unwrap().name_ref()? != *name_ref {
+ if full_path.segment()?.name_ref()? != *name_ref {
// `name_ref` isn't the last segment of the path, so `full_path` doesn't point to the
// struct we want to edit.
return None;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
index dcb96ab8a..7d0e42476 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
@@ -58,7 +58,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
return None;
}
- let bound_ident = pat.fields().next().unwrap();
+ let bound_ident = pat.fields().next()?;
if !ast::IdentPat::can_cast(bound_ident.syntax().kind()) {
return None;
}
@@ -108,6 +108,15 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
then_block.syntax().last_child_or_token().filter(|t| t.kind() == T!['}'])?;
+ let then_block_items = then_block.dedent(IndentLevel(1)).clone_for_update();
+
+ let end_of_then = then_block_items.syntax().last_child_or_token()?;
+ let end_of_then = if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {
+ end_of_then.prev_sibling_or_token()?
+ } else {
+ end_of_then
+ };
+
let target = if_expr.syntax().text_range();
acc.add(
AssistId("convert_to_guarded_return", AssistKind::RefactorRewrite),
@@ -141,16 +150,6 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
}
};
- let then_block_items = then_block.dedent(IndentLevel(1)).clone_for_update();
-
- let end_of_then = then_block_items.syntax().last_child_or_token().unwrap();
- let end_of_then =
- if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {
- end_of_then.prev_sibling_or_token().unwrap()
- } else {
- end_of_then
- };
-
let then_statements = replacement
.children_with_tokens()
.chain(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs
index 4f3b6e0c2..31a1ff496 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs
@@ -15,26 +15,13 @@ use syntax::{ast, AstNode, AstToken, NodeOrToken, SyntaxKind::COMMA, TextRange};
// Move an expression out of a format string.
//
// ```
-// macro_rules! format_args {
-// ($lit:literal $(tt:tt)*) => { 0 },
-// }
-// macro_rules! print {
-// ($($arg:tt)*) => (std::io::_print(format_args!($($arg)*)));
-// }
-//
+// # //- minicore: fmt
// fn main() {
// print!("{var} {x + 1}$0");
// }
// ```
// ->
// ```
-// macro_rules! format_args {
-// ($lit:literal $(tt:tt)*) => { 0 },
-// }
-// macro_rules! print {
-// ($($arg:tt)*) => (std::io::_print(format_args!($($arg)*)));
-// }
-//
// fn main() {
// print!("{var} {}"$0, x + 1);
// }
@@ -48,7 +35,7 @@ pub(crate) fn extract_expressions_from_format_string(
let tt = fmt_string.syntax().parent().and_then(ast::TokenTree::cast)?;
let expanded_t = ast::String::cast(
- ctx.sema.descend_into_macros_with_kind_preference(fmt_string.syntax().clone()),
+ ctx.sema.descend_into_macros_with_kind_preference(fmt_string.syntax().clone(), 0.into()),
)?;
if !is_format_string(&expanded_t) {
return None;
@@ -158,37 +145,21 @@ mod tests {
use super::*;
use crate::tests::check_assist;
- const MACRO_DECL: &'static str = r#"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
-macro_rules! print {
- ($($arg:tt)*) => (std::io::_print(format_args!($($arg)*)));
-}
-"#;
-
- fn add_macro_decl(s: &'static str) -> String {
- MACRO_DECL.to_string() + s
- }
-
#[test]
fn multiple_middle_arg() {
check_assist(
extract_expressions_from_format_string,
- &add_macro_decl(
- r#"
+ r#"
+//- minicore: fmt
fn main() {
print!("{} {x + 1:b} {}$0", y + 2, 2);
}
"#,
- ),
- &add_macro_decl(
- r#"
+ r#"
fn main() {
print!("{} {:b} {}"$0, y + 2, x + 1, 2);
}
"#,
- ),
);
}
@@ -196,20 +167,17 @@ fn main() {
fn single_arg() {
check_assist(
extract_expressions_from_format_string,
- &add_macro_decl(
- r#"
+ r#"
+//- minicore: fmt
fn main() {
print!("{obj.value:b}$0",);
}
"#,
- ),
- &add_macro_decl(
- r#"
+ r#"
fn main() {
print!("{:b}"$0, obj.value);
}
"#,
- ),
);
}
@@ -217,20 +185,17 @@ fn main() {
fn multiple_middle_placeholders_arg() {
check_assist(
extract_expressions_from_format_string,
- &add_macro_decl(
- r#"
+ r#"
+//- minicore: fmt
fn main() {
print!("{} {x + 1:b} {} {}$0", y + 2, 2);
}
"#,
- ),
- &add_macro_decl(
- r#"
+ r#"
fn main() {
print!("{} {:b} {} {}"$0, y + 2, x + 1, 2, $1);
}
"#,
- ),
);
}
@@ -238,20 +203,17 @@ fn main() {
fn multiple_trailing_args() {
check_assist(
extract_expressions_from_format_string,
- &add_macro_decl(
- r#"
+ r#"
+//- minicore: fmt
fn main() {
print!("{:b} {x + 1:b} {Struct(1, 2)}$0", 1);
}
"#,
- ),
- &add_macro_decl(
- r#"
+ r#"
fn main() {
print!("{:b} {:b} {}"$0, 1, x + 1, Struct(1, 2));
}
"#,
- ),
);
}
@@ -259,20 +221,17 @@ fn main() {
fn improper_commas() {
check_assist(
extract_expressions_from_format_string,
- &add_macro_decl(
- r#"
+ r#"
+//- minicore: fmt
fn main() {
print!("{} {x + 1:b} {Struct(1, 2)}$0", 1,);
}
"#,
- ),
- &add_macro_decl(
- r#"
+ r#"
fn main() {
print!("{} {:b} {}"$0, 1, x + 1, Struct(1, 2));
}
"#,
- ),
);
}
@@ -280,20 +239,17 @@ fn main() {
fn nested_tt() {
check_assist(
extract_expressions_from_format_string,
- &add_macro_decl(
- r#"
+ r#"
+//- minicore: fmt
fn main() {
print!("My name is {} {x$0 + x}", stringify!(Paperino))
}
"#,
- ),
- &add_macro_decl(
- r#"
+ r#"
fn main() {
print!("My name is {} {}"$0, stringify!(Paperino), x + x)
}
"#,
- ),
);
}
@@ -301,22 +257,19 @@ fn main() {
fn extract_only_expressions() {
check_assist(
extract_expressions_from_format_string,
- &add_macro_decl(
- r#"
+ r#"
+//- minicore: fmt
fn main() {
let var = 1 + 1;
print!("foobar {var} {var:?} {x$0 + x}")
}
"#,
- ),
- &add_macro_decl(
- r#"
+ r#"
fn main() {
let var = 1 + 1;
print!("foobar {var} {var:?} {}"$0, x + x)
}
"#,
- ),
);
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index b8b781ea4..de591cfde 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -531,7 +531,7 @@ impl FunctionBody {
fn extracted_from_trait_impl(&self) -> bool {
match self.node().ancestors().find_map(ast::Impl::cast) {
- Some(c) => return c.trait_().is_some(),
+ Some(c) => c.trait_().is_some(),
None => false,
}
}
@@ -750,7 +750,7 @@ impl FunctionBody {
.descendants_with_tokens()
.filter_map(SyntaxElement::into_token)
.filter(|it| matches!(it.kind(), SyntaxKind::IDENT | T![self]))
- .flat_map(|t| sema.descend_into_macros(t))
+ .flat_map(|t| sema.descend_into_macros(t, 0.into()))
.for_each(|t| add_name_if_local(t.parent().and_then(ast::NameRef::cast)));
}
}
@@ -810,7 +810,7 @@ impl FunctionBody {
(true, konst.body(), Some(sema.to_def(&konst)?.ty(sema.db)))
},
ast::ConstParam(cp) => {
- (true, cp.default_val(), Some(sema.to_def(&cp)?.ty(sema.db)))
+ (true, cp.default_val()?.expr(), Some(sema.to_def(&cp)?.ty(sema.db)))
},
ast::ConstBlockPat(cbp) => {
let expr = cbp.block_expr().map(ast::Expr::BlockExpr);
@@ -1048,23 +1048,17 @@ impl GenericParent {
fn generic_parents(parent: &SyntaxNode) -> Vec<GenericParent> {
let mut list = Vec::new();
if let Some(parent_item) = parent.ancestors().find_map(ast::Item::cast) {
- match parent_item {
- ast::Item::Fn(ref fn_) => {
- if let Some(parent_parent) = parent_item
- .syntax()
- .parent()
- .and_then(|it| it.parent())
- .and_then(ast::Item::cast)
- {
- match parent_parent {
- ast::Item::Impl(impl_) => list.push(GenericParent::Impl(impl_)),
- ast::Item::Trait(trait_) => list.push(GenericParent::Trait(trait_)),
- _ => (),
- }
+ if let ast::Item::Fn(ref fn_) = parent_item {
+ if let Some(parent_parent) =
+ parent_item.syntax().parent().and_then(|it| it.parent()).and_then(ast::Item::cast)
+ {
+ match parent_parent {
+ ast::Item::Impl(impl_) => list.push(GenericParent::Impl(impl_)),
+ ast::Item::Trait(trait_) => list.push(GenericParent::Trait(trait_)),
+ _ => (),
}
- list.push(GenericParent::Fn(fn_.clone()));
}
- _ => (),
+ list.push(GenericParent::Fn(fn_.clone()));
}
}
list
@@ -1385,31 +1379,30 @@ enum FlowHandler {
impl FlowHandler {
fn from_ret_ty(fun: &Function, ret_ty: &FunType) -> FlowHandler {
- match &fun.control_flow.kind {
- None => FlowHandler::None,
- Some(flow_kind) => {
- let action = flow_kind.clone();
- if let FunType::Unit = ret_ty {
- match flow_kind {
- FlowKind::Return(None)
- | FlowKind::Break(_, None)
- | FlowKind::Continue(_) => FlowHandler::If { action },
- FlowKind::Return(_) | FlowKind::Break(_, _) => {
- FlowHandler::IfOption { action }
- }
- FlowKind::Try { kind } => FlowHandler::Try { kind: kind.clone() },
- }
- } else {
- match flow_kind {
- FlowKind::Return(None)
- | FlowKind::Break(_, None)
- | FlowKind::Continue(_) => FlowHandler::MatchOption { none: action },
- FlowKind::Return(_) | FlowKind::Break(_, _) => {
- FlowHandler::MatchResult { err: action }
- }
- FlowKind::Try { kind } => FlowHandler::Try { kind: kind.clone() },
- }
+ if fun.contains_tail_expr {
+ return FlowHandler::None;
+ }
+ let Some(action) = fun.control_flow.kind.clone() else {
+ return FlowHandler::None;
+ };
+
+ if let FunType::Unit = ret_ty {
+ match action {
+ FlowKind::Return(None) | FlowKind::Break(_, None) | FlowKind::Continue(_) => {
+ FlowHandler::If { action }
+ }
+ FlowKind::Return(_) | FlowKind::Break(_, _) => FlowHandler::IfOption { action },
+ FlowKind::Try { kind } => FlowHandler::Try { kind },
+ }
+ } else {
+ match action {
+ FlowKind::Return(None) | FlowKind::Break(_, None) | FlowKind::Continue(_) => {
+ FlowHandler::MatchOption { none: action }
+ }
+ FlowKind::Return(_) | FlowKind::Break(_, _) => {
+ FlowHandler::MatchResult { err: action }
}
+ FlowKind::Try { kind } => FlowHandler::Try { kind },
}
}
}
@@ -1654,11 +1647,7 @@ impl Function {
fn make_ret_ty(&self, ctx: &AssistContext<'_>, module: hir::Module) -> Option<ast::RetType> {
let fun_ty = self.return_type(ctx);
- let handler = if self.contains_tail_expr {
- FlowHandler::None
- } else {
- FlowHandler::from_ret_ty(self, &fun_ty)
- };
+ let handler = FlowHandler::from_ret_ty(self, &fun_ty);
let ret_ty = match &handler {
FlowHandler::None => {
if matches!(fun_ty, FunType::Unit) {
@@ -1728,16 +1717,12 @@ fn make_body(
fun: &Function,
) -> ast::BlockExpr {
let ret_ty = fun.return_type(ctx);
- let handler = if fun.contains_tail_expr {
- FlowHandler::None
- } else {
- FlowHandler::from_ret_ty(fun, &ret_ty)
- };
+ let handler = FlowHandler::from_ret_ty(fun, &ret_ty);
let block = match &fun.body {
FunctionBody::Expr(expr) => {
let expr = rewrite_body_segment(ctx, &fun.params, &handler, expr.syntax());
- let expr = ast::Expr::cast(expr).unwrap();
+ let expr = ast::Expr::cast(expr).expect("Body segment should be an expr");
match expr {
ast::Expr::BlockExpr(block) => {
// If the extracted expression is itself a block, there is no need to wrap it inside another block.
@@ -1877,9 +1862,8 @@ fn with_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr
if let Some(stmt_list) = block.stmt_list() {
stmt_list.syntax().children_with_tokens().for_each(|node_or_token| {
- match &node_or_token {
- syntax::NodeOrToken::Token(_) => elements.push(node_or_token),
- _ => (),
+ if let syntax::NodeOrToken::Token(_) = &node_or_token {
+ elements.push(node_or_token)
};
});
}
@@ -1943,12 +1927,18 @@ fn fix_param_usages(ctx: &AssistContext<'_>, params: &[Param], syntax: &SyntaxNo
Some(ast::Expr::RefExpr(node))
if param.kind() == ParamKind::MutRef && node.mut_token().is_some() =>
{
- ted::replace(node.syntax(), node.expr().unwrap().syntax());
+ ted::replace(
+ node.syntax(),
+ node.expr().expect("RefExpr::expr() cannot be None").syntax(),
+ );
}
Some(ast::Expr::RefExpr(node))
if param.kind() == ParamKind::SharedRef && node.mut_token().is_none() =>
{
- ted::replace(node.syntax(), node.expr().unwrap().syntax());
+ ted::replace(
+ node.syntax(),
+ node.expr().expect("RefExpr::expr() cannot be None").syntax(),
+ );
}
Some(_) | None => {
let p = &make::expr_prefix(T![*], usage.clone()).clone_for_update();
@@ -4471,7 +4461,7 @@ async fn foo() -> Result<(), ()> {
"#,
r#"
async fn foo() -> Result<(), ()> {
- fun_name().await?
+ fun_name().await
}
async fn $0fun_name() -> Result<(), ()> {
@@ -4690,7 +4680,7 @@ fn $0fun_name() {
check_assist(
extract_function,
r#"
-//- minicore: result
+//- minicore: result, try
fn foo() -> Result<(), i64> {
$0Result::<i32, i64>::Ok(0)?;
Ok(())$0
@@ -4698,7 +4688,7 @@ fn foo() -> Result<(), i64> {
"#,
r#"
fn foo() -> Result<(), i64> {
- fun_name()?
+ fun_name()
}
fn $0fun_name() -> Result<(), i64> {
@@ -5754,6 +5744,34 @@ fn $0fun_name<T, V>(t: T, v: V) -> i32 where T: Into<i32> + Copy, V: Into<i32> {
}
#[test]
+ fn tail_expr_no_extra_control_flow() {
+ check_assist(
+ extract_function,
+ r#"
+//- minicore: result
+fn fallible() -> Result<(), ()> {
+ $0if true {
+ return Err(());
+ }
+ Ok(())$0
+}
+"#,
+ r#"
+fn fallible() -> Result<(), ()> {
+ fun_name()
+}
+
+fn $0fun_name() -> Result<(), ()> {
+ if true {
+ return Err(());
+ }
+ Ok(())
+}
+"#,
+ );
+ }
+
+ #[test]
fn non_tail_expr_of_tail_expr_loop() {
check_assist(
extract_function,
@@ -5800,12 +5818,6 @@ fn $0fun_name() -> ControlFlow<()> {
extract_function,
r#"
//- minicore: option, try
-impl<T> core::ops::Try for Option<T> {
- type Output = T;
- type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
fn f() -> Option<()> {
if true {
let a = $0if true {
@@ -5820,12 +5832,6 @@ fn f() -> Option<()> {
}
"#,
r#"
-impl<T> core::ops::Try for Option<T> {
- type Output = T;
- type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
fn f() -> Option<()> {
if true {
let a = fun_name()?;;
@@ -5852,12 +5858,6 @@ fn $0fun_name() -> Option<()> {
extract_function,
r#"
//- minicore: option, try
-impl<T> core::ops::Try for Option<T> {
- type Output = T;
- type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
fn f() -> Option<()> {
if true {
$0{
@@ -5874,15 +5874,9 @@ fn f() -> Option<()> {
}
"#,
r#"
-impl<T> core::ops::Try for Option<T> {
- type Output = T;
- type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
fn f() -> Option<()> {
if true {
- fun_name()?
+ fun_name()
} else {
None
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
index 31fc69562..bbac0a26e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
@@ -95,6 +95,9 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
let Some(impl_def) = find_struct_impl(ctx, &adt, std::slice::from_ref(&name)) else {
continue;
};
+
+ let field = make::ext::field_from_idents(["self", &field_name])?;
+
acc.add_group(
&GroupLabel("Generate delegate methods…".to_owned()),
AssistId("generate_delegate_methods", AssistKind::Generate),
@@ -115,11 +118,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
Some(list) => convert_param_list_to_arg_list(list),
None => make::arg_list([]),
};
- let tail_expr = make::expr_method_call(
- make::ext::field_from_idents(["self", &field_name]).unwrap(), // This unwrap is ok because we have at least 1 arg in the list
- make::name_ref(&name),
- arg_list,
- );
+ let tail_expr = make::expr_method_call(field, make::name_ref(&name), arg_list);
let ret_type = method_source.ret_type();
let is_async = method_source.async_token().is_some();
let is_const = method_source.const_token().is_some();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs
index 747f70f9f..53ba144ba 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs
@@ -27,13 +27,19 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
let cap = ctx.config.snippet_cap?;
let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
let target = nominal.syntax().text_range();
+ let derive_attr = nominal
+ .attrs()
+ .filter_map(|x| x.as_simple_call())
+ .filter(|(name, _arg)| name == "derive")
+ .map(|(_name, arg)| arg)
+ .next();
+
+ let delimiter = match &derive_attr {
+ None => None,
+ Some(tt) => Some(tt.right_delimiter_token()?),
+ };
+
acc.add(AssistId("generate_derive", AssistKind::Generate), "Add `#[derive]`", target, |edit| {
- let derive_attr = nominal
- .attrs()
- .filter_map(|x| x.as_simple_call())
- .filter(|(name, _arg)| name == "derive")
- .map(|(_name, arg)| arg)
- .next();
match derive_attr {
None => {
let derive = make::attr_outer(make::meta_token_tree(
@@ -45,16 +51,23 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
let nominal = edit.make_mut(nominal);
nominal.add_attr(derive.clone());
+ let delimiter = derive
+ .meta()
+ .expect("make::attr_outer was expected to have Meta")
+ .token_tree()
+ .expect("failed to get token tree out of Meta")
+ .r_paren_token()
+ .expect("make::attr_outer was expected to have a R_PAREN");
+
+ edit.add_tabstop_before_token(cap, delimiter);
+ }
+ Some(_) => {
+ // Just move the cursor.
edit.add_tabstop_before_token(
cap,
- derive.meta().unwrap().token_tree().unwrap().r_paren_token().unwrap(),
+ delimiter.expect("Right delim token could not be found."),
);
}
- Some(tt) => {
- // Just move the cursor.
- let tt = edit.make_mut(tt);
- edit.add_tabstop_before_token(cap, tt.right_delimiter_token().unwrap());
- }
};
})
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs
new file mode 100644
index 000000000..663df266b
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/into_to_qualified_from.rs
@@ -0,0 +1,205 @@
+use hir::{AsAssocItem, HirDisplay};
+use ide_db::{
+ assists::{AssistId, AssistKind},
+ famous_defs::FamousDefs,
+};
+use syntax::{ast, AstNode};
+
+use crate::assist_context::{AssistContext, Assists};
+
+// Assist: into_to_qualified_from
+//
+// Convert an `into` method call to a fully qualified `from` call.
+//
+// ```
+// //- minicore: from
+// struct B;
+// impl From<i32> for B {
+// fn from(a: i32) -> Self {
+// B
+// }
+// }
+//
+// fn main() -> () {
+// let a = 3;
+// let b: B = a.in$0to();
+// }
+// ```
+// ->
+// ```
+// struct B;
+// impl From<i32> for B {
+// fn from(a: i32) -> Self {
+// B
+// }
+// }
+//
+// fn main() -> () {
+// let a = 3;
+// let b: B = B::from(a);
+// }
+// ```
+pub(crate) fn into_to_qualified_from(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+ let method_call: ast::MethodCallExpr = ctx.find_node_at_offset()?;
+ let nameref = method_call.name_ref()?;
+ let receiver = method_call.receiver()?;
+ let db = ctx.db();
+ let sema = &ctx.sema;
+ let fnc = sema.resolve_method_call(&method_call)?;
+ let scope = sema.scope(method_call.syntax())?;
+ // Check if the method call refers to Into trait.
+ if fnc.as_assoc_item(db)?.containing_trait_impl(db)?
+ == FamousDefs(sema, scope.krate()).core_convert_Into()?
+ {
+ let type_call = sema.type_of_expr(&method_call.clone().into())?;
+ let type_call_disp =
+ type_call.adjusted().display_source_code(db, scope.module().into(), true).ok()?;
+
+ acc.add(
+ AssistId("into_to_qualified_from", AssistKind::Generate),
+ "Convert `into` to fully qualified `from`",
+ nameref.syntax().text_range(),
+ |edit| {
+ edit.replace(
+ method_call.syntax().text_range(),
+ format!("{}::from({})", type_call_disp, receiver),
+ );
+ },
+ );
+ }
+
+ Some(())
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::check_assist;
+
+ use super::into_to_qualified_from;
+
+ #[test]
+ fn two_types_in_same_mod() {
+ check_assist(
+ into_to_qualified_from,
+ r#"
+//- minicore: from
+struct A;
+struct B;
+impl From<A> for B {
+ fn from(a: A) -> Self {
+ B
+ }
+}
+
+fn main() -> () {
+ let a: A = A;
+ let b: B = a.in$0to();
+}"#,
+ r#"
+struct A;
+struct B;
+impl From<A> for B {
+ fn from(a: A) -> Self {
+ B
+ }
+}
+
+fn main() -> () {
+ let a: A = A;
+ let b: B = B::from(a);
+}"#,
+ )
+ }
+
+ #[test]
+ fn fromed_in_child_mod_imported() {
+ check_assist(
+ into_to_qualified_from,
+ r#"
+//- minicore: from
+use C::B;
+
+struct A;
+
+mod C {
+ use crate::A;
+
+ pub(super) struct B;
+ impl From<A> for B {
+ fn from(a: A) -> Self {
+ B
+ }
+ }
+}
+
+fn main() -> () {
+ let a: A = A;
+ let b: B = a.in$0to();
+}"#,
+ r#"
+use C::B;
+
+struct A;
+
+mod C {
+ use crate::A;
+
+ pub(super) struct B;
+ impl From<A> for B {
+ fn from(a: A) -> Self {
+ B
+ }
+ }
+}
+
+fn main() -> () {
+ let a: A = A;
+ let b: B = B::from(a);
+}"#,
+ )
+ }
+
+ #[test]
+ fn fromed_in_child_mod_not_imported() {
+ check_assist(
+ into_to_qualified_from,
+ r#"
+//- minicore: from
+struct A;
+
+mod C {
+ use crate::A;
+
+ pub(super) struct B;
+ impl From<A> for B {
+ fn from(a: A) -> Self {
+ B
+ }
+ }
+}
+
+fn main() -> () {
+ let a: A = A;
+ let b: C::B = a.in$0to();
+}"#,
+ r#"
+struct A;
+
+mod C {
+ use crate::A;
+
+ pub(super) struct B;
+ impl From<A> for B {
+ fn from(a: A) -> Self {
+ B
+ }
+ }
+}
+
+fn main() -> () {
+ let a: A = A;
+ let b: C::B = C::B::from(a);
+}"#,
+ )
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs
index 5cc110cf1..6ed9bd85f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/promote_local_to_const.rs
@@ -76,12 +76,19 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>)
let name = to_upper_snake_case(&name.to_string());
let usages = Definition::Local(local).usages(&ctx.sema).all();
if let Some(usages) = usages.references.get(&ctx.file_id()) {
- let name = make::name_ref(&name);
+ let name_ref = make::name_ref(&name);
for usage in usages {
let Some(usage) = usage.name.as_name_ref().cloned() else { continue };
- let usage = edit.make_mut(usage);
- ted::replace(usage.syntax(), name.clone_for_update().syntax());
+ if let Some(record_field) = ast::RecordExprField::for_name_ref(&usage) {
+ let record_field = edit.make_mut(record_field);
+ let name_expr =
+ make::expr_path(make::path_from_text(&name)).clone_for_update();
+ record_field.replace_expr(name_expr);
+ } else {
+ let usage = edit.make_mut(usage);
+ ted::replace(usage.syntax(), name_ref.clone_for_update().syntax());
+ }
}
}
@@ -120,8 +127,7 @@ fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bool {
is_const &=
sema.resolve_method_call(&call).map(|it| it.is_const(sema.db)).unwrap_or(true)
}
- ast::Expr::BoxExpr(_)
- | ast::Expr::ForExpr(_)
+ ast::Expr::ForExpr(_)
| ast::Expr::ReturnExpr(_)
| ast::Expr::TryExpr(_)
| ast::Expr::YieldExpr(_)
@@ -180,6 +186,33 @@ fn foo() {
}
#[test]
+ fn usage_in_field_shorthand() {
+ check_assist(
+ promote_local_to_const,
+ r"
+struct Foo {
+ bar: usize,
+}
+
+fn main() {
+ let $0bar = 0;
+ let foo = Foo { bar };
+}
+",
+ r"
+struct Foo {
+ bar: usize,
+}
+
+fn main() {
+ const $0BAR: usize = 0;
+ let foo = Foo { bar: BAR };
+}
+",
+ )
+ }
+
+ #[test]
fn not_applicable_non_const_meth_call() {
cov_mark::check!(promote_local_non_const);
check_assist_not_applicable(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
index a403d5bc6..cffa3f55c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
@@ -39,14 +39,11 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
let replacements =
macro_calls.into_iter().filter_map(compute_dbg_replacement).collect::<Vec<_>>();
- if replacements.is_empty() {
- return None;
- }
acc.add(
AssistId("remove_dbg", AssistKind::Refactor),
"Remove dbg!()",
- replacements.iter().map(|&(range, _)| range).reduce(|acc, range| acc.cover(range)).unwrap(),
+ replacements.iter().map(|&(range, _)| range).reduce(|acc, range| acc.cover(range))?,
|builder| {
for (range, expr) in replacements {
if let Some(expr) = expr {
@@ -116,10 +113,7 @@ fn compute_dbg_replacement(macro_expr: ast::MacroExpr) -> Option<(TextRange, Opt
Some(parent) => match (expr, parent) {
(ast::Expr::CastExpr(_), ast::Expr::CastExpr(_)) => false,
(
- ast::Expr::BoxExpr(_)
- | ast::Expr::PrefixExpr(_)
- | ast::Expr::RefExpr(_)
- | ast::Expr::MacroExpr(_),
+ ast::Expr::PrefixExpr(_) | ast::Expr::RefExpr(_) | ast::Expr::MacroExpr(_),
ast::Expr::AwaitExpr(_)
| ast::Expr::CallExpr(_)
| ast::Expr::CastExpr(_)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs
index dd4839351..5fcab8c02 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs
@@ -67,7 +67,7 @@ pub(crate) fn remove_unused_imports(acc: &mut Assists, ctx: &AssistContext<'_>)
// This case maps to the situation where the * token is braced.
// In this case, the parent use tree's path is the one we should use to resolve the glob.
match u.syntax().ancestors().skip(1).find_map(ast::UseTree::cast) {
- Some(parent_u) if parent_u.path().is_some() => parent_u.path().unwrap(),
+ Some(parent_u) if parent_u.path().is_some() => parent_u.path()?,
_ => return None,
}
} else {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
index 24c338745..61e9bcdcc 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
@@ -48,6 +48,11 @@ pub(crate) fn wrap_return_type_in_result(acc: &mut Assists, ctx: &AssistContext<
return None;
}
+ let new_result_ty =
+ make::ext::ty_result(type_ref.clone(), make::ty_placeholder()).clone_for_update();
+ let generic_args = new_result_ty.syntax().descendants().find_map(ast::GenericArgList::cast)?;
+ let last_genarg = generic_args.generic_args().last()?;
+
acc.add(
AssistId("wrap_return_type_in_result", AssistKind::RefactorRewrite),
"Wrap return type in Result",
@@ -75,19 +80,12 @@ pub(crate) fn wrap_return_type_in_result(acc: &mut Assists, ctx: &AssistContext<
ted::replace(ret_expr_arg.syntax(), ok_wrapped.syntax());
}
- let new_result_ty =
- make::ext::ty_result(type_ref.clone(), make::ty_placeholder()).clone_for_update();
let old_result_ty = edit.make_mut(type_ref.clone());
ted::replace(old_result_ty.syntax(), new_result_ty.syntax());
if let Some(cap) = ctx.config.snippet_cap {
- let generic_args = new_result_ty
- .syntax()
- .descendants()
- .find_map(ast::GenericArgList::cast)
- .unwrap();
- edit.add_placeholder_snippet(cap, generic_args.generic_args().last().unwrap());
+ edit.add_placeholder_snippet(cap, last_genarg);
}
},
)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
index 2ebb5ef9b..6f973ab53 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
@@ -114,6 +114,7 @@ mod handlers {
mod add_turbo_fish;
mod apply_demorgan;
mod auto_import;
+ mod bind_unused_param;
mod change_visibility;
mod convert_bool_then;
mod convert_comment_block;
@@ -211,6 +212,7 @@ mod handlers {
mod unwrap_result_return_type;
mod unqualify_method_call;
mod wrap_return_type_in_result;
+ mod into_to_qualified_from;
pub(crate) fn all() -> &'static [Handler] {
&[
@@ -224,6 +226,7 @@ mod handlers {
add_turbo_fish::add_turbo_fish,
apply_demorgan::apply_demorgan,
auto_import::auto_import,
+ bind_unused_param::bind_unused_param,
change_visibility::change_visibility,
convert_bool_then::convert_bool_then_to_if,
convert_bool_then::convert_if_to_bool_then,
@@ -274,6 +277,7 @@ mod handlers {
inline_local_variable::inline_local_variable,
inline_type_alias::inline_type_alias,
inline_type_alias::inline_type_alias_uses,
+ into_to_qualified_from::into_to_qualified_from,
introduce_named_generic::introduce_named_generic,
introduce_named_lifetime::introduce_named_lifetime,
invert_if::invert_if,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 6eadc3dbc..dfaa53449 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -266,6 +266,21 @@ pub mod std { pub mod collections { pub struct HashMap { } } }
}
#[test]
+fn doctest_bind_unused_param() {
+ check_doc_test(
+ "bind_unused_param",
+ r#####"
+fn some_function(x: i32$0) {}
+"#####,
+ r#####"
+fn some_function(x: i32) {
+ let _ = x;
+}
+"#####,
+ )
+}
+
+#[test]
fn doctest_change_visibility() {
check_doc_test(
"change_visibility",
@@ -694,25 +709,12 @@ fn doctest_extract_expressions_from_format_string() {
check_doc_test(
"extract_expressions_from_format_string",
r#####"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
-macro_rules! print {
- ($($arg:tt)*) => (std::io::_print(format_args!($($arg)*)));
-}
-
+//- minicore: fmt
fn main() {
print!("{var} {x + 1}$0");
}
"#####,
r#####"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
-macro_rules! print {
- ($($arg:tt)*) => (std::io::_print(format_args!($($arg)*)));
-}
-
fn main() {
print!("{var} {}"$0, x + 1);
}
@@ -1755,6 +1757,40 @@ fn foo() {
}
#[test]
+fn doctest_into_to_qualified_from() {
+ check_doc_test(
+ "into_to_qualified_from",
+ r#####"
+//- minicore: from
+struct B;
+impl From<i32> for B {
+ fn from(a: i32) -> Self {
+ B
+ }
+}
+
+fn main() -> () {
+ let a = 3;
+ let b: B = a.in$0to();
+}
+"#####,
+ r#####"
+struct B;
+impl From<i32> for B {
+ fn from(a: i32) -> Self {
+ B
+ }
+}
+
+fn main() -> () {
+ let a = 3;
+ let b: B = B::from(a);
+}
+"#####,
+ )
+}
+
+#[test]
fn doctest_introduce_named_generic() {
check_doc_test(
"introduce_named_generic",
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs
index f74ebfae0..16704d598 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs
@@ -103,7 +103,6 @@ pub(crate) fn for_variable(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>)
match expr {
ast::Expr::RefExpr(inner) => next_expr = inner.expr(),
- ast::Expr::BoxExpr(inner) => next_expr = inner.expr(),
ast::Expr::AwaitExpr(inner) => next_expr = inner.expr(),
// ast::Expr::BlockExpr(block) => expr = block.tail_expr(),
ast::Expr::CastExpr(inner) => next_expr = inner.expr(),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
index 480cb77b4..f60ac1501 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -20,6 +20,7 @@ pub(crate) mod r#type;
pub(crate) mod use_;
pub(crate) mod vis;
pub(crate) mod env_vars;
+pub(crate) mod extern_crate;
use std::iter;
@@ -703,7 +704,9 @@ pub(super) fn complete_name_ref(
TypeLocation::TypeAscription(ascription) => {
r#type::complete_ascribed_type(acc, ctx, path_ctx, ascription);
}
- TypeLocation::GenericArgList(_)
+ TypeLocation::GenericArg { .. }
+ | TypeLocation::AssocConstEq
+ | TypeLocation::AssocTypeEq
| TypeLocation::TypeBound
| TypeLocation::ImplTarget
| TypeLocation::ImplTrait
@@ -737,6 +740,7 @@ pub(super) fn complete_name_ref(
}
}
}
+ NameRefKind::ExternCrate => extern_crate::complete_extern_crate(acc, ctx),
NameRefKind::DotAccess(dot_access) => {
flyimport::import_on_the_fly_dot(acc, ctx, dot_access);
dot::complete_dot(acc, ctx, dot_access);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs
index 62bdb6ee6..87a286778 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs
@@ -1,10 +1,8 @@
//! Completion for cfg
-use std::iter;
-
use ide_db::SymbolKind;
use itertools::Itertools;
-use syntax::SyntaxKind;
+use syntax::{algo, ast::Ident, AstToken, Direction, NodeOrToken, SyntaxKind};
use crate::{completions::Completions, context::CompletionContext, CompletionItem};
@@ -15,31 +13,44 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
acc.add(completion.build(ctx.db));
};
- let previous = iter::successors(ctx.original_token.prev_token(), |t| {
- (matches!(t.kind(), SyntaxKind::EQ) || t.kind().is_trivia())
- .then(|| t.prev_token())
- .flatten()
- })
- .find(|t| matches!(t.kind(), SyntaxKind::IDENT));
-
- match previous.as_ref().map(|p| p.text()) {
- Some("target_arch") => KNOWN_ARCH.iter().copied().for_each(add_completion),
- Some("target_env") => KNOWN_ENV.iter().copied().for_each(add_completion),
- Some("target_os") => KNOWN_OS.iter().copied().for_each(add_completion),
- Some("target_vendor") => KNOWN_VENDOR.iter().copied().for_each(add_completion),
- Some("target_endian") => ["little", "big"].into_iter().for_each(add_completion),
- Some(name) => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).cloned().for_each(|s| {
- let insert_text = format!(r#""{s}""#);
- let mut item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
- item.insert_text(insert_text);
+ // FIXME: Move this into context/analysis.rs
+ let previous = ctx
+ .original_token
+ .prev_token()
+ .and_then(|it| {
+ if matches!(it.kind(), SyntaxKind::EQ) {
+ Some(it.into())
+ } else {
+ algo::non_trivia_sibling(it.into(), Direction::Prev)
+ }
+ })
+ .filter(|t| matches!(t.kind(), SyntaxKind::EQ))
+ .and_then(|it| algo::non_trivia_sibling(it.prev_sibling_or_token()?, Direction::Prev))
+ .map(|it| match it {
+ NodeOrToken::Node(_) => None,
+ NodeOrToken::Token(t) => Ident::cast(t),
+ });
+ match previous {
+ Some(None) => (),
+ Some(Some(p)) => match p.text() {
+ "target_arch" => KNOWN_ARCH.iter().copied().for_each(add_completion),
+ "target_env" => KNOWN_ENV.iter().copied().for_each(add_completion),
+ "target_os" => KNOWN_OS.iter().copied().for_each(add_completion),
+ "target_vendor" => KNOWN_VENDOR.iter().copied().for_each(add_completion),
+ "target_endian" => ["little", "big"].into_iter().for_each(add_completion),
+ name => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).cloned().for_each(|s| {
+ let insert_text = format!(r#""{s}""#);
+ let mut item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
+ item.insert_text(insert_text);
- acc.add(item.build(ctx.db));
- }),
+ acc.add(item.build(ctx.db));
+ }),
+ },
None => ctx.krate.potential_cfg(ctx.db).get_cfg_keys().cloned().unique().for_each(|s| {
let item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
acc.add(item.build(ctx.db));
}),
- };
+ }
}
const KNOWN_ARCH: [&str; 20] = [
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs
index 9447bc7db..90dac1902 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/derive.rs
@@ -1,6 +1,6 @@
//! Completion for derives
-use hir::{HasAttrs, ScopeDef};
-use ide_db::SymbolKind;
+use hir::ScopeDef;
+use ide_db::{documentation::HasDocs, SymbolKind};
use itertools::Itertools;
use syntax::SmolStr;
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs
index 6bc6f34ed..f9dec5380 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/lint.rs
@@ -1,5 +1,5 @@
//! Completion for lints
-use ide_db::{generated::lints::Lint, SymbolKind};
+use ide_db::{documentation::Documentation, generated::lints::Lint, SymbolKind};
use syntax::ast;
use crate::{context::CompletionContext, item::CompletionItem, Completions};
@@ -55,7 +55,7 @@ pub(super) fn complete_lint(
_ => name.to_owned(),
};
let mut item = CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), label);
- item.documentation(hir::Documentation::new(description.to_owned()));
+ item.documentation(Documentation::new(description.to_owned()));
item.add_to(acc, ctx.db)
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs
new file mode 100644
index 000000000..f9cde4466
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs
@@ -0,0 +1,71 @@
+//! Completion for extern crates
+
+use hir::Name;
+use ide_db::{documentation::HasDocs, SymbolKind};
+
+use crate::{context::CompletionContext, CompletionItem, CompletionItemKind};
+
+use super::Completions;
+
+pub(crate) fn complete_extern_crate(acc: &mut Completions, ctx: &CompletionContext<'_>) {
+ let imported_extern_crates: Vec<Name> = ctx.scope.extern_crate_decls().collect();
+
+ for (name, module) in ctx.scope.extern_crates() {
+ if imported_extern_crates.contains(&name) {
+ continue;
+ }
+
+ let mut item = CompletionItem::new(
+ CompletionItemKind::SymbolKind(SymbolKind::Module),
+ ctx.source_range(),
+ name.to_smol_str(),
+ );
+ item.set_documentation(module.docs(ctx.db));
+
+ item.add_to(acc, ctx.db);
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::tests::completion_list_no_kw;
+
+ #[test]
+ fn can_complete_extern_crate() {
+ let case = r#"
+//- /lib.rs crate:other_crate_a
+// nothing here
+//- /other_crate_b.rs crate:other_crate_b
+pub mod good_mod{}
+//- /lib.rs crate:crate_c
+// nothing here
+//- /lib.rs crate:lib deps:other_crate_a,other_crate_b,crate_c extern-prelude:other_crate_a
+extern crate oth$0
+mod other_mod {}
+"#;
+
+ let completion_list = completion_list_no_kw(case);
+
+ assert_eq!("md other_crate_a\n".to_string(), completion_list);
+ }
+
+ #[test]
+ fn will_not_complete_existing_import() {
+ let case = r#"
+//- /lib.rs crate:other_crate_a
+// nothing here
+//- /lib.rs crate:crate_c
+// nothing here
+//- /lib.rs crate:other_crate_b
+//
+//- /lib.rs crate:lib deps:other_crate_a,other_crate_b,crate_c extern-prelude:other_crate_a,other_crate_b
+extern crate other_crate_b;
+extern crate oth$0
+mod other_mod {}
+"#;
+
+ let completion_list = completion_list_no_kw(case);
+
+ assert_eq!("md other_crate_a\n".to_string(), completion_list);
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs
index 8e904fd60..cecbe7539 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/format_string.rs
@@ -51,9 +51,7 @@ mod tests {
fn works_when_wrapped() {
check(
r#"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
+//- minicore: fmt
macro_rules! print {
($($arg:tt)*) => (std::io::_print(format_args!($($arg)*)));
}
@@ -70,9 +68,7 @@ fn main() {
fn no_completion_without_brace() {
check(
r#"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
+//- minicore: fmt
fn main() {
let foobar = 1;
format_args!("f$0");
@@ -87,18 +83,13 @@ fn main() {
check_edit(
"foobar",
r#"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
+//- minicore: fmt
fn main() {
let foobar = 1;
format_args!("{f$0");
}
"#,
r#"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
fn main() {
let foobar = 1;
format_args!("{foobar");
@@ -108,18 +99,13 @@ fn main() {
check_edit(
"foobar",
r#"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
+//- minicore: fmt
fn main() {
let foobar = 1;
format_args!("{$0");
}
"#,
r#"
-macro_rules! format_args {
- ($lit:literal $(tt:tt)*) => { 0 },
-}
fn main() {
let foobar = 1;
format_args!("{foobar");
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
index 269e40e6e..42dfbfc7d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -33,8 +33,8 @@
use hir::{self, HasAttrs};
use ide_db::{
- path_transform::PathTransform, syntax_helpers::insert_whitespace_into_node,
- traits::get_missing_assoc_items, SymbolKind,
+ documentation::HasDocs, path_transform::PathTransform,
+ syntax_helpers::insert_whitespace_into_node, traits::get_missing_assoc_items, SymbolKind,
};
use syntax::{
ast::{self, edit_in_place::AttrsOwnerEdit, HasTypeBounds},
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
index 2ffe12337..fc21bba45 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs
@@ -2,8 +2,12 @@
mod format_like;
-use hir::{Documentation, HasAttrs};
-use ide_db::{imports::insert_use::ImportScope, ty_filter::TryEnum, SnippetCap};
+use ide_db::{
+ documentation::{Documentation, HasDocs},
+ imports::insert_use::ImportScope,
+ ty_filter::TryEnum,
+ SnippetCap,
+};
use syntax::{
ast::{self, make, AstNode, AstToken},
SyntaxKind::{BLOCK_EXPR, EXPR_STMT, FOR_EXPR, IF_EXPR, LOOP_EXPR, STMT_LIST, WHILE_EXPR},
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs
index e9831a5b2..3ff68b978 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/snippet.rs
@@ -1,7 +1,6 @@
//! This file provides snippet completions, like `pd` => `eprintln!(...)`.
-use hir::Documentation;
-use ide_db::{imports::insert_use::ImportScope, SnippetCap};
+use ide_db::{documentation::Documentation, imports::insert_use::ImportScope, SnippetCap};
use crate::{
context::{ExprCtx, ItemListKind, PathCompletionCtx, Qualified},
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs
index e47054756..a30fd13b1 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs
@@ -1,7 +1,7 @@
//! Completion of names from the current scope in type position.
use hir::{HirDisplay, ScopeDef};
-use syntax::{ast, AstNode, SyntaxKind};
+use syntax::{ast, AstNode};
use crate::{
context::{PathCompletionCtx, Qualified, TypeAscriptionTarget, TypeLocation},
@@ -20,16 +20,15 @@ pub(crate) fn complete_type_path(
let scope_def_applicable = |def| {
use hir::{GenericParam::*, ModuleDef::*};
match def {
- ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
+ ScopeDef::GenericParam(LifetimeParam(_)) => location.complete_lifetimes(),
+ ScopeDef::Label(_) => false,
// no values in type places
ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_)) | ScopeDef::Local(_) => false,
// unless its a constant in a generic arg list position
ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => {
- matches!(location, TypeLocation::GenericArgList(_))
- }
- ScopeDef::ImplSelfType(_) => {
- !matches!(location, TypeLocation::ImplTarget | TypeLocation::ImplTrait)
+ location.complete_consts()
}
+ ScopeDef::ImplSelfType(_) => location.complete_self_type(),
// Don't suggest attribute macros and derives.
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
// Type things are fine
@@ -38,12 +37,12 @@ pub(crate) fn complete_type_path(
)
| ScopeDef::AdtSelfType(_)
| ScopeDef::Unknown
- | ScopeDef::GenericParam(TypeParam(_)) => true,
+ | ScopeDef::GenericParam(TypeParam(_)) => location.complete_types(),
}
};
let add_assoc_item = |acc: &mut Completions, item| match item {
- hir::AssocItem::Const(ct) if matches!(location, TypeLocation::GenericArgList(_)) => {
+ hir::AssocItem::Const(ct) if matches!(location, TypeLocation::GenericArg { .. }) => {
acc.add_const(ctx, ct)
}
hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => (),
@@ -157,56 +156,30 @@ pub(crate) fn complete_type_path(
});
return;
}
- TypeLocation::GenericArgList(Some(arg_list)) => {
- let in_assoc_type_arg = ctx
- .original_token
- .parent_ancestors()
- .any(|node| node.kind() == SyntaxKind::ASSOC_TYPE_ARG);
-
- if !in_assoc_type_arg {
- if let Some(path_seg) =
- arg_list.syntax().parent().and_then(ast::PathSegment::cast)
- {
- if path_seg
- .syntax()
- .ancestors()
- .find_map(ast::TypeBound::cast)
- .is_some()
- {
- if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(
- trait_,
- ))) = ctx.sema.resolve_path(&path_seg.parent_path())
- {
- let arg_idx = arg_list
- .generic_args()
- .filter(|arg| {
- arg.syntax().text_range().end()
- < ctx.original_token.text_range().start()
- })
- .count();
-
- let n_required_params =
- trait_.type_or_const_param_count(ctx.sema.db, true);
- if arg_idx >= n_required_params {
- trait_
- .items_with_supertraits(ctx.sema.db)
- .into_iter()
- .for_each(|it| {
- if let hir::AssocItem::TypeAlias(alias) = it {
- cov_mark::hit!(
- complete_assoc_type_in_generics_list
- );
- acc.add_type_alias_with_eq(ctx, alias);
- }
- });
-
- let n_params =
- trait_.type_or_const_param_count(ctx.sema.db, false);
- if arg_idx >= n_params {
- return; // only show assoc types
- }
- }
+ TypeLocation::GenericArg {
+ args: Some(arg_list), of_trait: Some(trait_), ..
+ } => {
+ if arg_list.syntax().ancestors().find_map(ast::TypeBound::cast).is_some() {
+ let arg_idx = arg_list
+ .generic_args()
+ .filter(|arg| {
+ arg.syntax().text_range().end()
+ < ctx.original_token.text_range().start()
+ })
+ .count();
+
+ let n_required_params = trait_.type_or_const_param_count(ctx.sema.db, true);
+ if arg_idx >= n_required_params {
+ trait_.items_with_supertraits(ctx.sema.db).into_iter().for_each(|it| {
+ if let hir::AssocItem::TypeAlias(alias) = it {
+ cov_mark::hit!(complete_assoc_type_in_generics_list);
+ acc.add_type_alias_with_eq(ctx, alias);
}
+ });
+
+ let n_params = trait_.type_or_const_param_count(ctx.sema.db, false);
+ if arg_idx >= n_params {
+ return; // only show assoc types
}
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index 3cb65b272..0da7ba6d0 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -155,13 +155,63 @@ pub(crate) struct ExprCtx {
pub(crate) enum TypeLocation {
TupleField,
TypeAscription(TypeAscriptionTarget),
- GenericArgList(Option<ast::GenericArgList>),
+ /// Generic argument position e.g. `Foo<$0>`
+ GenericArg {
+ /// The generic argument list containing the generic arg
+ args: Option<ast::GenericArgList>,
+ /// `Some(trait_)` if `trait_` is being instantiated with `args`
+ of_trait: Option<hir::Trait>,
+ /// The generic parameter being filled in by the generic arg
+ corresponding_param: Option<ast::GenericParam>,
+ },
+ /// Associated type equality constraint e.g. `Foo<Bar = $0>`
+ AssocTypeEq,
+ /// Associated constant equality constraint e.g. `Foo<X = $0>`
+ AssocConstEq,
TypeBound,
ImplTarget,
ImplTrait,
Other,
}
+impl TypeLocation {
+ pub(crate) fn complete_lifetimes(&self) -> bool {
+ matches!(
+ self,
+ TypeLocation::GenericArg {
+ corresponding_param: Some(ast::GenericParam::LifetimeParam(_)),
+ ..
+ }
+ )
+ }
+
+ pub(crate) fn complete_consts(&self) -> bool {
+ match self {
+ TypeLocation::GenericArg {
+ corresponding_param: Some(ast::GenericParam::ConstParam(_)),
+ ..
+ } => true,
+ TypeLocation::AssocConstEq => true,
+ _ => false,
+ }
+ }
+
+ pub(crate) fn complete_types(&self) -> bool {
+ match self {
+ TypeLocation::GenericArg { corresponding_param: Some(param), .. } => {
+ matches!(param, ast::GenericParam::TypeParam(_))
+ }
+ TypeLocation::AssocConstEq => false,
+ TypeLocation::AssocTypeEq => true,
+ _ => true,
+ }
+ }
+
+ pub(crate) fn complete_self_type(&self) -> bool {
+ self.complete_types() && !matches!(self, TypeLocation::ImplTarget | TypeLocation::ImplTrait)
+ }
+}
+
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) enum TypeAscriptionTarget {
Let(Option<ast::Pat>),
@@ -301,6 +351,7 @@ pub(super) enum NameRefKind {
expr: ast::RecordExpr,
},
Pattern(PatternContext),
+ ExternCrate,
}
/// The identifier we are currently completing.
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index 3ea506590..1e6b2f319 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -1,11 +1,11 @@
//! Module responsible for analyzing the code surrounding the cursor for completion.
use std::iter;
-use hir::{Semantics, Type, TypeInfo, Variant};
+use hir::{HasSource, Semantics, Type, TypeInfo, Variant};
use ide_db::{active_parameter::ActiveParameter, RootDatabase};
use syntax::{
algo::{find_node_at_offset, non_trivia_sibling},
- ast::{self, AttrKind, HasArgList, HasLoopBody, HasName, NameOrNameRef},
+ ast::{self, AttrKind, HasArgList, HasGenericParams, HasLoopBody, HasName, NameOrNameRef},
match_ast, AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
SyntaxToken, TextRange, TextSize, T,
};
@@ -624,6 +624,10 @@ fn classify_name_ref(
});
return Some(make_res(kind));
},
+ ast::ExternCrate(_) => {
+ let kind = NameRefKind::ExternCrate;
+ return Some(make_res(kind));
+ },
ast::MethodCallExpr(method) => {
let receiver = find_opt_node_in_file(original_file, method.receiver());
let kind = NameRefKind::DotAccess(DotAccess {
@@ -719,6 +723,136 @@ fn classify_name_ref(
None
};
+ let generic_arg_location = |arg: ast::GenericArg| {
+ let mut override_location = None;
+ let location = find_opt_node_in_file_compensated(
+ sema,
+ original_file,
+ arg.syntax().parent().and_then(ast::GenericArgList::cast),
+ )
+ .map(|args| {
+ let mut in_trait = None;
+ let param = (|| {
+ let parent = args.syntax().parent()?;
+ let params = match_ast! {
+ match parent {
+ ast::PathSegment(segment) => {
+ match sema.resolve_path(&segment.parent_path().top_path())? {
+ hir::PathResolution::Def(def) => match def {
+ hir::ModuleDef::Function(func) => {
+ func.source(sema.db)?.value.generic_param_list()
+ }
+ hir::ModuleDef::Adt(adt) => {
+ adt.source(sema.db)?.value.generic_param_list()
+ }
+ hir::ModuleDef::Variant(variant) => {
+ variant.parent_enum(sema.db).source(sema.db)?.value.generic_param_list()
+ }
+ hir::ModuleDef::Trait(trait_) => {
+ if let ast::GenericArg::AssocTypeArg(arg) = &arg {
+ let arg_name = arg.name_ref()?;
+ let arg_name = arg_name.text();
+ for item in trait_.items_with_supertraits(sema.db) {
+ match item {
+ hir::AssocItem::TypeAlias(assoc_ty) => {
+ if assoc_ty.name(sema.db).as_str()? == arg_name {
+ override_location = Some(TypeLocation::AssocTypeEq);
+ return None;
+ }
+ },
+ hir::AssocItem::Const(const_) => {
+ if const_.name(sema.db)?.as_str()? == arg_name {
+ override_location = Some(TypeLocation::AssocConstEq);
+ return None;
+ }
+ },
+ _ => (),
+ }
+ }
+ return None;
+ } else {
+ in_trait = Some(trait_);
+ trait_.source(sema.db)?.value.generic_param_list()
+ }
+ }
+ hir::ModuleDef::TraitAlias(trait_) => {
+ trait_.source(sema.db)?.value.generic_param_list()
+ }
+ hir::ModuleDef::TypeAlias(ty_) => {
+ ty_.source(sema.db)?.value.generic_param_list()
+ }
+ _ => None,
+ },
+ _ => None,
+ }
+ },
+ ast::MethodCallExpr(call) => {
+ let func = sema.resolve_method_call(&call)?;
+ func.source(sema.db)?.value.generic_param_list()
+ },
+ ast::AssocTypeArg(arg) => {
+ let trait_ = ast::PathSegment::cast(arg.syntax().parent()?.parent()?)?;
+ match sema.resolve_path(&trait_.parent_path().top_path())? {
+ hir::PathResolution::Def(def) => match def {
+ hir::ModuleDef::Trait(trait_) => {
+ let arg_name = arg.name_ref()?;
+ let arg_name = arg_name.text();
+ let trait_items = trait_.items_with_supertraits(sema.db);
+ let assoc_ty = trait_items.iter().find_map(|item| match item {
+ hir::AssocItem::TypeAlias(assoc_ty) => {
+ (assoc_ty.name(sema.db).as_str()? == arg_name)
+ .then_some(assoc_ty)
+ },
+ _ => None,
+ })?;
+ assoc_ty.source(sema.db)?.value.generic_param_list()
+ }
+ _ => None,
+ },
+ _ => None,
+ }
+ },
+ _ => None,
+ }
+ }?;
+ // Determine the index of the argument in the `GenericArgList` and match it with
+ // the corresponding parameter in the `GenericParamList`. Since lifetime parameters
+ // are often omitted, ignore them for the purposes of matching the argument with
+ // its parameter unless a lifetime argument is provided explicitly. That is, for
+ // `struct S<'a, 'b, T>`, match `S::<$0>` to `T` and `S::<'a, $0, _>` to `'b`.
+ // FIXME: This operates on the syntax tree and will produce incorrect results when
+ // generic parameters are disabled by `#[cfg]` directives. It should operate on the
+ // HIR, but the functionality necessary to do so is not exposed at the moment.
+ let mut explicit_lifetime_arg = false;
+ let arg_idx = arg
+ .syntax()
+ .siblings(Direction::Prev)
+ // Skip the node itself
+ .skip(1)
+ .map(|arg| if ast::LifetimeArg::can_cast(arg.kind()) { explicit_lifetime_arg = true })
+ .count();
+ let param_idx = if explicit_lifetime_arg {
+ arg_idx
+ } else {
+ // Lifetimes parameters always precede type and generic parameters,
+ // so offset the argument index by the total number of lifetime params
+ arg_idx + params.lifetime_params().count()
+ };
+ params.generic_params().nth(param_idx)
+ })();
+ (args, in_trait, param)
+ });
+ let (arg_list, of_trait, corresponding_param) = match location {
+ Some((arg_list, of_trait, param)) => (Some(arg_list), of_trait, param),
+ _ => (None, None, None),
+ };
+ override_location.unwrap_or(TypeLocation::GenericArg {
+ args: arg_list,
+ of_trait,
+ corresponding_param,
+ })
+ };
+
let type_location = |node: &SyntaxNode| {
let parent = node.parent()?;
let res = match_ast! {
@@ -774,9 +908,12 @@ fn classify_name_ref(
ast::TypeBound(_) => TypeLocation::TypeBound,
// is this case needed?
ast::TypeBoundList(_) => TypeLocation::TypeBound,
- ast::GenericArg(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, it.syntax().parent().and_then(ast::GenericArgList::cast))),
+ ast::GenericArg(it) => generic_arg_location(it),
// is this case needed?
- ast::GenericArgList(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, Some(it))),
+ ast::GenericArgList(it) => {
+ let args = find_opt_node_in_file_compensated(sema, original_file, Some(it));
+ TypeLocation::GenericArg { args, of_trait: None, corresponding_param: None }
+ },
ast::TupleField(_) => TypeLocation::TupleField,
_ => return None,
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
index 0309952c2..c45cc8d7b 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
@@ -2,8 +2,11 @@
use std::fmt;
-use hir::{Documentation, Mutability};
-use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SnippetCap, SymbolKind};
+use hir::Mutability;
+use ide_db::{
+ documentation::Documentation, imports::import_assets::LocatedImport, RootDatabase, SnippetCap,
+ SymbolKind,
+};
use itertools::Itertools;
use smallvec::SmallVec;
use stdx::{impl_from, never};
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
index 1953eb479..dfe8fe7e2 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -12,7 +12,10 @@ pub(crate) mod literal;
use hir::{AsAssocItem, HasAttrs, HirDisplay, ScopeDef};
use ide_db::{
- helpers::item_name, imports::import_assets::LocatedImport, RootDatabase, SnippetCap, SymbolKind,
+ documentation::{Documentation, HasDocs},
+ helpers::item_name,
+ imports::import_assets::LocatedImport,
+ RootDatabase, SnippetCap, SymbolKind,
};
use syntax::{AstNode, SmolStr, SyntaxKind, TextRange};
@@ -114,7 +117,7 @@ impl<'a> RenderContext<'a> {
}
// FIXME: remove this
- fn docs(&self, def: impl HasAttrs) -> Option<hir::Documentation> {
+ fn docs(&self, def: impl HasDocs) -> Option<Documentation> {
def.docs(self.db())
}
}
@@ -409,7 +412,7 @@ fn res_to_kind(resolution: ScopeDef) -> CompletionItemKind {
}
}
-fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<hir::Documentation> {
+fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<Documentation> {
use hir::ModuleDef::*;
match resolution {
ScopeDef::ModuleDef(Module(it)) => it.docs(db),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
index 728d236df..b218502f7 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
@@ -1,7 +1,10 @@
//! Renderer for `enum` variants.
-use hir::{db::HirDatabase, Documentation, HasAttrs, StructKind};
-use ide_db::SymbolKind;
+use hir::{db::HirDatabase, StructKind};
+use ide_db::{
+ documentation::{Documentation, HasDocs},
+ SymbolKind,
+};
use crate::{
context::{CompletionContext, PathCompletionCtx, PathKind},
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
index ce7af1d34..68d175c2b 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
@@ -1,7 +1,7 @@
//! Renderer for macro invocations.
-use hir::{Documentation, HirDisplay};
-use ide_db::SymbolKind;
+use hir::HirDisplay;
+use ide_db::{documentation::Documentation, SymbolKind};
use syntax::SmolStr;
use crate::{
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
index d06abc5e9..6f998119b 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
@@ -1,7 +1,7 @@
//! Renderer for patterns.
-use hir::{db::HirDatabase, HasAttrs, Name, StructKind};
-use ide_db::SnippetCap;
+use hir::{db::HirDatabase, Name, StructKind};
+use ide_db::{documentation::HasDocs, SnippetCap};
use itertools::Itertools;
use syntax::SmolStr;
@@ -103,7 +103,7 @@ fn build_completion(
label: SmolStr,
lookup: SmolStr,
pat: String,
- def: impl HasAttrs + Copy,
+ def: impl HasDocs + Copy,
adt_ty: hir::Type,
// Missing in context of match statement completions
is_variant_missing: bool,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
index 1aaf39587..d8c134c53 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
@@ -67,11 +67,6 @@ struct Foo;
}
#[test]
-fn inside_nested_attr() {
- check(r#"#[cfg($0)]"#, expect![[]])
-}
-
-#[test]
fn with_existing_attr() {
check(
r#"#[no_mangle] #[$0] mcall!();"#,
@@ -636,6 +631,32 @@ mod cfg {
use super::*;
#[test]
+ fn inside_cfg() {
+ check(
+ r#"
+//- /main.rs cfg:test,dbg=false,opt_level=2
+#[cfg($0)]
+"#,
+ expect![[r#"
+ ba dbg
+ ba opt_level
+ ba test
+ "#]],
+ );
+ check(
+ r#"
+//- /main.rs cfg:test,dbg=false,opt_level=2
+#[cfg(b$0)]
+"#,
+ expect![[r#"
+ ba dbg
+ ba opt_level
+ ba test
+ "#]],
+ );
+ }
+
+ #[test]
fn cfg_target_endian() {
check(
r#"#[cfg(target_endian = $0"#,
@@ -644,6 +665,13 @@ mod cfg {
ba little
"#]],
);
+ check(
+ r#"#[cfg(target_endian = b$0"#,
+ expect![[r#"
+ ba big
+ ba little
+ "#]],
+ );
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
index 8c038c0fb..4cdfd546f 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
@@ -1286,3 +1286,57 @@ macro_rules! println {
expect![""],
)
}
+
+#[test]
+fn no_completions_for_external_doc_hidden_in_path() {
+ check(
+ r#"
+//- /main.rs crate:main deps:dep
+fn main() {
+ Span$0
+}
+//- /lib.rs crate:dep
+#[doc(hidden)]
+pub mod bridge {
+ pub mod server {
+ pub trait Span
+ }
+}
+pub mod bridge2 {
+ #[doc(hidden)]
+ pub mod server2 {
+ pub trait Span
+ }
+}
+"#,
+ expect![""],
+ );
+ // unless re-exported
+ check(
+ r#"
+//- /main.rs crate:main deps:dep
+fn main() {
+ Span$0
+}
+//- /lib.rs crate:dep
+#[doc(hidden)]
+pub mod bridge {
+ pub mod server {
+ pub trait Span
+ }
+}
+pub use bridge::server::Span;
+pub mod bridge2 {
+ #[doc(hidden)]
+ pub mod server2 {
+ pub trait Span2
+ }
+}
+pub use bridge2::server2::Span2;
+"#,
+ expect![[r#"
+ tt Span (use dep::Span)
+ tt Span2 (use dep::Span2)
+ "#]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
index 8cb1ff4a1..d518dd764 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
@@ -384,10 +384,8 @@ trait Trait2<T>: Trait1 {
fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
"#,
expect![[r#"
- ct CONST
- cp CONST_PARAM
en Enum
- ma makro!(…) macro_rules! makro
+ ma makro!(…) macro_rules! makro
md module
st Record
st Tuple
@@ -404,14 +402,13 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
);
check(
r#"
-trait Trait2 {
+trait Trait2<T> {
type Foo;
}
fn foo<'lt, T: Trait2<self::$0>, const CONST_PARAM: usize>(_: T) {}
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -437,7 +434,6 @@ trait Tr<T> {
impl Tr<$0
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -485,7 +481,6 @@ trait MyTrait<T, U> {
fn f(t: impl MyTrait<u$0
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -511,7 +506,6 @@ trait MyTrait<T, U> {
fn f(t: impl MyTrait<u8, u$0
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -555,7 +549,6 @@ trait MyTrait<T, U = u8> {
fn f(t: impl MyTrait<u$0
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -581,7 +574,6 @@ trait MyTrait<T, U = u8> {
fn f(t: impl MyTrait<u8, u$0
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -627,7 +619,6 @@ trait MyTrait {
fn f(t: impl MyTrait<Item1 = $0
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -653,7 +644,6 @@ trait MyTrait {
fn f(t: impl MyTrait<Item1 = u8, Item2 = $0
"#,
expect![[r#"
- ct CONST
en Enum
ma makro!(…) macro_rules! makro
md module
@@ -668,6 +658,22 @@ fn f(t: impl MyTrait<Item1 = u8, Item2 = $0
kw self::
"#]],
);
+
+ check(
+ r#"
+trait MyTrait {
+ const C: usize;
+};
+
+fn f(t: impl MyTrait<C = $0
+"#,
+ expect![[r#"
+ ct CONST
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
}
#[test]
@@ -719,3 +725,267 @@ pub struct S;
"#]],
)
}
+
+#[test]
+fn completes_const_and_type_generics_separately() {
+ // Function generic params
+ check(
+ r#"
+ struct Foo;
+ const X: usize = 0;
+ fn foo<T, const N: usize>() {}
+ fn main() {
+ foo::<F$0, _>();
+ }
+ "#,
+ expect![[r#"
+ en Enum
+ ma makro!(…) macro_rules! makro
+ md module
+ st Foo
+ st Record
+ st Tuple
+ st Unit
+ tt Trait
+ un Union
+ bt u32
+ kw crate::
+ kw self::
+ "#]],
+ );
+ // FIXME: This should probably also suggest completions for types, at least those that have
+ // associated constants usable in this position. For example, a user could be typing
+ // `foo::<_, { usize::MAX }>()`, but we currently don't suggest `usize` in constant position.
+ check(
+ r#"
+ struct Foo;
+ const X: usize = 0;
+ fn foo<T, const N: usize>() {}
+ fn main() {
+ foo::<_, $0>();
+ }
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Method generic params
+ check(
+ r#"
+ const X: usize = 0;
+ struct Foo;
+ impl Foo { fn bar<const N: usize, T>(self) {} }
+ fn main() {
+ Foo.bar::<_, $0>();
+ }
+ "#,
+ expect![[r#"
+ en Enum
+ ma makro!(…) macro_rules! makro
+ md module
+ st Foo
+ st Record
+ st Tuple
+ st Unit
+ tt Trait
+ un Union
+ bt u32
+ kw crate::
+ kw self::
+ "#]],
+ );
+ check(
+ r#"
+ const X: usize = 0;
+ struct Foo;
+ impl Foo { fn bar<const N: usize, T>(self) {} }
+ fn main() {
+ Foo.bar::<X$0, _>();
+ }
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Associated type generic params
+ check(
+ r#"
+ const X: usize = 0;
+ struct Foo;
+ trait Bar {
+ type Baz<T, const X: usize>;
+ }
+ fn foo(_: impl Bar<Baz<F$0, 0> = ()>) {}
+ "#,
+ expect![[r#"
+ en Enum
+ ma makro!(…) macro_rules! makro
+ md module
+ st Foo
+ st Record
+ st Tuple
+ st Unit
+ tt Bar
+ tt Trait
+ un Union
+ bt u32
+ kw crate::
+ kw self::
+ "#]],
+ );
+ check(
+ r#"
+ const X: usize = 0;
+ struct Foo;
+ trait Bar {
+ type Baz<T, const X: usize>;
+ }
+ fn foo<T: Bar<Baz<(), $0> = ()>>() {}
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Type generic params
+ check(
+ r#"
+ const X: usize = 0;
+ struct Foo<T, const N: usize>(T);
+ fn main() {
+ let _: Foo::<_, $0> = Foo(());
+ }
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Type alias generic params
+ check(
+ r#"
+ const X: usize = 0;
+ struct Foo<T, const N: usize>(T);
+ type Bar<const X: usize, U> = Foo<U, X>;
+ fn main() {
+ let _: Bar::<X$0, _> = Bar(());
+ }
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Enum variant params
+ check(
+ r#"
+ const X: usize = 0;
+ enum Foo<T, const N: usize> { A(T), B }
+ fn main() {
+ Foo::B::<(), $0>;
+ }
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Trait params
+ check(
+ r#"
+ const X: usize = 0;
+ trait Foo<T, const N: usize> {}
+ impl Foo<(), $0> for () {}
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Trait alias params
+ check(
+ r#"
+ #![feature(trait_alias)]
+ const X: usize = 0;
+ trait Foo<T, const N: usize> {}
+ trait Bar<const M: usize, U> = Foo<U, M>;
+ fn foo<T: Bar<X$0, ()>>() {}
+ "#,
+ expect![[r#"
+ ct CONST
+ ct X
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+
+ // Omitted lifetime params
+ check(
+ r#"
+struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
+fn foo<'a>() { S::<F$0, _>; }
+ "#,
+ expect![[r#"
+ ct CONST
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+ // Explicit lifetime params
+ check(
+ r#"
+struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
+fn foo<'a>() { S::<'static, 'static, F$0, _>; }
+ "#,
+ expect![[r#"
+ ct CONST
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+ check(
+ r#"
+struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
+fn foo<'a>() { S::<'static, F$0, _, _>; }
+ "#,
+ expect![[r#"
+ lt 'a
+ ma makro!(…) macro_rules! makro
+ kw crate::
+ kw self::
+ "#]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
index 5e4562d9c..4ce80532e 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -7,7 +7,7 @@
use arrayvec::ArrayVec;
use hir::{
- Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper,
+ Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, DocLinkDef,
ExternCrateDecl, Field, Function, GenericParam, HasVisibility, Impl, Label, Local, Macro,
Module, ModuleDef, Name, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias,
TypeAlias, Variant, Visibility,
@@ -649,3 +649,13 @@ impl From<ModuleDef> for Definition {
}
}
}
+
+impl From<DocLinkDef> for Definition {
+ fn from(def: DocLinkDef) -> Self {
+ match def {
+ DocLinkDef::ModuleDef(it) => it.into(),
+ DocLinkDef::Field(it) => it.into(),
+ DocLinkDef::SelfType(it) => it.into(),
+ }
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs
new file mode 100644
index 000000000..26f3cd28a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-db/src/documentation.rs
@@ -0,0 +1,281 @@
+//! Documentation attribute related utilties.
+use either::Either;
+use hir::{
+ db::{DefDatabase, HirDatabase},
+ resolve_doc_path_on, AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile,
+};
+use itertools::Itertools;
+use syntax::{
+ ast::{self, IsString},
+ AstToken,
+};
+use text_edit::{TextRange, TextSize};
+
+/// Holds documentation
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Documentation(String);
+
+impl Documentation {
+ pub fn new(s: String) -> Self {
+ Documentation(s)
+ }
+
+ pub fn as_str(&self) -> &str {
+ &self.0
+ }
+}
+
+impl From<Documentation> for String {
+ fn from(Documentation(string): Documentation) -> Self {
+ string
+ }
+}
+
+pub trait HasDocs: HasAttrs {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>;
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>,
+ ) -> Option<hir::DocLinkDef>;
+}
+/// A struct to map text ranges from [`Documentation`] back to TextRanges in the syntax tree.
+#[derive(Debug)]
+pub struct DocsRangeMap {
+ source_map: AttrSourceMap,
+ // (docstring-line-range, attr_index, attr-string-range)
+ // a mapping from the text range of a line of the [`Documentation`] to the attribute index and
+ // the original (untrimmed) syntax doc line
+ mapping: Vec<(TextRange, AttrId, TextRange)>,
+}
+
+impl DocsRangeMap {
+ /// Maps a [`TextRange`] relative to the documentation string back to its AST range
+ pub fn map(&self, range: TextRange) -> Option<InFile<TextRange>> {
+ let found = self.mapping.binary_search_by(|(probe, ..)| probe.ordering(range)).ok()?;
+ let (line_docs_range, idx, original_line_src_range) = self.mapping[found];
+ if !line_docs_range.contains_range(range) {
+ return None;
+ }
+
+ let relative_range = range - line_docs_range.start();
+
+ let InFile { file_id, value: source } = self.source_map.source_of_id(idx);
+ match source {
+ Either::Left(attr) => {
+ let string = get_doc_string_in_attr(attr)?;
+ let text_range = string.open_quote_text_range()?;
+ let range = TextRange::at(
+ text_range.end() + original_line_src_range.start() + relative_range.start(),
+ string.syntax().text_range().len().min(range.len()),
+ );
+ Some(InFile { file_id, value: range })
+ }
+ Either::Right(comment) => {
+ let text_range = comment.syntax().text_range();
+ let range = TextRange::at(
+ text_range.start()
+ + TextSize::try_from(comment.prefix().len()).ok()?
+ + original_line_src_range.start()
+ + relative_range.start(),
+ text_range.len().min(range.len()),
+ );
+ Some(InFile { file_id, value: range })
+ }
+ }
+ }
+}
+
+pub fn docs_with_rangemap(
+ db: &dyn DefDatabase,
+ attrs: &AttrsWithOwner,
+) -> Option<(Documentation, DocsRangeMap)> {
+ let docs =
+ attrs.by_key("doc").attrs().filter_map(|attr| attr.string_value().map(|s| (s, attr.id)));
+ let indent = doc_indent(attrs);
+ let mut buf = String::new();
+ let mut mapping = Vec::new();
+ for (doc, idx) in docs {
+ if !doc.is_empty() {
+ let mut base_offset = 0;
+ for raw_line in doc.split('\n') {
+ let line = raw_line.trim_end();
+ let line_len = line.len();
+ let (offset, line) = match line.char_indices().nth(indent) {
+ Some((offset, _)) => (offset, &line[offset..]),
+ None => (0, line),
+ };
+ let buf_offset = buf.len();
+ buf.push_str(line);
+ mapping.push((
+ TextRange::new(buf_offset.try_into().ok()?, buf.len().try_into().ok()?),
+ idx,
+ TextRange::at(
+ (base_offset + offset).try_into().ok()?,
+ line_len.try_into().ok()?,
+ ),
+ ));
+ buf.push('\n');
+ base_offset += raw_line.len() + 1;
+ }
+ } else {
+ buf.push('\n');
+ }
+ }
+ buf.pop();
+ if buf.is_empty() {
+ None
+ } else {
+ Some((Documentation(buf), DocsRangeMap { mapping, source_map: attrs.source_map(db) }))
+ }
+}
+
+pub fn docs_from_attrs(attrs: &hir::Attrs) -> Option<String> {
+ let docs = attrs.by_key("doc").attrs().filter_map(|attr| attr.string_value());
+ let indent = doc_indent(attrs);
+ let mut buf = String::new();
+ for doc in docs {
+ // str::lines doesn't yield anything for the empty string
+ if !doc.is_empty() {
+ buf.extend(Itertools::intersperse(
+ doc.lines().map(|line| {
+ line.char_indices()
+ .nth(indent)
+ .map_or(line, |(offset, _)| &line[offset..])
+ .trim_end()
+ }),
+ "\n",
+ ));
+ }
+ buf.push('\n');
+ }
+ buf.pop();
+ if buf.is_empty() {
+ None
+ } else {
+ Some(buf)
+ }
+}
+
+macro_rules! impl_has_docs {
+ ($($def:ident,)*) => {$(
+ impl HasDocs for hir::$def {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ docs_from_attrs(&self.attrs(db)).map(Documentation)
+ }
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>
+ ) -> Option<hir::DocLinkDef> {
+ resolve_doc_path_on(db, self, link, ns)
+ }
+ }
+ )*};
+}
+
+impl_has_docs![
+ Variant, Field, Static, Const, Trait, TraitAlias, TypeAlias, Macro, Function, Adt, Module,
+ Impl,
+];
+
+macro_rules! impl_has_docs_enum {
+ ($($variant:ident),* for $enum:ident) => {$(
+ impl HasDocs for hir::$variant {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ hir::$enum::$variant(self).docs(db)
+ }
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>
+ ) -> Option<hir::DocLinkDef> {
+ hir::$enum::$variant(self).resolve_doc_path(db, link, ns)
+ }
+ }
+ )*};
+}
+
+impl_has_docs_enum![Struct, Union, Enum for Adt];
+
+impl HasDocs for hir::AssocItem {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ match self {
+ hir::AssocItem::Function(it) => it.docs(db),
+ hir::AssocItem::Const(it) => it.docs(db),
+ hir::AssocItem::TypeAlias(it) => it.docs(db),
+ }
+ }
+
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>,
+ ) -> Option<hir::DocLinkDef> {
+ match self {
+ hir::AssocItem::Function(it) => it.resolve_doc_path(db, link, ns),
+ hir::AssocItem::Const(it) => it.resolve_doc_path(db, link, ns),
+ hir::AssocItem::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
+ }
+ }
+}
+
+impl HasDocs for hir::ExternCrateDecl {
+ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
+ let crate_docs =
+ docs_from_attrs(&self.resolved_crate(db)?.root_module().attrs(db)).map(String::from);
+ let decl_docs = docs_from_attrs(&self.attrs(db)).map(String::from);
+ match (decl_docs, crate_docs) {
+ (None, None) => None,
+ (Some(decl_docs), None) => Some(decl_docs),
+ (None, Some(crate_docs)) => Some(crate_docs),
+ (Some(mut decl_docs), Some(crate_docs)) => {
+ decl_docs.push('\n');
+ decl_docs.push('\n');
+ decl_docs += &crate_docs;
+ Some(decl_docs)
+ }
+ }
+ .map(Documentation::new)
+ }
+ fn resolve_doc_path(
+ self,
+ db: &dyn HirDatabase,
+ link: &str,
+ ns: Option<hir::Namespace>,
+ ) -> Option<hir::DocLinkDef> {
+ resolve_doc_path_on(db, self, link, ns)
+ }
+}
+
+fn get_doc_string_in_attr(it: &ast::Attr) -> Option<ast::String> {
+ match it.expr() {
+ // #[doc = lit]
+ Some(ast::Expr::Literal(lit)) => match lit.kind() {
+ ast::LiteralKind::String(it) => Some(it),
+ _ => None,
+ },
+ // #[cfg_attr(..., doc = "", ...)]
+ None => {
+ // FIXME: See highlight injection for what to do here
+ None
+ }
+ _ => None,
+ }
+}
+
+fn doc_indent(attrs: &hir::Attrs) -> usize {
+ attrs
+ .by_key("doc")
+ .attrs()
+ .filter_map(|attr| attr.string_value())
+ .flat_map(|s| s.lines())
+ .filter(|line| !line.chars().all(|c| c.is_whitespace()))
+ .map(|line| line.chars().take_while(|c| c.is_whitespace()).count())
+ .min()
+ .unwrap_or(0)
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
index 49b37024a..57563a174 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
@@ -3505,8 +3505,8 @@ This serves two purposes:
"##,
},
Lint {
- label: "no_coverage",
- description: r##"# `no_coverage`
+ label: "coverage",
+ description: r##"# `coverage`
The tracking issue for this feature is: [#84605]
@@ -3514,7 +3514,7 @@ The tracking issue for this feature is: [#84605]
---
-The `no_coverage` attribute can be used to selectively disable coverage
+The `coverage` attribute can be used to selectively disable coverage
instrumentation in an annotated function. This might be useful to:
- Avoid instrumentation overhead in a performance critical function
@@ -3524,14 +3524,14 @@ instrumentation in an annotated function. This might be useful to:
## Example
```rust
-#![feature(no_coverage)]
+#![feature(coverage)]
// `foo()` will get coverage instrumentation (by default)
fn foo() {
// ...
}
-#[no_coverage]
+#[coverage(off)]
fn bar() {
// ...
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
index 1eb8f0002..330af442f 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
@@ -117,7 +117,7 @@ pub fn get_definition(
sema: &Semantics<'_, RootDatabase>,
token: SyntaxToken,
) -> Option<Definition> {
- for token in sema.descend_into_macros(token) {
+ for token in sema.descend_into_macros(token, 0.into()) {
let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops);
if let Some(&[x]) = def.as_deref() {
return Some(x);
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
index e52dc3567..e475c5cd6 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
@@ -6,7 +6,7 @@ use hir::{
use itertools::Itertools;
use rustc_hash::FxHashSet;
use syntax::{
- ast::{self, HasName},
+ ast::{self, make, HasName},
utils::path_to_string_stripping_turbo_fish,
AstNode, SyntaxNode,
};
@@ -607,7 +607,7 @@ impl ImportCandidate {
fn for_name(sema: &Semantics<'_, RootDatabase>, name: &ast::Name) -> Option<Self> {
if sema
.scope(name.syntax())?
- .speculative_resolve(&ast::make::ext::ident_path(&name.text()))
+ .speculative_resolve(&make::ext::ident_path(&name.text()))
.is_some()
{
return None;
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index f27ed485d..226def4d5 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -22,6 +22,7 @@ pub mod symbol_index;
pub mod traits;
pub mod ty_filter;
pub mod use_trivial_constructor;
+pub mod documentation;
pub mod imports {
pub mod import_assets;
@@ -94,18 +95,21 @@ impl fmt::Debug for RootDatabase {
}
impl Upcast<dyn ExpandDatabase> for RootDatabase {
+ #[inline]
fn upcast(&self) -> &(dyn ExpandDatabase + 'static) {
&*self
}
}
impl Upcast<dyn DefDatabase> for RootDatabase {
+ #[inline]
fn upcast(&self) -> &(dyn DefDatabase + 'static) {
&*self
}
}
impl Upcast<dyn HirDatabase> for RootDatabase {
+ #[inline]
fn upcast(&self) -> &(dyn HirDatabase + 'static) {
&*self
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
index 1d0cb426a..fb75b5b45 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -5,7 +5,7 @@ use either::Either;
use hir::{AsAssocItem, HirDisplay, SemanticsScope};
use rustc_hash::FxHashMap;
use syntax::{
- ast::{self, AstNode},
+ ast::{self, make, AstNode},
ted, SyntaxNode,
};
@@ -21,6 +21,7 @@ enum TypeOrConst {
}
type LifetimeName = String;
+type DefaultedParam = Either<hir::TypeParam, hir::ConstParam>;
/// `PathTransform` substitutes path in SyntaxNodes in bulk.
///
@@ -115,7 +116,7 @@ impl<'a> PathTransform<'a> {
};
let mut type_substs: FxHashMap<hir::TypeParam, ast::Type> = Default::default();
let mut const_substs: FxHashMap<hir::ConstParam, SyntaxNode> = Default::default();
- let mut default_types: Vec<hir::TypeParam> = Default::default();
+ let mut defaulted_params: Vec<DefaultedParam> = Default::default();
self.generic_def
.into_iter()
.flat_map(|it| it.type_params(db))
@@ -138,8 +139,8 @@ impl<'a> PathTransform<'a> {
if let Some(default) =
&default.display_source_code(db, source_module.into(), false).ok()
{
- type_substs.insert(k, ast::make::ty(default).clone_for_update());
- default_types.push(k);
+ type_substs.insert(k, make::ty(default).clone_for_update());
+ defaulted_params.push(Either::Left(k));
}
}
}
@@ -155,11 +156,19 @@ impl<'a> PathTransform<'a> {
// is a standalone statement or a part of another expresson)
// and sometimes require slight modifications; see
// https://doc.rust-lang.org/reference/statements.html#expression-statements
+ // (default values in curly brackets can cause the same problem)
const_substs.insert(k, expr.syntax().clone());
}
}
- (Either::Left(_), None) => (), // FIXME: get default const value
- _ => (), // ignore mismatching params
+ (Either::Left(k), None) => {
+ if let Some(default) = k.default(db) {
+ if let Some(default) = default.expr() {
+ const_substs.insert(k, default.syntax().clone_for_update());
+ defaulted_params.push(Either::Right(k));
+ }
+ }
+ }
+ _ => (), // ignore mismatching params
});
let lifetime_substs: FxHashMap<_, _> = self
.generic_def
@@ -175,7 +184,7 @@ impl<'a> PathTransform<'a> {
target_module,
source_scope: self.source_scope,
};
- ctx.transform_default_type_substs(default_types);
+ ctx.transform_default_values(defaulted_params);
ctx
}
}
@@ -212,13 +221,19 @@ impl Ctx<'_> {
});
}
- fn transform_default_type_substs(&self, default_types: Vec<hir::TypeParam>) {
- for k in default_types {
- let v = self.type_substs.get(&k).unwrap();
+ fn transform_default_values(&self, defaulted_params: Vec<DefaultedParam>) {
+ // By now the default values are simply copied from where they are declared
+ // and should be transformed. As any value is allowed to refer to previous
+ // generic (both type and const) parameters, they should be all iterated left-to-right.
+ for param in defaulted_params {
+ let value = match param {
+ Either::Left(k) => self.type_substs.get(&k).unwrap().syntax(),
+ Either::Right(k) => self.const_substs.get(&k).unwrap(),
+ };
// `transform_path` may update a node's parent and that would break the
// tree traversal. Thus all paths in the tree are collected into a vec
// so that such operation is safe.
- let paths = postorder(&v.syntax()).filter_map(ast::Path::cast).collect::<Vec<_>>();
+ let paths = postorder(value).filter_map(ast::Path::cast).collect::<Vec<_>>();
for path in paths {
self.transform_path(path);
}
@@ -263,15 +278,14 @@ impl Ctx<'_> {
hir::ModuleDef::Trait(trait_ref),
false,
)?;
- match ast::make::ty_path(mod_path_to_ast(&found_path)) {
+ match make::ty_path(mod_path_to_ast(&found_path)) {
ast::Type::PathType(path_ty) => Some(path_ty),
_ => None,
}
});
- let segment = ast::make::path_segment_ty(subst.clone(), trait_ref);
- let qualified =
- ast::make::path_from_segments(std::iter::once(segment), false);
+ let segment = make::path_segment_ty(subst.clone(), trait_ref);
+ let qualified = make::path_from_segments(std::iter::once(segment), false);
ted::replace(path.syntax(), qualified.clone_for_update().syntax());
} else if let Some(path_ty) = ast::PathType::cast(parent) {
ted::replace(
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
index aa0bb7cce..353a9749a 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs
@@ -71,12 +71,29 @@ impl Definition {
sema: &Semantics<'_, RootDatabase>,
new_name: &str,
) -> Result<SourceChange> {
+ // self.krate() returns None if
+ // self is a built-in attr, built-in type or tool module.
+ // it is not allowed for these defs to be renamed.
+ // cases where self.krate() is None is handled below.
+ if let Some(krate) = self.krate(sema.db) {
+ if !krate.origin(sema.db).is_local() {
+ bail!("Cannot rename a non-local definition.")
+ }
+ }
+
match *self {
Definition::Module(module) => rename_mod(sema, module, new_name),
+ Definition::ToolModule(_) => {
+ bail!("Cannot rename a tool module")
+ }
Definition::BuiltinType(_) => {
bail!("Cannot rename builtin type")
}
+ Definition::BuiltinAttr(_) => {
+ bail!("Cannot rename a builtin attr.")
+ }
Definition::SelfType(_) => bail!("Cannot rename `Self`"),
+ Definition::Macro(mac) => rename_reference(sema, Definition::Macro(mac), new_name),
def => rename_reference(sema, def, new_name),
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rust_doc.rs b/src/tools/rust-analyzer/crates/ide-db/src/rust_doc.rs
index e27e23867..ab2a25028 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/rust_doc.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/rust_doc.rs
@@ -1,5 +1,7 @@
//! Rustdoc specific doc comment handling
+use crate::documentation::Documentation;
+
// stripped down version of https://github.com/rust-lang/rust/blob/392ba2ba1a7d6c542d2459fb8133bebf62a4a423/src/librustdoc/html/markdown.rs#L810-L933
pub fn is_rust_fence(s: &str) -> bool {
let mut seen_rust_tags = false;
@@ -32,3 +34,170 @@ pub fn is_rust_fence(s: &str) -> bool {
!seen_other_tags || seen_rust_tags
}
+
+const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
+
+pub fn format_docs(src: &Documentation) -> String {
+ format_docs_(src.as_str())
+}
+
+fn format_docs_(src: &str) -> String {
+ let mut processed_lines = Vec::new();
+ let mut in_code_block = false;
+ let mut is_rust = false;
+
+ for mut line in src.lines() {
+ if in_code_block && is_rust && code_line_ignored_by_rustdoc(line) {
+ continue;
+ }
+
+ if let Some(header) = RUSTDOC_FENCES.into_iter().find_map(|fence| line.strip_prefix(fence))
+ {
+ in_code_block ^= true;
+
+ if in_code_block {
+ is_rust = is_rust_fence(header);
+
+ if is_rust {
+ line = "```rust";
+ }
+ }
+ }
+
+ if in_code_block {
+ let trimmed = line.trim_start();
+ if is_rust && trimmed.starts_with("##") {
+ line = &trimmed[1..];
+ }
+ }
+
+ processed_lines.push(line);
+ }
+ processed_lines.join("\n")
+}
+
+fn code_line_ignored_by_rustdoc(line: &str) -> bool {
+ let trimmed = line.trim();
+ trimmed == "#" || trimmed.starts_with("# ") || trimmed.starts_with("#\t")
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_format_docs_adds_rust() {
+ let comment = "```\nfn some_rust() {}\n```";
+ assert_eq!(format_docs_(comment), "```rust\nfn some_rust() {}\n```");
+ }
+
+ #[test]
+ fn test_format_docs_handles_plain_text() {
+ let comment = "```text\nthis is plain text\n```";
+ assert_eq!(format_docs_(comment), "```text\nthis is plain text\n```");
+ }
+
+ #[test]
+ fn test_format_docs_handles_non_rust() {
+ let comment = "```sh\nsupposedly shell code\n```";
+ assert_eq!(format_docs_(comment), "```sh\nsupposedly shell code\n```");
+ }
+
+ #[test]
+ fn test_format_docs_handles_rust_alias() {
+ let comment = "```ignore\nlet z = 55;\n```";
+ assert_eq!(format_docs_(comment), "```rust\nlet z = 55;\n```");
+ }
+
+ #[test]
+ fn test_format_docs_handles_complex_code_block_attrs() {
+ let comment = "```rust,no_run\nlet z = 55;\n```";
+ assert_eq!(format_docs_(comment), "```rust\nlet z = 55;\n```");
+ }
+
+ #[test]
+ fn test_format_docs_handles_error_codes() {
+ let comment = "```compile_fail,E0641\nlet b = 0 as *const _;\n```";
+ assert_eq!(format_docs_(comment), "```rust\nlet b = 0 as *const _;\n```");
+ }
+
+ #[test]
+ fn test_format_docs_skips_comments_in_rust_block() {
+ let comment =
+ "```rust\n # skip1\n# skip2\n#stay1\nstay2\n#\n #\n # \n #\tskip3\n\t#\t\n```";
+ assert_eq!(format_docs_(comment), "```rust\n#stay1\nstay2\n```");
+ }
+
+ #[test]
+ fn test_format_docs_does_not_skip_lines_if_plain_text() {
+ let comment =
+ "```text\n # stay1\n# stay2\n#stay3\nstay4\n#\n #\n # \n #\tstay5\n\t#\t\n```";
+ assert_eq!(
+ format_docs_(comment),
+ "```text\n # stay1\n# stay2\n#stay3\nstay4\n#\n #\n # \n #\tstay5\n\t#\t\n```",
+ );
+ }
+
+ #[test]
+ fn test_format_docs_keeps_comments_outside_of_rust_block() {
+ let comment = " # stay1\n# stay2\n#stay3\nstay4\n#\n #\n # \n #\tstay5\n\t#\t";
+ assert_eq!(format_docs_(comment), comment);
+ }
+
+ #[test]
+ fn test_format_docs_preserves_newlines() {
+ let comment = "this\nis\nmultiline";
+ assert_eq!(format_docs_(comment), comment);
+ }
+
+ #[test]
+ fn test_code_blocks_in_comments_marked_as_rust() {
+ let comment = r#"```rust
+fn main(){}
+```
+Some comment.
+```
+let a = 1;
+```"#;
+
+ assert_eq!(
+ format_docs_(comment),
+ "```rust\nfn main(){}\n```\nSome comment.\n```rust\nlet a = 1;\n```"
+ );
+ }
+
+ #[test]
+ fn test_code_blocks_in_comments_marked_as_text() {
+ let comment = r#"```text
+filler
+text
+```
+Some comment.
+```
+let a = 1;
+```"#;
+
+ assert_eq!(
+ format_docs_(comment),
+ "```text\nfiller\ntext\n```\nSome comment.\n```rust\nlet a = 1;\n```"
+ );
+ }
+
+ #[test]
+ fn test_format_docs_handles_escape_double_hashes() {
+ let comment = r#"```rust
+let s = "foo
+## bar # baz";
+```"#;
+
+ assert_eq!(format_docs_(comment), "```rust\nlet s = \"foo\n# bar # baz\";\n```");
+ }
+
+ #[test]
+ fn test_format_docs_handles_double_hashes_non_rust() {
+ let comment = r#"```markdown
+## A second-level heading
+```"#;
+ assert_eq!(format_docs_(comment), "```markdown\n## A second-level heading\n```");
+ }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index d5abd0991..9c4f0ac8c 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -6,7 +6,7 @@
use std::mem;
-use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
+use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt};
use hir::{
AsAssocItem, DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility,
};
@@ -221,7 +221,6 @@ impl Definition {
}
// def is crate root
- // FIXME: We don't do searches for crates currently, as a crate does not actually have a single name
if let &Definition::Module(module) = self {
if module.is_crate_root() {
return SearchScope::reverse_dependencies(db, module.krate());
@@ -393,7 +392,10 @@ impl<'a> FindUsages<'a> {
let name = match self.def {
// special case crate modules as these do not have a proper name
Definition::Module(module) if module.is_crate_root() => {
- // FIXME: This assumes the crate name is always equal to its display name when it really isn't
+ // FIXME: This assumes the crate name is always equal to its display name when it
+ // really isn't
+ // we should instead look at the dependency edge name and recursively search our way
+ // up the ancestors
module
.krate()
.display_name(self.sema.db)
@@ -456,18 +458,19 @@ impl<'a> FindUsages<'a> {
it.text().trim_start_matches("r#") == name
})
.into_iter()
- .flat_map(|token| {
+ .flat_map(move |token| {
// FIXME: There should be optimization potential here
// Currently we try to descend everything we find which
// means we call `Semantics::descend_into_macros` on
// every textual hit. That function is notoriously
// expensive even for things that do not get down mapped
// into macros.
- sema.descend_into_macros(token).into_iter().filter_map(|it| it.parent())
+ sema.descend_into_macros(token, offset).into_iter().filter_map(|it| it.parent())
})
};
for (text, file_id, search_range) in scope_files(sema, &search_scope) {
+ self.sema.db.unwind_if_cancelled();
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
// Search for occurrences of the items name
@@ -504,6 +507,7 @@ impl<'a> FindUsages<'a> {
let finder = &Finder::new("super");
for (text, file_id, search_range) in scope_files(sema, &scope) {
+ self.sema.db.unwind_if_cancelled();
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
for offset in match_indices(&text, finder, search_range) {
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
index b54c43b29..f699f999b 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
@@ -323,6 +323,8 @@ impl Query {
hir::ModuleDef::Adt(..)
| hir::ModuleDef::TypeAlias(..)
| hir::ModuleDef::BuiltinType(..)
+ | hir::ModuleDef::TraitAlias(..)
+ | hir::ModuleDef::Trait(..)
)
{
continue;
@@ -417,9 +419,16 @@ const CONST_WITH_INNER: () = {
mod b_mod;
+
+use define_struct as really_define_struct;
+use Macro as ItemLikeMacro;
+use Macro as Trait; // overlay namespaces
//- /b_mod.rs
struct StructInModB;
- "#,
+use super::Macro as SuperItemLikeMacro;
+use crate::b_mod::StructInModB as ThisStruct;
+use crate::Trait as IsThisJustATrait;
+"#,
);
let symbols: Vec<_> = Crate::from(db.test_crate())
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs
index acf0a67de..8302b015d 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs
@@ -1,10 +1,10 @@
//! Tools to work with format string literals for the `format_args!` family of macros.
-use crate::syntax_helpers::node_ext::macro_call_for_string_token;
use syntax::{
ast::{self, IsString},
- TextRange, TextSize,
+ AstNode, AstToken, TextRange, TextSize,
};
+// FIXME: This can probably be re-implemented via the HIR?
pub fn is_format_string(string: &ast::String) -> bool {
// Check if `string` is a format string argument of a macro invocation.
// `string` is a string literal, mapped down into the innermost macro expansion.
@@ -15,19 +15,9 @@ pub fn is_format_string(string: &ast::String) -> bool {
// This setup lets us correctly highlight the components of `concat!("{}", "bla")` format
// strings. It still fails for `concat!("{", "}")`, but that is rare.
(|| {
- let name = macro_call_for_string_token(string)?.path()?.segment()?.name_ref()?;
-
- if !matches!(
- name.text().as_str(),
- "format_args" | "format_args_nl" | "const_format_args" | "panic_2015" | "panic_2021"
- ) {
- return None;
- }
-
- // NB: we match against `panic_2015`/`panic_2021` here because they have a special-cased arm for
- // `"{}"`, which otherwise wouldn't get highlighted.
-
- Some(())
+ let lit = string.syntax().parent().and_then(ast::Literal::cast)?;
+ let fa = lit.syntax().parent().and_then(ast::FormatArgsExpr::cast)?;
+ (fa.template()? == ast::Expr::Literal(lit)).then_some(|| ())
})()
.is_some()
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
index 22ced69d8..e4e735cec 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs
@@ -312,7 +312,6 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
ast::Expr::ArrayExpr(_)
| ast::Expr::AwaitExpr(_)
| ast::Expr::BinExpr(_)
- | ast::Expr::BoxExpr(_)
| ast::Expr::BreakExpr(_)
| ast::Expr::CallExpr(_)
| ast::Expr::CastExpr(_)
@@ -335,7 +334,10 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
| ast::Expr::LetExpr(_)
| ast::Expr::UnderscoreExpr(_)
| ast::Expr::YieldExpr(_)
- | ast::Expr::YeetExpr(_) => cb(expr),
+ | ast::Expr::YeetExpr(_)
+ | ast::Expr::OffsetOfExpr(_)
+ | ast::Expr::FormatArgsExpr(_)
+ | ast::Expr::AsmExpr(_) => cb(expr),
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
index 1a00e2938..87ad5844c 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
+++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
@@ -119,6 +119,35 @@
is_alias: false,
},
FileSymbol {
+ name: "ItemLikeMacro",
+ def: Macro(
+ Macro {
+ id: Macro2Id(
+ Macro2Id(
+ 0,
+ ),
+ ),
+ },
+ ),
+ loc: DeclarationLocation {
+ hir_file_id: FileId(
+ FileId(
+ 0,
+ ),
+ ),
+ ptr: SyntaxNodePtr {
+ kind: USE_TREE,
+ range: 654..676,
+ },
+ name_ptr: SyntaxNodePtr {
+ kind: NAME,
+ range: 663..676,
+ },
+ },
+ container_name: None,
+ is_alias: false,
+ },
+ FileSymbol {
name: "Macro",
def: Macro(
Macro {
@@ -353,6 +382,35 @@
is_alias: false,
},
FileSymbol {
+ name: "Trait",
+ def: Macro(
+ Macro {
+ id: Macro2Id(
+ Macro2Id(
+ 0,
+ ),
+ ),
+ },
+ ),
+ loc: DeclarationLocation {
+ hir_file_id: FileId(
+ FileId(
+ 0,
+ ),
+ ),
+ ptr: SyntaxNodePtr {
+ kind: USE_TREE,
+ range: 682..696,
+ },
+ name_ptr: SyntaxNodePtr {
+ kind: NAME,
+ range: 691..696,
+ },
+ },
+ container_name: None,
+ is_alias: false,
+ },
+ FileSymbol {
name: "Union",
def: Adt(
Union(
@@ -552,6 +610,35 @@
is_alias: false,
},
FileSymbol {
+ name: "really_define_struct",
+ def: Macro(
+ Macro {
+ id: MacroRulesId(
+ MacroRulesId(
+ 1,
+ ),
+ ),
+ },
+ ),
+ loc: DeclarationLocation {
+ hir_file_id: FileId(
+ FileId(
+ 0,
+ ),
+ ),
+ ptr: SyntaxNodePtr {
+ kind: USE_TREE,
+ range: 611..648,
+ },
+ name_ptr: SyntaxNodePtr {
+ kind: NAME,
+ range: 628..648,
+ },
+ },
+ container_name: None,
+ is_alias: false,
+ },
+ FileSymbol {
name: "trait_fn",
def: Function(
Function {
@@ -632,6 +719,35 @@
},
[
FileSymbol {
+ name: "IsThisJustATrait",
+ def: Macro(
+ Macro {
+ id: Macro2Id(
+ Macro2Id(
+ 0,
+ ),
+ ),
+ },
+ ),
+ loc: DeclarationLocation {
+ hir_file_id: FileId(
+ FileId(
+ 1,
+ ),
+ ),
+ ptr: SyntaxNodePtr {
+ kind: USE_TREE,
+ range: 111..143,
+ },
+ name_ptr: SyntaxNodePtr {
+ kind: NAME,
+ range: 127..143,
+ },
+ },
+ container_name: None,
+ is_alias: false,
+ },
+ FileSymbol {
name: "StructInModB",
def: Adt(
Struct(
@@ -660,6 +776,93 @@
container_name: None,
is_alias: false,
},
+ FileSymbol {
+ name: "SuperItemLikeMacro",
+ def: Macro(
+ Macro {
+ id: Macro2Id(
+ Macro2Id(
+ 0,
+ ),
+ ),
+ },
+ ),
+ loc: DeclarationLocation {
+ hir_file_id: FileId(
+ FileId(
+ 1,
+ ),
+ ),
+ ptr: SyntaxNodePtr {
+ kind: USE_TREE,
+ range: 25..59,
+ },
+ name_ptr: SyntaxNodePtr {
+ kind: NAME,
+ range: 41..59,
+ },
+ },
+ container_name: None,
+ is_alias: false,
+ },
+ FileSymbol {
+ name: "ThisStruct",
+ def: Adt(
+ Struct(
+ Struct {
+ id: StructId(
+ 3,
+ ),
+ },
+ ),
+ ),
+ loc: DeclarationLocation {
+ hir_file_id: FileId(
+ FileId(
+ 1,
+ ),
+ ),
+ ptr: SyntaxNodePtr {
+ kind: USE_TREE,
+ range: 65..105,
+ },
+ name_ptr: SyntaxNodePtr {
+ kind: NAME,
+ range: 95..105,
+ },
+ },
+ container_name: None,
+ is_alias: false,
+ },
+ FileSymbol {
+ name: "ThisStruct",
+ def: Adt(
+ Struct(
+ Struct {
+ id: StructId(
+ 3,
+ ),
+ },
+ ),
+ ),
+ loc: DeclarationLocation {
+ hir_file_id: FileId(
+ FileId(
+ 1,
+ ),
+ ),
+ ptr: SyntaxNodePtr {
+ kind: USE_TREE,
+ range: 65..105,
+ },
+ name_ptr: SyntaxNodePtr {
+ kind: NAME,
+ range: 95..105,
+ },
+ },
+ container_name: None,
+ is_alias: false,
+ },
],
),
]
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
index f96ea29ae..a915391ad 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
@@ -1,31 +1,29 @@
//! Functionality for generating trivial constructors
use hir::StructKind;
-use syntax::ast;
+use syntax::ast::{make, Expr, Path};
/// given a type return the trivial constructor (if one exists)
pub fn use_trivial_constructor(
db: &crate::RootDatabase,
- path: ast::Path,
+ path: Path,
ty: &hir::Type,
-) -> Option<ast::Expr> {
+) -> Option<Expr> {
match ty.as_adt() {
Some(hir::Adt::Enum(x)) => {
if let &[variant] = &*x.variants(db) {
if variant.kind(db) == hir::StructKind::Unit {
- let path = ast::make::path_qualified(
+ let path = make::path_qualified(
path,
- syntax::ast::make::path_segment(ast::make::name_ref(
- &variant.name(db).to_smol_str(),
- )),
+ make::path_segment(make::name_ref(&variant.name(db).to_smol_str())),
);
- return Some(syntax::ast::make::expr_path(path));
+ return Some(make::expr_path(path));
}
}
}
Some(hir::Adt::Struct(x)) if x.kind(db) == StructKind::Unit => {
- return Some(syntax::ast::make::expr_path(path));
+ return Some(make::expr_path(path));
}
_ => {}
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
index f54cdd63b..7ca0a0eab 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
@@ -157,6 +157,7 @@ struct S;
fn macro_diag_builtin() {
check_diagnostics(
r#"
+//- minicore: fmt
#[rustc_builtin_macro]
macro_rules! env {}
@@ -166,9 +167,6 @@ macro_rules! include {}
#[rustc_builtin_macro]
macro_rules! compile_error {}
-#[rustc_builtin_macro]
-macro_rules! format_args { () => {} }
-
fn main() {
// Test a handful of built-in (eager) macros:
@@ -189,7 +187,7 @@ fn main() {
// Lazy:
format_args!();
- //^^^^^^^^^^^ error: no rule matches input tokens
+ //^^^^^^^^^^^ error: Syntax Error in Expansion: expected expression
}
"#,
);
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs
index 6238c7e09..8265e0b1c 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mismatched_arg_count.rs
@@ -1,10 +1,37 @@
+use either::Either;
+use hir::InFile;
use syntax::{
ast::{self, HasArgList},
- AstNode, TextRange,
+ AstNode, SyntaxNodePtr, TextRange,
};
use crate::{adjusted_display_range, Diagnostic, DiagnosticCode, DiagnosticsContext};
+// Diagnostic: mismatched-tuple-struct-pat-arg-count
+//
+// This diagnostic is triggered if a function is invoked with an incorrect amount of arguments.
+pub(crate) fn mismatched_tuple_struct_pat_arg_count(
+ ctx: &DiagnosticsContext<'_>,
+ d: &hir::MismatchedTupleStructPatArgCount,
+) -> Diagnostic {
+ let s = if d.found == 1 { "" } else { "s" };
+ let s2 = if d.expected == 1 { "" } else { "s" };
+ let message = format!(
+ "this pattern has {} field{s}, but the corresponding tuple struct has {} field{s2}",
+ d.found, d.expected
+ );
+ Diagnostic::new(
+ DiagnosticCode::RustcHardError("E0023"),
+ message,
+ invalid_args_range(
+ ctx,
+ d.expr_or_pat.clone().map(|it| it.either(Into::into, Into::into)),
+ d.expected,
+ d.found,
+ ),
+ )
+}
+
// Diagnostic: mismatched-arg-count
//
// This diagnostic is triggered if a function is invoked with an incorrect amount of arguments.
@@ -14,31 +41,63 @@ pub(crate) fn mismatched_arg_count(
) -> Diagnostic {
let s = if d.expected == 1 { "" } else { "s" };
let message = format!("expected {} argument{s}, found {}", d.expected, d.found);
- Diagnostic::new(DiagnosticCode::RustcHardError("E0107"), message, invalid_args_range(ctx, d))
+ Diagnostic::new(
+ DiagnosticCode::RustcHardError("E0107"),
+ message,
+ invalid_args_range(ctx, d.call_expr.clone().map(Into::into), d.expected, d.found),
+ )
}
-fn invalid_args_range(ctx: &DiagnosticsContext<'_>, d: &hir::MismatchedArgCount) -> TextRange {
- adjusted_display_range::<ast::Expr>(ctx, d.call_expr.clone().map(|it| it.into()), &|expr| {
- let arg_list = match expr {
- ast::Expr::CallExpr(call) => call.arg_list()?,
- ast::Expr::MethodCallExpr(call) => call.arg_list()?,
+fn invalid_args_range(
+ ctx: &DiagnosticsContext<'_>,
+ source: InFile<SyntaxNodePtr>,
+ expected: usize,
+ found: usize,
+) -> TextRange {
+ adjusted_display_range::<Either<ast::Expr, ast::TupleStructPat>>(ctx, source, &|expr| {
+ let (text_range, r_paren_token, expected_arg) = match expr {
+ Either::Left(ast::Expr::CallExpr(call)) => {
+ let arg_list = call.arg_list()?;
+ (
+ arg_list.syntax().text_range(),
+ arg_list.r_paren_token(),
+ arg_list.args().nth(expected).map(|it| it.syntax().text_range()),
+ )
+ }
+ Either::Left(ast::Expr::MethodCallExpr(call)) => {
+ let arg_list = call.arg_list()?;
+ (
+ arg_list.syntax().text_range(),
+ arg_list.r_paren_token(),
+ arg_list.args().nth(expected).map(|it| it.syntax().text_range()),
+ )
+ }
+ Either::Right(pat) => {
+ let r_paren = pat.r_paren_token()?;
+ let l_paren = pat.l_paren_token()?;
+ (
+ l_paren.text_range().cover(r_paren.text_range()),
+ Some(r_paren),
+ pat.fields().nth(expected).map(|it| it.syntax().text_range()),
+ )
+ }
_ => return None,
};
- if d.found < d.expected {
- if d.found == 0 {
- return Some(arg_list.syntax().text_range());
+ if found < expected {
+ if found == 0 {
+ return Some(text_range);
}
- if let Some(r_paren) = arg_list.r_paren_token() {
+ if let Some(r_paren) = r_paren_token {
return Some(r_paren.text_range());
}
}
- if d.expected < d.found {
- if d.expected == 0 {
- return Some(arg_list.syntax().text_range());
+ if expected < found {
+ if expected == 0 {
+ return Some(text_range);
}
- let zip = arg_list.args().nth(d.expected).zip(arg_list.r_paren_token());
+ let zip = expected_arg.zip(r_paren_token);
if let Some((arg, r_paren)) = zip {
- return Some(arg.syntax().text_range().cover(r_paren.text_range()));
+ return Some(arg.cover(r_paren.text_range()));
}
}
@@ -331,4 +390,21 @@ fn g() {
"#,
)
}
+
+ #[test]
+ fn tuple_struct_pat() {
+ check_diagnostics(
+ r#"
+struct S(u32, u32);
+fn f(
+ S(a, b, c): S,
+ // ^^ error: this pattern has 3 fields, but the corresponding tuple struct has 2 fields
+ S(): S,
+ // ^^ error: this pattern has 0 fields, but the corresponding tuple struct has 2 fields
+ S(e, f, .., g, d): S
+ // ^^^^^^^^^ error: this pattern has 4 fields, but the corresponding tuple struct has 2 fields
+) {}
+"#,
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
index 82a9a3bd5..06b03d3d1 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
@@ -319,6 +319,7 @@ fn main() {
match Either::A {
Either::A => (),
Either::B() => (),
+ // ^^ error: this pattern has 0 fields, but the corresponding tuple struct has 1 field
}
}
"#,
@@ -334,9 +335,11 @@ enum A { B(isize, isize), C }
fn main() {
match A::B(1, 2) {
A::B(_, _, _) => (),
+ // ^^ error: this pattern has 3 fields, but the corresponding tuple struct has 2 fields
}
match A::B(1, 2) {
A::C(_) => (),
+ // ^^^ error: this pattern has 1 field, but the corresponding tuple struct has 0 fields
}
}
"#,
@@ -846,6 +849,7 @@ fn main() {
struct Foo { }
fn main(f: Foo) {
match f { Foo { bar } => () }
+ // ^^^ error: no such field
}
"#,
);
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index e0c3bedce..d056e5c85 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -76,7 +76,7 @@ pub(crate) fn unused_mut(ctx: &DiagnosticsContext<'_>, d: &hir::UnusedMut) -> Di
"variable does not need to be mutable",
ast,
)
- .experimental() // Not supporting `#[allow(unused_mut)]` leads to false positive.
+ .experimental() // Not supporting `#[allow(unused_mut)]` in proc macros leads to false positive.
.with_fixes(fixes)
}
@@ -1173,4 +1173,27 @@ fn f() {
"#,
);
}
+
+ #[test]
+ fn regression_15623() {
+ check_diagnostics(
+ r#"
+//- minicore: fn
+
+struct Foo;
+
+impl Foo {
+ fn needs_mut(&mut self) {}
+}
+
+fn foo(mut foo: Foo) {
+ let mut call_me = || {
+ let 0 = 1 else { return };
+ foo.needs_mut();
+ };
+ call_me();
+}
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
index a34a5824f..290c16c9d 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
@@ -1,3 +1,4 @@
+use either::Either;
use hir::{db::ExpandDatabase, HasSource, HirDisplay, Semantics};
use ide_db::{base_db::FileId, source_change::SourceChange, RootDatabase};
use syntax::{
@@ -12,22 +13,39 @@ use crate::{fix, Assist, Diagnostic, DiagnosticCode, DiagnosticsContext};
//
// This diagnostic is triggered if created structure does not have field provided in record.
pub(crate) fn no_such_field(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Diagnostic {
- Diagnostic::new_with_syntax_node_ptr(
- ctx,
- DiagnosticCode::RustcHardError("E0559"),
- "no such field",
- d.field.clone().map(|it| it.into()),
- )
- .with_fixes(fixes(ctx, d))
+ let node = d.field.clone().map(|it| it.either(Into::into, Into::into));
+ if d.private {
+ // FIXME: quickfix to add required visibility
+ Diagnostic::new_with_syntax_node_ptr(
+ ctx,
+ DiagnosticCode::RustcHardError("E0451"),
+ "field is private",
+ node,
+ )
+ } else {
+ Diagnostic::new_with_syntax_node_ptr(
+ ctx,
+ DiagnosticCode::RustcHardError("E0559"),
+ "no such field",
+ node,
+ )
+ .with_fixes(fixes(ctx, d))
+ }
}
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Option<Vec<Assist>> {
- let root = ctx.sema.db.parse_or_expand(d.field.file_id);
- missing_record_expr_field_fixes(
- &ctx.sema,
- d.field.file_id.original_file(ctx.sema.db),
- &d.field.value.to_node(&root),
- )
+ // FIXME: quickfix for pattern
+ match &d.field.value {
+ Either::Left(ptr) => {
+ let root = ctx.sema.db.parse_or_expand(d.field.file_id);
+ missing_record_expr_field_fixes(
+ &ctx.sema,
+ d.field.file_id.original_file(ctx.sema.db),
+ &ptr.to_node(&root),
+ )
+ }
+ _ => None,
+ }
}
fn missing_record_expr_field_fixes(
@@ -118,13 +136,34 @@ mod tests {
r#"
struct S { foo: i32, bar: () }
impl S {
- fn new() -> S {
+ fn new(
+ s@S {
+ //^ 💡 error: missing structure fields:
+ //| - bar
+ foo,
+ baz: baz2,
+ //^^^^^^^^^ error: no such field
+ qux
+ //^^^ error: no such field
+ }: S
+ ) -> S {
+ S {
+ //^ 💡 error: missing structure fields:
+ //| - bar
+ foo,
+ baz: baz2,
+ //^^^^^^^^^ error: no such field
+ qux
+ //^^^ error: no such field
+ } = s;
S {
//^ 💡 error: missing structure fields:
//| - bar
foo: 92,
baz: 62,
//^^^^^^^ 💡 error: no such field
+ qux
+ //^^^ error: no such field
}
}
}
@@ -295,4 +334,38 @@ fn main() {
"#,
)
}
+
+ #[test]
+ fn test_struct_field_private() {
+ check_diagnostics(
+ r#"
+mod m {
+ pub struct Struct {
+ field: u32,
+ field2: u32,
+ }
+}
+fn f(s@m::Struct {
+ field: f,
+ //^^^^^^^^ error: field is private
+ field2
+ //^^^^^^ error: field is private
+}: m::Struct) {
+ // assignee expression
+ m::Struct {
+ field: 0,
+ //^^^^^^^^ error: field is private
+ field2
+ //^^^^^^ error: field is private
+ } = s;
+ m::Struct {
+ field: 0,
+ //^^^^^^^^ error: field is private
+ field2
+ //^^^^^^ error: field is private
+ };
+}
+"#,
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/undeclared_label.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/undeclared_label.rs
index 7de9a9a32..495ea7487 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/undeclared_label.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/undeclared_label.rs
@@ -35,6 +35,25 @@ fn foo() {
}
#[test]
+ fn while_let_loop_with_label_in_condition() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ let mut optional = Some(0);
+
+ 'my_label: while let Some(a) = match optional {
+ None => break 'my_label,
+ Some(val) => Some(val),
+ } {
+ optional = None;
+ continue 'my_label;
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
fn for_loop() {
check_diagnostics(
r#"
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs
index 0aa439f79..c4ac59ec2 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs
@@ -1,3 +1,4 @@
+use hir::InFile;
use ide_db::{base_db::FileId, source_change::SourceChange};
use itertools::Itertools;
use syntax::{ast, AstNode, SyntaxNode};
@@ -39,6 +40,7 @@ pub(crate) fn useless_braces(
"Unnecessary braces in use statement".to_string(),
use_range,
)
+ .with_main_node(InFile::new(file_id.into(), node.clone()))
.with_fixes(Some(vec![fix(
"remove_braces",
"Remove unnecessary braces",
@@ -156,4 +158,23 @@ use a::{c, d::e};
"#,
);
}
+
+ #[test]
+ fn respect_lint_attributes_for_unused_braces() {
+ check_diagnostics(
+ r#"
+mod b {}
+#[allow(unused_braces)]
+use {b};
+"#,
+ );
+ check_diagnostics(
+ r#"
+mod b {}
+#[deny(unused_braces)]
+use {b};
+ //^^^ 💡 error: Unnecessary braces in use statement
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index b1b9b4b8e..ebe197a67 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -369,6 +369,7 @@ pub fn diagnostics(
AnyDiagnostic::UnresolvedProcMacro(d) => handlers::unresolved_proc_macro::unresolved_proc_macro(&ctx, &d, config.proc_macros_enabled, config.proc_attr_macros_enabled),
AnyDiagnostic::UnusedMut(d) => handlers::mutability_errors::unused_mut(&ctx, &d),
AnyDiagnostic::BreakOutsideOfLoop(d) => handlers::break_outside_of_loop::break_outside_of_loop(&ctx, &d),
+ AnyDiagnostic::MismatchedTupleStructPatArgCount(d) => handlers::mismatched_arg_count::mismatched_tuple_struct_pat_arg_count(&ctx, &d),
};
res.push(d)
}
@@ -432,7 +433,8 @@ fn handle_lint_attributes(
diagnostics_of_range: &mut FxHashMap<InFile<SyntaxNode>, &mut Diagnostic>,
) {
let file_id = sema.hir_file_for(root);
- for ev in root.preorder() {
+ let mut preorder = root.preorder();
+ while let Some(ev) = preorder.next() {
match ev {
syntax::WalkEvent::Enter(node) => {
for attr in node.children().filter_map(ast::Attr::cast) {
@@ -515,7 +517,7 @@ fn parse_lint_attribute(
let Some((tag, args_tt)) = attr.as_simple_call() else {
return;
};
- let serevity = match tag.as_str() {
+ let severity = match tag.as_str() {
"allow" => Severity::Allow,
"warn" => Severity::Warning,
"forbid" | "deny" => Severity::Error,
@@ -523,12 +525,12 @@ fn parse_lint_attribute(
};
for lint in parse_tt_as_comma_sep_paths(args_tt).into_iter().flatten() {
if let Some(lint) = lint.as_single_name_ref() {
- job(rustc_stack.entry(lint.to_string()).or_default(), serevity);
+ job(rustc_stack.entry(lint.to_string()).or_default(), severity);
}
if let Some(tool) = lint.qualifier().and_then(|x| x.as_single_name_ref()) {
if let Some(name_ref) = &lint.segment().and_then(|x| x.name_ref()) {
if tool.to_string() == "clippy" {
- job(clippy_stack.entry(name_ref.to_string()).or_default(), serevity);
+ job(clippy_stack.entry(name_ref.to_string()).or_default(), severity);
}
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
index a8e883690..60fcbbbd3 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
@@ -560,8 +560,10 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
placeholder_value.autoref_kind = self
.sema
.resolve_method_call_as_callable(code)
- .and_then(|callable| callable.receiver_param(self.sema.db))
- .map(|(self_param, _)| self_param.kind())
+ .and_then(|callable| {
+ let (self_param, _) = callable.receiver_param(self.sema.db)?;
+ Some(self_param.source(self.sema.db)?.value.kind())
+ })
.unwrap_or(ast::SelfParamKind::Owned);
}
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/annotations.rs b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
index f994c284c..fb79b5dc2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/annotations.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/annotations.rs
@@ -94,10 +94,9 @@ pub(crate) fn annotations(
enum_
.variants(db)
.into_iter()
- .map(|variant| {
+ .filter_map(|variant| {
variant.source(db).and_then(|node| name_range(db, node, file_id))
})
- .flatten()
.for_each(|range| {
let (annotation_range, target_position) = mk_ranges(range);
annotations.push(Annotation {
diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
index dd1d0d75c..f834f2ce5 100644
--- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
@@ -74,18 +74,20 @@ pub(crate) fn incoming_calls(
Some(calls.into_items())
}
-pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> {
+pub(crate) fn outgoing_calls(
+ db: &RootDatabase,
+ FilePosition { file_id, offset }: FilePosition,
+) -> Option<Vec<CallItem>> {
let sema = Semantics::new(db);
- let file_id = position.file_id;
let file = sema.parse(file_id);
let file = file.syntax();
- let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
+ let token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
IDENT => 1,
_ => 0,
})?;
let mut calls = CallLocations::default();
- sema.descend_into_macros(token)
+ sema.descend_into_macros(token, offset)
.into_iter()
.filter_map(|it| it.parent_ancestors().nth(1).and_then(ast::Item::cast))
.filter_map(|item| match item {
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
index d240127f3..37a177622 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -16,6 +16,7 @@ use hir::{db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, HasA
use ide_db::{
base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, SourceDatabase},
defs::{Definition, NameClass, NameRefClass},
+ documentation::{docs_with_rangemap, Documentation, HasDocs},
helpers::pick_best_token,
RootDatabase,
};
@@ -131,19 +132,19 @@ pub(crate) fn remove_links(markdown: &str) -> String {
// |===
pub(crate) fn external_docs(
db: &RootDatabase,
- position: &FilePosition,
+ FilePosition { file_id, offset }: FilePosition,
target_dir: Option<&OsStr>,
sysroot: Option<&OsStr>,
) -> Option<DocumentationLinks> {
let sema = &Semantics::new(db);
- let file = sema.parse(position.file_id).syntax().clone();
- let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
+ let file = sema.parse(file_id).syntax().clone();
+ let token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
IDENT | INT_NUMBER | T![self] => 3,
T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
})?;
- let token = sema.descend_into_macros_single(token);
+ let token = sema.descend_into_macros_single(token, offset);
let node = token.parent()?;
let definition = match_ast! {
@@ -171,7 +172,7 @@ pub(crate) fn external_docs(
/// Extracts all links from a given markdown text returning the definition text range, link-text
/// and the namespace if known.
pub(crate) fn extract_definitions_from_docs(
- docs: &hir::Documentation,
+ docs: &Documentation,
) -> Vec<(TextRange, String, Option<hir::Namespace>)> {
Parser::new_with_broken_link_callback(
docs.as_str(),
@@ -285,7 +286,7 @@ impl DocCommentToken {
let original_start = doc_token.text_range().start();
let relative_comment_offset = offset - original_start - prefix_len;
- sema.descend_into_macros(doc_token).into_iter().find_map(|t| {
+ sema.descend_into_macros(doc_token, offset).into_iter().find_map(|t| {
let (node, descended_prefix_len) = match_ast! {
match t {
ast::Comment(comment) => (t.parent()?, TextSize::try_from(comment.prefix().len()).ok()?),
@@ -297,7 +298,7 @@ impl DocCommentToken {
let abs_in_expansion_offset = token_start + relative_comment_offset + descended_prefix_len;
let (attributes, def) = doc_attributes(sema, &node)?;
- let (docs, doc_mapping) = attributes.docs_with_rangemap(sema.db)?;
+ let (docs, doc_mapping) = docs_with_rangemap(sema.db, &attributes)?;
let (in_expansion_range, link, ns) =
extract_definitions_from_docs(&docs).into_iter().find_map(|(range, link, ns)| {
let mapped = doc_mapping.map(range)?;
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
index 05a64b33b..9ae70ae66 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
@@ -1,10 +1,11 @@
use std::ffi::OsStr;
use expect_test::{expect, Expect};
-use hir::{HasAttrs, Semantics};
+use hir::Semantics;
use ide_db::{
base_db::{FilePosition, FileRange},
defs::Definition,
+ documentation::{Documentation, HasDocs},
RootDatabase,
};
use itertools::Itertools;
@@ -78,7 +79,7 @@ fn check_doc_links(ra_fixture: &str) {
fn def_under_cursor(
sema: &Semantics<'_, RootDatabase>,
position: &FilePosition,
-) -> (Definition, hir::Documentation) {
+) -> (Definition, Documentation) {
let (docs, def) = sema
.parse(position.file_id)
.syntax()
@@ -96,7 +97,7 @@ fn def_under_cursor(
fn node_to_def(
sema: &Semantics<'_, RootDatabase>,
node: &SyntaxNode,
-) -> Option<Option<(Option<hir::Documentation>, Definition)>> {
+) -> Option<Option<(Option<Documentation>, Definition)>> {
Some(match_ast! {
match node {
ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Module(def))),
@@ -518,6 +519,62 @@ fn function();
}
#[test]
+fn doc_links_field() {
+ check_doc_links(
+ r#"
+/// [`S::f`]
+/// [`S2::f`]
+/// [`T::0`]
+/// [`U::a`]
+/// [`E::A::f`]
+/// [`E::B::0`]
+struct S$0 {
+ f: i32,
+ //^ S::f
+ //^ S2::f
+}
+type S2 = S;
+struct T(i32);
+ //^^^ T::0
+union U {
+ a: i32,
+ //^ U::a
+}
+enum E {
+ A { f: i32 },
+ //^ E::A::f
+ B(i32),
+ //^^^ E::B::0
+}
+"#,
+ );
+}
+
+#[test]
+fn doc_links_field_via_self() {
+ check_doc_links(
+ r#"
+/// [`Self::f`]
+struct S$0 {
+ f: i32,
+ //^ Self::f
+}
+"#,
+ );
+}
+
+#[test]
+fn doc_links_tuple_field_via_self() {
+ check_doc_links(
+ r#"
+/// [`Self::0`]
+struct S$0(i32);
+ //^^^ Self::0
+"#,
+ );
+}
+
+#[test]
fn rewrite_html_root_url() {
check_rewrite(
r#"
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index d6bbf2bf7..119a9c7c3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -40,28 +40,33 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
// struct Bar;
// ```
- let derive = sema.descend_into_macros(tok.clone()).into_iter().find_map(|descended| {
- let hir_file = sema.hir_file_for(&descended.parent()?);
- if !hir_file.is_derive_attr_pseudo_expansion(db) {
- return None;
- }
+ let derive =
+ sema.descend_into_macros(tok.clone(), 0.into()).into_iter().find_map(|descended| {
+ let hir_file = sema.hir_file_for(&descended.parent()?);
+ if !hir_file.is_derive_attr_pseudo_expansion(db) {
+ return None;
+ }
- let name = descended.parent_ancestors().filter_map(ast::Path::cast).last()?.to_string();
- // up map out of the #[derive] expansion
- let token = hir::InFile::new(hir_file, descended).upmap(db)?.value;
- let attr = token.parent_ancestors().find_map(ast::Attr::cast)?;
- let expansions = sema.expand_derive_macro(&attr)?;
- let idx = attr
- .token_tree()?
- .token_trees_and_tokens()
- .filter_map(NodeOrToken::into_token)
- .take_while(|it| it != &token)
- .filter(|it| it.kind() == T![,])
- .count();
- let expansion =
- format(db, SyntaxKind::MACRO_ITEMS, position.file_id, expansions.get(idx).cloned()?);
- Some(ExpandedMacro { name, expansion })
- });
+ let name = descended.parent_ancestors().filter_map(ast::Path::cast).last()?.to_string();
+ // up map out of the #[derive] expansion
+ let token = hir::InFile::new(hir_file, descended).upmap(db)?.value;
+ let attr = token.parent_ancestors().find_map(ast::Attr::cast)?;
+ let expansions = sema.expand_derive_macro(&attr)?;
+ let idx = attr
+ .token_tree()?
+ .token_trees_and_tokens()
+ .filter_map(NodeOrToken::into_token)
+ .take_while(|it| it != &token)
+ .filter(|it| it.kind() == T![,])
+ .count();
+ let expansion = format(
+ db,
+ SyntaxKind::MACRO_ITEMS,
+ position.file_id,
+ expansions.get(idx).cloned()?,
+ );
+ Some(ExpandedMacro { name, expansion })
+ });
if derive.is_some() {
return derive;
diff --git a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
index f90618222..3d89599c5 100644
--- a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
@@ -17,8 +17,6 @@ use crate::FileRange;
// Extends or shrinks the current selection to the encompassing syntactic construct
// (expression, statement, item, module, etc). It works with multiple cursors.
//
-// This is a standard LSP feature and not a protocol extension.
-//
// |===
// | Editor | Shortcut
//
@@ -142,8 +140,10 @@ fn extend_tokens_from_range(
// compute original mapped token range
let extended = {
- let fst_expanded = sema.descend_into_macros_single(first_token.clone());
- let lst_expanded = sema.descend_into_macros_single(last_token.clone());
+ let fst_expanded =
+ sema.descend_into_macros_single(first_token.clone(), original_range.start());
+ let lst_expanded =
+ sema.descend_into_macros_single(last_token.clone(), original_range.end());
let mut lca =
algo::least_common_ancestor(&fst_expanded.parent()?, &lst_expanded.parent()?)?;
lca = shallowest_node(&lca);
@@ -154,13 +154,16 @@ fn extend_tokens_from_range(
};
// Compute parent node range
- let validate = |token: &SyntaxToken| -> bool {
- let expanded = sema.descend_into_macros_single(token.clone());
- let parent = match expanded.parent() {
- Some(it) => it,
- None => return false,
- };
- algo::least_common_ancestor(&extended, &parent).as_ref() == Some(&extended)
+ let validate = |offset: TextSize| {
+ let extended = &extended;
+ move |token: &SyntaxToken| -> bool {
+ let expanded = sema.descend_into_macros_single(token.clone(), offset);
+ let parent = match expanded.parent() {
+ Some(it) => it,
+ None => return false,
+ };
+ algo::least_common_ancestor(extended, &parent).as_ref() == Some(extended)
+ }
};
// Find the first and last text range under expanded parent
@@ -168,14 +171,14 @@ fn extend_tokens_from_range(
let token = token.prev_token()?;
skip_trivia_token(token, Direction::Prev)
})
- .take_while(validate)
+ .take_while(validate(original_range.start()))
.last()?;
let last = successors(Some(last_token), |token| {
let token = token.next_token()?;
skip_trivia_token(token, Direction::Next)
})
- .take_while(validate)
+ .take_while(validate(original_range.end()))
.last()?;
let range = first.text_range().cover(last.text_range());
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs
index c39c696cf..7e0fab426 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs
@@ -20,16 +20,16 @@ use crate::{
// - fields in patterns will navigate to the field declaration of the struct, union or variant
pub(crate) fn goto_declaration(
db: &RootDatabase,
- position: FilePosition,
+ position @ FilePosition { file_id, offset }: FilePosition,
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
let sema = Semantics::new(db);
- let file = sema.parse(position.file_id).syntax().clone();
+ let file = sema.parse(file_id).syntax().clone();
let original_token = file
- .token_at_offset(position.offset)
+ .token_at_offset(offset)
.find(|it| matches!(it.kind(), IDENT | T![self] | T![super] | T![crate] | T![Self]))?;
let range = original_token.text_range();
let info: Vec<NavigationTarget> = sema
- .descend_into_macros(original_token)
+ .descend_into_macros(original_token, offset)
.iter()
.filter_map(|token| {
let parent = token.parent()?;
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index 21471ab2a..e09b9f391 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -29,45 +29,39 @@ use syntax::{ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T};
// image::https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif[]
pub(crate) fn goto_definition(
db: &RootDatabase,
- position: FilePosition,
+ FilePosition { file_id, offset }: FilePosition,
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
let sema = &Semantics::new(db);
- let file = sema.parse(position.file_id).syntax().clone();
- let original_token =
- pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
- IDENT
- | INT_NUMBER
- | LIFETIME_IDENT
- | T![self]
- | T![super]
- | T![crate]
- | T![Self]
- | COMMENT => 4,
- // index and prefix ops
- T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
- kind if kind.is_keyword() => 2,
- T!['('] | T![')'] => 2,
- kind if kind.is_trivia() => 0,
- _ => 1,
- })?;
+ let file = sema.parse(file_id).syntax().clone();
+ let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
+ IDENT
+ | INT_NUMBER
+ | LIFETIME_IDENT
+ | T![self]
+ | T![super]
+ | T![crate]
+ | T![Self]
+ | COMMENT => 4,
+ // index and prefix ops
+ T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
+ kind if kind.is_keyword() => 2,
+ T!['('] | T![')'] => 2,
+ kind if kind.is_trivia() => 0,
+ _ => 1,
+ })?;
if let Some(doc_comment) = token_as_doc_comment(&original_token) {
- return doc_comment.get_definition_with_descend_at(
- sema,
- position.offset,
- |def, _, link_range| {
- let nav = def.try_to_nav(db)?;
- Some(RangeInfo::new(link_range, vec![nav]))
- },
- );
+ return doc_comment.get_definition_with_descend_at(sema, offset, |def, _, link_range| {
+ let nav = def.try_to_nav(db)?;
+ Some(RangeInfo::new(link_range, vec![nav]))
+ });
}
let navs = sema
- .descend_into_macros(original_token.clone())
+ .descend_into_macros(original_token.clone(), offset)
.into_iter()
.filter_map(|token| {
let parent = token.parent()?;
if let Some(tt) = ast::TokenTree::cast(parent) {
- if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), position.file_id)
- {
+ if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), file_id) {
return Some(vec![x]);
}
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
index 37166bdbd..544c6b423 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
@@ -22,20 +22,19 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav};
// image::https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif[]
pub(crate) fn goto_implementation(
db: &RootDatabase,
- position: FilePosition,
+ FilePosition { file_id, offset }: FilePosition,
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
let sema = Semantics::new(db);
- let source_file = sema.parse(position.file_id);
+ let source_file = sema.parse(file_id);
let syntax = source_file.syntax().clone();
- let original_token =
- pick_best_token(syntax.token_at_offset(position.offset), |kind| match kind {
- IDENT | T![self] | INT_NUMBER => 1,
- _ => 0,
- })?;
+ let original_token = pick_best_token(syntax.token_at_offset(offset), |kind| match kind {
+ IDENT | T![self] | INT_NUMBER => 1,
+ _ => 0,
+ })?;
let range = original_token.text_range();
let navs =
- sema.descend_into_macros(original_token)
+ sema.descend_into_macros(original_token, offset)
.into_iter()
.filter_map(|token| token.parent().and_then(ast::NameLike::cast))
.filter_map(|node| match &node {
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
index 6048990f7..955923d76 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
@@ -16,13 +16,13 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav};
// image::https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif[]
pub(crate) fn goto_type_definition(
db: &RootDatabase,
- position: FilePosition,
+ FilePosition { file_id, offset }: FilePosition,
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
let sema = hir::Semantics::new(db);
- let file: ast::SourceFile = sema.parse(position.file_id);
+ let file: ast::SourceFile = sema.parse(file_id);
let token: SyntaxToken =
- pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind {
+ pick_best_token(file.syntax().token_at_offset(offset), |kind| match kind {
IDENT | INT_NUMBER | T![self] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
@@ -37,7 +37,7 @@ pub(crate) fn goto_type_definition(
}
};
let range = token.text_range();
- sema.descend_into_macros(token)
+ sema.descend_into_macros(token, offset)
.into_iter()
.filter_map(|token| {
let ty = sema
diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
index 43e89a334..46a0464e9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -15,6 +15,7 @@ use syntax::{
SyntaxKind::{self, IDENT, INT_NUMBER},
SyntaxNode, SyntaxToken, TextRange, T,
};
+use text_edit::TextSize;
use crate::{navigation_target::ToNav, references, NavigationTarget, TryToNav};
@@ -51,7 +52,7 @@ pub struct HighlightRelatedConfig {
pub(crate) fn highlight_related(
sema: &Semantics<'_, RootDatabase>,
config: HighlightRelatedConfig,
- FilePosition { offset, file_id }: FilePosition,
+ pos @ FilePosition { offset, file_id }: FilePosition,
) -> Option<Vec<HighlightedRange>> {
let _p = profile::span("highlight_related");
let syntax = sema.parse(file_id).syntax().clone();
@@ -79,7 +80,7 @@ pub(crate) fn highlight_related(
}
T![|] if config.closure_captures => highlight_closure_captures(sema, token, file_id),
T![move] if config.closure_captures => highlight_closure_captures(sema, token, file_id),
- _ if config.references => highlight_references(sema, &syntax, token, file_id),
+ _ if config.references => highlight_references(sema, &syntax, token, pos),
_ => None,
}
}
@@ -129,9 +130,9 @@ fn highlight_references(
sema: &Semantics<'_, RootDatabase>,
node: &SyntaxNode,
token: SyntaxToken,
- file_id: FileId,
+ FilePosition { file_id, offset }: FilePosition,
) -> Option<Vec<HighlightedRange>> {
- let defs = find_defs(sema, token.clone());
+ let defs = find_defs(sema, token.clone(), offset);
let usages = defs
.iter()
.filter_map(|&d| {
@@ -455,8 +456,12 @@ fn cover_range(r0: Option<TextRange>, r1: Option<TextRange>) -> Option<TextRange
}
}
-fn find_defs(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> FxHashSet<Definition> {
- sema.descend_into_macros(token)
+fn find_defs(
+ sema: &Semantics<'_, RootDatabase>,
+ token: SyntaxToken,
+ offset: TextSize,
+) -> FxHashSet<Definition> {
+ sema.descend_into_macros(token, offset)
.into_iter()
.filter_map(|token| IdentClass::classify_token(sema, &token))
.map(IdentClass::definitions_no_ops)
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 40659e6c2..21934b948 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -162,9 +162,9 @@ fn hover_simple(
// prefer descending the same token kind in attribute expansions, in normal macros text
// equivalency is more important
let descended = if in_attr {
- [sema.descend_into_macros_with_kind_preference(original_token.clone())].into()
+ [sema.descend_into_macros_with_kind_preference(original_token.clone(), offset)].into()
} else {
- sema.descend_into_macros_with_same_text(original_token.clone())
+ sema.descend_into_macros_with_same_text(original_token.clone(), offset)
};
let descended = || descended.iter();
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index a33a6ee18..f72ce37d1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -3,12 +3,13 @@ use std::fmt::Display;
use either::Either;
use hir::{
- Adt, AsAssocItem, AttributeTemplate, CaptureKind, HasAttrs, HasSource, HirDisplay, Layout,
- LayoutError, Semantics, TypeInfo,
+ Adt, AsAssocItem, AttributeTemplate, CaptureKind, HasSource, HirDisplay, Layout, LayoutError,
+ Semantics, TypeInfo,
};
use ide_db::{
base_db::SourceDatabase,
defs::Definition,
+ documentation::{Documentation, HasDocs},
famous_defs::FamousDefs,
generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
syntax_helpers::insert_whitespace_into_node,
@@ -470,7 +471,7 @@ pub(super) fn definition(
Definition::SelfType(impl_def) => {
impl_def.self_ty(db).as_adt().map(|adt| label_and_docs(db, adt))?
}
- Definition::GenericParam(it) => label_and_docs(db, it),
+ Definition::GenericParam(it) => (it.display(db).to_string(), None),
Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db).display(db))),
Definition::ExternCrateDecl(it) => label_and_docs(db, it),
// FIXME: We should be able to show more info about these
@@ -616,9 +617,9 @@ fn render_builtin_attr(db: &RootDatabase, attr: hir::BuiltinAttr) -> Option<Mark
markup(Some(docs.replace('*', "\\*")), desc, None)
}
-fn label_and_docs<D>(db: &RootDatabase, def: D) -> (String, Option<hir::Documentation>)
+fn label_and_docs<D>(db: &RootDatabase, def: D) -> (String, Option<Documentation>)
where
- D: HasAttrs + HirDisplay,
+ D: HasDocs + HirDisplay,
{
let label = def.display(db).to_string();
let docs = def.docs(db);
@@ -631,9 +632,9 @@ fn label_and_layout_info_and_docs<D, E, E2>(
config: &HoverConfig,
layout_extractor: E,
layout_offset_extractor: E2,
-) -> (String, Option<hir::Documentation>)
+) -> (String, Option<Documentation>)
where
- D: HasAttrs + HirDisplay,
+ D: HasDocs + HirDisplay,
E: Fn(&D) -> Result<Layout, LayoutError>,
E2: Fn(&Layout) -> Option<u64>,
{
@@ -657,9 +658,9 @@ fn label_value_and_layout_info_and_docs<D, E, E2, E3, V>(
value_extractor: E,
layout_extractor: E2,
layout_tag_extractor: E3,
-) -> (String, Option<hir::Documentation>)
+) -> (String, Option<Documentation>)
where
- D: HasAttrs + HirDisplay,
+ D: HasDocs + HirDisplay,
E: Fn(&D) -> Option<V>,
E2: Fn(&D) -> Result<Layout, LayoutError>,
E3: Fn(&Layout) -> Option<usize>,
@@ -686,9 +687,9 @@ fn label_value_and_docs<D, E, V>(
db: &RootDatabase,
def: D,
value_extractor: E,
-) -> (String, Option<hir::Documentation>)
+) -> (String, Option<Documentation>)
where
- D: HasAttrs + HirDisplay,
+ D: HasDocs + HirDisplay,
E: Fn(&D) -> Option<V>,
V: Display,
{
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index ddc71dffa..81d6db564 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -1557,6 +1557,49 @@ fn test_hover_function_show_types() {
}
#[test]
+fn test_hover_function_associated_type_params() {
+ check(
+ r#"
+trait Foo { type Bar; }
+impl Foo for i32 { type Bar = i64; }
+fn foo(arg: <i32 as Foo>::Bar) {}
+fn main() { foo$0; }
+"#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ fn foo(arg: <i32 as Foo>::Bar)
+ ```
+ "#]],
+ );
+
+ check(
+ r#"
+trait Foo<T> { type Bar<U>; }
+impl Foo<i64> for i32 { type Bar<U> = i32; }
+fn foo(arg: <<i32 as Foo<i64>>::Bar<i8> as Foo<i64>>::Bar<i8>) {}
+fn main() { foo$0; }
+"#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ fn foo(arg: <<i32 as Foo<i64>>::Bar<i8> as Foo<i64>>::Bar<i8>)
+ ```
+ "#]],
+ );
+}
+
+#[test]
fn test_hover_function_pointer_show_identifiers() {
check(
r#"type foo$0 = fn(a: i32, b: i32) -> i32;"#,
@@ -3292,7 +3335,50 @@ struct S$0T<const C: usize = 1, T = Foo>(T);
```
```rust
- struct ST<const C: usize, T = Foo>
+ struct ST<const C: usize = 1, T = Foo>
+ ```
+ "#]],
+ );
+}
+
+#[test]
+fn const_generic_default_value() {
+ check(
+ r#"
+struct Foo;
+struct S$0T<const C: usize = {40 + 2}, T = Foo>(T);
+"#,
+ expect![[r#"
+ *ST*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ struct ST<const C: usize = {const}, T = Foo>
+ ```
+ "#]],
+ );
+}
+
+#[test]
+fn const_generic_default_value_2() {
+ check(
+ r#"
+struct Foo;
+const VAL = 1;
+struct S$0T<const C: usize = VAL, T = Foo>(T);
+"#,
+ expect![[r#"
+ *ST*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ struct ST<const C: usize = VAL, T = Foo>
```
"#]],
);
@@ -6469,3 +6555,42 @@ fn test() {
"#]],
);
}
+
+#[test]
+fn generic_params_disabled_by_cfg() {
+ check(
+ r#"
+struct S<#[cfg(never)] T>;
+fn test() {
+ let s$0: S = S;
+}
+"#,
+ expect![[r#"
+ *s*
+
+ ```rust
+ let s: S // size = 0, align = 1
+ ```
+ "#]],
+ );
+}
+
+#[test]
+fn format_args_arg() {
+ check(
+ r#"
+//- minicore: fmt
+fn test() {
+ let foo = 0;
+ format_args!("{}", foo$0);
+}
+"#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ let foo: i32 // size = 4, align = 4
+ ```
+ "#]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
index 292591674..a5d070fe7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -52,6 +52,28 @@ pub struct InlayHintsConfig {
pub closure_style: ClosureStyle,
pub max_length: Option<usize>,
pub closing_brace_hints_min_lines: Option<usize>,
+ pub fields_to_resolve: InlayFieldsToResolve,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct InlayFieldsToResolve {
+ pub resolve_text_edits: bool,
+ pub resolve_hint_tooltip: bool,
+ pub resolve_label_tooltip: bool,
+ pub resolve_label_location: bool,
+ pub resolve_label_command: bool,
+}
+
+impl InlayFieldsToResolve {
+ pub const fn empty() -> Self {
+ Self {
+ resolve_text_edits: false,
+ resolve_hint_tooltip: false,
+ resolve_label_tooltip: false,
+ resolve_label_location: false,
+ resolve_label_command: false,
+ }
+ }
}
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -123,11 +145,13 @@ pub struct InlayHint {
pub label: InlayHintLabel,
/// Text edit to apply when "accepting" this inlay hint.
pub text_edit: Option<TextEdit>,
+ pub needs_resolve: bool,
}
impl InlayHint {
fn closing_paren_after(kind: InlayKind, range: TextRange) -> InlayHint {
InlayHint {
+ needs_resolve: false,
range,
kind,
label: InlayHintLabel::from(")"),
@@ -139,6 +163,7 @@ impl InlayHint {
}
fn opening_paren_before(kind: InlayKind, range: TextRange) -> InlayHint {
InlayHint {
+ needs_resolve: false,
range,
kind,
label: InlayHintLabel::from("("),
@@ -196,6 +221,10 @@ impl InlayHintLabel {
}),
}
}
+
+ pub fn needs_resolve(&self) -> bool {
+ self.parts.iter().any(|part| part.linked_location.is_some() || part.tooltip.is_some())
+ }
}
impl From<String> for InlayHintLabel {
@@ -529,6 +558,7 @@ fn closure_has_block_body(closure: &ast::ClosureExpr) -> bool {
#[cfg(test)]
mod tests {
+
use expect_test::Expect;
use hir::ClosureStyle;
use itertools::Itertools;
@@ -538,7 +568,7 @@ mod tests {
use crate::DiscriminantHints;
use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints};
- use super::ClosureReturnTypeHints;
+ use super::{ClosureReturnTypeHints, InlayFieldsToResolve};
pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig {
discriminant_hints: DiscriminantHints::Never,
@@ -559,6 +589,7 @@ mod tests {
param_names_for_lifetime_elision_hints: false,
max_length: None,
closing_brace_hints_min_lines: None,
+ fields_to_resolve: InlayFieldsToResolve::empty(),
};
pub(super) const TEST_CONFIG: InlayHintsConfig = InlayHintsConfig {
type_hints: true,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
index 6d6bd315e..631807d99 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
@@ -137,21 +137,23 @@ pub(super) fn hints(
}
_ => continue,
};
+ let label = InlayHintLabel::simple(
+ if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() },
+ Some(InlayTooltip::Markdown(format!(
+ "`{}` → `{}` ({coercion} coercion)",
+ source.display(sema.db),
+ target.display(sema.db),
+ ))),
+ None,
+ );
acc.push(InlayHint {
+ needs_resolve: label.needs_resolve(),
range: expr.syntax().text_range(),
pad_left: false,
pad_right: false,
position: if postfix { InlayHintPosition::After } else { InlayHintPosition::Before },
kind: InlayKind::Adjustment,
- label: InlayHintLabel::simple(
- if postfix { format!(".{}", text.trim_end()) } else { text.to_owned() },
- Some(InlayTooltip::Markdown(format!(
- "`{}` → `{}` ({coercion} coercion)",
- source.display(sema.db),
- target.display(sema.db),
- ))),
- None,
- ),
+ label,
text_edit: None,
});
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
index 07b9f9cc1..680035c72 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
@@ -99,6 +99,7 @@ pub(super) fn hints(
None => pat.syntax().text_range(),
};
acc.push(InlayHint {
+ needs_resolve: label.needs_resolve() || text_edit.is_some(),
range: match type_ascriptable {
Some(Some(t)) => text_range.cover(t.text_range()),
_ => text_range,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
index 343cf17e5..35504ffa7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
@@ -50,9 +50,10 @@ pub(super) fn hints(
_ => return,
};
acc.push(InlayHint {
+ needs_resolve: false,
range,
kind: InlayKind::BindingMode,
- label: r.to_string().into(),
+ label: r.into(),
text_edit: None,
position: InlayHintPosition::Before,
pad_left: false,
@@ -68,9 +69,10 @@ pub(super) fn hints(
hir::BindingMode::Ref(Mutability::Shared) => "ref",
};
acc.push(InlayHint {
+ needs_resolve: false,
range: pat.syntax().text_range(),
kind: InlayKind::BindingMode,
- label: bm.to_string().into(),
+ label: bm.into(),
text_edit: None,
position: InlayHintPosition::Before,
pad_left: false,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
index b621a8dda..12e46c0f8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/chaining.rs
@@ -57,10 +57,12 @@ pub(super) fn hints(
}
}
}
+ let label = label_of_ty(famous_defs, config, &ty)?;
acc.push(InlayHint {
+ needs_resolve: label.needs_resolve(),
range: expr.syntax().text_range(),
kind: InlayKind::Chaining,
- label: label_of_ty(famous_defs, config, &ty)?,
+ label,
text_edit: None,
position: InlayHintPosition::After,
pad_left: true,
@@ -128,6 +130,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 147..154,
@@ -152,6 +155,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
]
"#]],
@@ -221,6 +225,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 143..179,
@@ -245,6 +250,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
]
"#]],
@@ -298,6 +304,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 143..179,
@@ -322,6 +329,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
]
"#]],
@@ -389,6 +397,7 @@ fn main() {
"<i32, bool>>",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 246..265,
@@ -426,6 +435,7 @@ fn main() {
"<i32, bool>>",
],
text_edit: None,
+ needs_resolve: true,
},
]
"#]],
@@ -474,7 +484,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9289..9297,
+ range: 10739..10747,
},
),
tooltip: "",
@@ -487,7 +497,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9321..9325,
+ range: 10771..10775,
},
),
tooltip: "",
@@ -495,6 +505,7 @@ fn main() {
" = ()>",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 174..224,
@@ -511,7 +522,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9289..9297,
+ range: 10739..10747,
},
),
tooltip: "",
@@ -524,7 +535,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9321..9325,
+ range: 10771..10775,
},
),
tooltip: "",
@@ -532,6 +543,7 @@ fn main() {
" = ()>",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 174..206,
@@ -548,7 +560,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9289..9297,
+ range: 10739..10747,
},
),
tooltip: "",
@@ -561,7 +573,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9321..9325,
+ range: 10771..10775,
},
),
tooltip: "",
@@ -569,6 +581,7 @@ fn main() {
" = ()>",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 174..189,
@@ -593,6 +606,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
]
"#]],
@@ -655,6 +669,7 @@ fn main() {
],
},
),
+ needs_resolve: true,
},
InlayHint {
range: 145..185,
@@ -679,6 +694,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 145..168,
@@ -703,6 +719,7 @@ fn main() {
"",
],
text_edit: None,
+ needs_resolve: true,
},
InlayHint {
range: 222..228,
@@ -725,6 +742,7 @@ fn main() {
},
],
text_edit: None,
+ needs_resolve: true,
},
]
"#]],
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
index 2cefd5acd..2b68538c1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs
@@ -109,6 +109,7 @@ pub(super) fn hints(
let linked_location = name_range.map(|range| FileRange { file_id, range });
acc.push(InlayHint {
+ needs_resolve: linked_location.is_some(),
range: closing_token.text_range(),
kind: InlayKind::ClosingBrace,
label: InlayHintLabel::simple(label, None, linked_location),
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs
index 9d5defcbb..d691303c1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_captures.rs
@@ -31,9 +31,10 @@ pub(super) fn hints(
let range = closure.syntax().first_token()?.prev_token()?.text_range();
let range = TextRange::new(range.end() - TextSize::from(1), range.end());
acc.push(InlayHint {
+ needs_resolve: false,
range,
kind: InlayKind::ClosureCapture,
- label: InlayHintLabel::simple("move", None, None),
+ label: InlayHintLabel::from("move"),
text_edit: None,
position: InlayHintPosition::After,
pad_left: false,
@@ -43,6 +44,7 @@ pub(super) fn hints(
}
};
acc.push(InlayHint {
+ needs_resolve: false,
range: move_kw_range,
kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from("("),
@@ -59,23 +61,25 @@ pub(super) fn hints(
// force cache the source file, otherwise sema lookup will potentially panic
_ = sema.parse_or_expand(source.file());
+ let label = InlayHintLabel::simple(
+ format!(
+ "{}{}",
+ match capture.kind() {
+ hir::CaptureKind::SharedRef => "&",
+ hir::CaptureKind::UniqueSharedRef => "&unique ",
+ hir::CaptureKind::MutableRef => "&mut ",
+ hir::CaptureKind::Move => "",
+ },
+ capture.display_place(sema.db)
+ ),
+ None,
+ source.name().and_then(|name| name.syntax().original_file_range_opt(sema.db)),
+ );
acc.push(InlayHint {
+ needs_resolve: label.needs_resolve(),
range: move_kw_range,
kind: InlayKind::ClosureCapture,
- label: InlayHintLabel::simple(
- format!(
- "{}{}",
- match capture.kind() {
- hir::CaptureKind::SharedRef => "&",
- hir::CaptureKind::UniqueSharedRef => "&unique ",
- hir::CaptureKind::MutableRef => "&mut ",
- hir::CaptureKind::Move => "",
- },
- capture.display_place(sema.db)
- ),
- None,
- source.name().and_then(|name| name.syntax().original_file_range_opt(sema.db)),
- ),
+ label,
text_edit: None,
position: InlayHintPosition::After,
pad_left: false,
@@ -84,9 +88,10 @@ pub(super) fn hints(
if idx != last {
acc.push(InlayHint {
+ needs_resolve: false,
range: move_kw_range,
kind: InlayKind::ClosureCapture,
- label: InlayHintLabel::simple(", ", None, None),
+ label: InlayHintLabel::from(", "),
text_edit: None,
position: InlayHintPosition::After,
pad_left: false,
@@ -95,6 +100,7 @@ pub(super) fn hints(
}
}
acc.push(InlayHint {
+ needs_resolve: false,
range: move_kw_range,
kind: InlayKind::ClosureCapture,
label: InlayHintLabel::from(")"),
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
index 3b41db0f1..204967cd7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closure_ret.rs
@@ -64,6 +64,7 @@ pub(super) fn hints(
};
acc.push(InlayHint {
+ needs_resolve: label.needs_resolve() || text_edit.is_some(),
range: param_list.syntax().text_range(),
kind: InlayKind::Type,
label,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs
index c4d2ac75c..26dc6fa8b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs
@@ -79,6 +79,7 @@ fn variant_hints(
None,
);
acc.push(InlayHint {
+ needs_resolve: label.needs_resolve(),
range: match eq_token {
Some(t) => range.cover(t.text_range()),
_ => range,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
index 5fce11b78..7b05e32ad 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
@@ -22,6 +22,7 @@ pub(super) fn hints(
}
let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
+ needs_resolve: false,
range: t.text_range(),
kind: InlayKind::Lifetime,
label: label.into(),
@@ -185,6 +186,7 @@ pub(super) fn hints(
let angle_tok = gpl.l_angle_token()?;
let is_empty = gpl.generic_params().next().is_none();
acc.push(InlayHint {
+ needs_resolve: false,
range: angle_tok.text_range(),
kind: InlayKind::Lifetime,
label: format!(
@@ -200,6 +202,7 @@ pub(super) fn hints(
});
}
(None, allocated_lifetimes) => acc.push(InlayHint {
+ needs_resolve: false,
range: func.name()?.syntax().text_range(),
kind: InlayKind::GenericParamList,
label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
index fc297a8d8..f18e6421c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_static.rs
@@ -31,9 +31,10 @@ pub(super) fn hints(
if ty.lifetime().is_none() {
let t = ty.amp_token()?;
acc.push(InlayHint {
+ needs_resolve: false,
range: t.text_range(),
kind: InlayKind::Lifetime,
- label: "'static".to_owned().into(),
+ label: "'static".into(),
text_edit: None,
position: InlayHintPosition::After,
pad_left: false,
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
index c4f43f411..b4260d825 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
@@ -57,6 +57,7 @@ pub(super) fn hints(
let label =
InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location);
InlayHint {
+ needs_resolve: label.needs_resolve(),
range,
kind: InlayKind::Parameter,
label,
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index bf77d55d5..aee03d218 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -91,9 +91,9 @@ pub use crate::{
MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind,
},
inlay_hints::{
- AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints, InlayHint,
- InlayHintLabel, InlayHintLabelPart, InlayHintPosition, InlayHintsConfig, InlayKind,
- InlayTooltip, LifetimeElisionHints,
+ AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
+ InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintPosition,
+ InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
},
join_lines::JoinLinesConfig,
markup::Markup,
@@ -111,7 +111,7 @@ pub use crate::{
HighlightConfig, HlRange,
},
};
-pub use hir::{Documentation, Semantics};
+pub use hir::Semantics;
pub use ide_assists::{
Assist, AssistConfig, AssistId, AssistKind, AssistResolveStrategy, SingleResolve,
};
@@ -124,6 +124,7 @@ pub use ide_db::{
Cancelled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange,
SourceRoot, SourceRootId,
},
+ documentation::Documentation,
label::Label,
line_index::{LineCol, LineIndex},
search::{ReferenceCategory, SearchScope},
@@ -484,7 +485,7 @@ impl Analysis {
sysroot: Option<&OsStr>,
) -> Cancellable<doc_links::DocumentationLinks> {
self.with_db(|db| {
- doc_links::external_docs(db, &position, target_dir, sysroot).unwrap_or_default()
+ doc_links::external_docs(db, position, target_dir, sysroot).unwrap_or_default()
})
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 17f3771b1..2ca2b5b1d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -99,7 +99,7 @@ pub(crate) fn moniker(
});
}
let navs = sema
- .descend_into_macros(original_token.clone())
+ .descend_into_macros(original_token.clone(), offset)
.into_iter()
.filter_map(|token| {
IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops).map(|it| {
diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs
index d1479dd1e..32f211c6b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs
@@ -4,14 +4,15 @@ use std::fmt;
use either::Either;
use hir::{
- symbols::FileSymbol, AssocItem, Documentation, FieldSource, HasAttrs, HasContainer, HasSource,
- HirDisplay, HirFileId, InFile, LocalSource, ModuleSource,
+ symbols::FileSymbol, AssocItem, FieldSource, HasContainer, HasSource, HirDisplay, HirFileId,
+ InFile, LocalSource, ModuleSource,
};
use ide_db::{
base_db::{FileId, FileRange},
- SymbolKind,
+ defs::Definition,
+ documentation::{Documentation, HasDocs},
+ RootDatabase, SymbolKind,
};
-use ide_db::{defs::Definition, RootDatabase};
use stdx::never;
use syntax::{
ast::{self, HasName},
@@ -175,8 +176,12 @@ impl TryToNav for FileSymbol {
Some(NavigationTarget {
file_id: full_range.file_id,
- name: if self.is_alias { self.def.name(db)?.to_smol_str() } else { self.name.clone() },
- alias: if self.is_alias { Some(self.name.clone()) } else { None },
+ name: self
+ .is_alias
+ .then(|| self.def.name(db))
+ .flatten()
+ .map_or_else(|| self.name.clone(), |it| it.to_smol_str()),
+ alias: self.is_alias.then(|| self.name.clone()),
kind: Some(hir::ModuleDefId::from(self.def).into()),
full_range: full_range.range,
focus_range,
@@ -323,7 +328,7 @@ impl ToNavFromAst for hir::TraitAlias {
impl<D> TryToNav for D
where
- D: HasSource + ToNavFromAst + Copy + HasAttrs + HirDisplay,
+ D: HasSource + ToNavFromAst + Copy + HasDocs + HirDisplay,
D::Ast: ast::HasName,
{
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index 813f9ed94..2d0295692 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -126,7 +126,7 @@ pub(crate) fn find_defs<'a>(
)
});
token.map(|token| {
- sema.descend_into_macros_with_same_text(token)
+ sema.descend_into_macros_with_same_text(token, offset)
.into_iter()
.filter_map(|it| ast::NameLike::cast(it.parent()?))
.filter_map(move |name_like| {
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index dae8e71e8..ac9df5ed6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -2634,4 +2634,33 @@ use qux as frob;
// ",
// );
}
+
+ #[test]
+ fn disallow_renaming_for_non_local_definition() {
+ check(
+ "Baz",
+ r#"
+//- /lib.rs crate:lib new_source_root:library
+pub struct S;
+//- /main.rs crate:main deps:lib new_source_root:local
+use lib::S$0;
+"#,
+ "error: Cannot rename a non-local definition.",
+ );
+ }
+
+ #[test]
+ fn disallow_renaming_for_builtin_macros() {
+ check(
+ "Baz",
+ r#"
+//- minicore: derive, hash
+//- /main.rs crate:main
+use core::hash::Hash;
+#[derive(H$0ash)]
+struct A;
+ "#,
+ "error: Cannot rename a non-local definition.",
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index 5f87a7855..2d528c642 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -7,6 +7,7 @@ use ide_assists::utils::test_related_attribute;
use ide_db::{
base_db::{FilePosition, FileRange},
defs::Definition,
+ documentation::docs_from_attrs,
helpers::visit_file_defs,
search::SearchScope,
FxHashMap, FxHashSet, RootDatabase, SymbolKind,
@@ -496,7 +497,7 @@ const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] =
&["", "rust", "should_panic", "edition2015", "edition2018", "edition2021"];
fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool {
- attrs.docs().map_or(false, |doc| {
+ docs_from_attrs(attrs).map_or(false, |doc| {
let mut in_code_block = false;
for line in String::from(doc).lines() {
diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
index 7795be54e..e020b52e1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -4,12 +4,11 @@
use std::collections::BTreeSet;
use either::Either;
-use hir::{
- AssocItem, GenericParam, HasAttrs, HirDisplay, ModuleDef, PathResolution, Semantics, Trait,
-};
+use hir::{AssocItem, GenericParam, HirDisplay, ModuleDef, PathResolution, Semantics, Trait};
use ide_db::{
active_parameter::{callable_for_node, generic_def_for_node},
base_db::FilePosition,
+ documentation::{Documentation, HasDocs},
FxIndexMap,
};
use stdx::format_to;
@@ -28,7 +27,7 @@ use crate::RootDatabase;
/// edited.
#[derive(Debug)]
pub struct SignatureHelp {
- pub doc: Option<String>,
+ pub doc: Option<Documentation>,
pub signature: String,
pub active_parameter: Option<usize>,
parameters: Vec<TextRange>,
@@ -67,17 +66,20 @@ impl SignatureHelp {
}
/// Computes parameter information for the given position.
-pub(crate) fn signature_help(db: &RootDatabase, position: FilePosition) -> Option<SignatureHelp> {
+pub(crate) fn signature_help(
+ db: &RootDatabase,
+ FilePosition { file_id, offset }: FilePosition,
+) -> Option<SignatureHelp> {
let sema = Semantics::new(db);
- let file = sema.parse(position.file_id);
+ let file = sema.parse(file_id);
let file = file.syntax();
let token = file
- .token_at_offset(position.offset)
+ .token_at_offset(offset)
.left_biased()
// if the cursor is sandwiched between two space tokens and the call is unclosed
// this prevents us from leaving the CallExpression
.and_then(|tok| algo::skip_trivia_token(tok, Direction::Prev))?;
- let token = sema.descend_into_macros_single(token);
+ let token = sema.descend_into_macros_single(token, offset);
for node in token.parent_ancestors() {
match_ast! {
@@ -176,7 +178,7 @@ fn signature_help_for_call(
let mut fn_params = None;
match callable.kind() {
hir::CallableKind::Function(func) => {
- res.doc = func.docs(db).map(|it| it.into());
+ res.doc = func.docs(db);
format_to!(res.signature, "fn {}", func.name(db).display(db));
fn_params = Some(match callable.receiver_param(db) {
Some(_self) => func.params_without_self(db),
@@ -184,11 +186,11 @@ fn signature_help_for_call(
});
}
hir::CallableKind::TupleStruct(strukt) => {
- res.doc = strukt.docs(db).map(|it| it.into());
+ res.doc = strukt.docs(db);
format_to!(res.signature, "struct {}", strukt.name(db).display(db));
}
hir::CallableKind::TupleEnumVariant(variant) => {
- res.doc = variant.docs(db).map(|it| it.into());
+ res.doc = variant.docs(db);
format_to!(
res.signature,
"enum {}::{}",
@@ -202,7 +204,7 @@ fn signature_help_for_call(
res.signature.push('(');
{
if let Some((self_param, _)) = callable.receiver_param(db) {
- format_to!(res.signature, "{}", self_param)
+ format_to!(res.signature, "{}", self_param.display(db))
}
let mut buf = String::new();
for (idx, (pat, ty)) in callable.params(db).into_iter().enumerate() {
@@ -262,38 +264,38 @@ fn signature_help_for_generics(
let db = sema.db;
match generics_def {
hir::GenericDef::Function(it) => {
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
format_to!(res.signature, "fn {}", it.name(db).display(db));
}
hir::GenericDef::Adt(hir::Adt::Enum(it)) => {
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
format_to!(res.signature, "enum {}", it.name(db).display(db));
}
hir::GenericDef::Adt(hir::Adt::Struct(it)) => {
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
format_to!(res.signature, "struct {}", it.name(db).display(db));
}
hir::GenericDef::Adt(hir::Adt::Union(it)) => {
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
format_to!(res.signature, "union {}", it.name(db).display(db));
}
hir::GenericDef::Trait(it) => {
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
format_to!(res.signature, "trait {}", it.name(db).display(db));
}
hir::GenericDef::TraitAlias(it) => {
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
format_to!(res.signature, "trait {}", it.name(db).display(db));
}
hir::GenericDef::TypeAlias(it) => {
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
format_to!(res.signature, "type {}", it.name(db).display(db));
}
hir::GenericDef::Variant(it) => {
// In paths, generics of an enum can be specified *after* one of its variants.
// eg. `None::<u8>`
// We'll use the signature of the enum, but include the docs of the variant.
- res.doc = it.docs(db).map(|it| it.into());
+ res.doc = it.docs(db);
let enum_ = it.parent_enum(db);
format_to!(res.signature, "enum {}", enum_.name(db).display(db));
generics_def = enum_.into();
@@ -1315,6 +1317,25 @@ id! {
}
#[test]
+ fn fn_signature_for_method_call_defined_in_macro() {
+ check(
+ r#"
+macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
+struct S;
+id! {
+ impl S {
+ fn foo<'a>(&'a mut self) {}
+ }
+}
+fn test() { S.foo($0); }
+"#,
+ expect![[r#"
+ fn foo(&'a mut self)
+ "#]],
+ );
+ }
+
+ #[test]
fn call_info_for_lambdas() {
check(
r#"
diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
index d8696198d..aabd26da2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -12,6 +12,7 @@ use ide_db::{
};
use syntax::{AstNode, SyntaxKind::*, TextRange, T};
+use crate::inlay_hints::InlayFieldsToResolve;
use crate::{
hover::hover_for_definition,
inlay_hints::AdjustmentHintsMode,
@@ -125,6 +126,7 @@ impl StaticIndex<'_> {
max_length: Some(25),
closure_capture_hints: false,
closing_brace_hints_min_lines: Some(25),
+ fields_to_resolve: InlayFieldsToResolve::empty(),
},
file_id,
None,
diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs
index d2c77e2dc..c9ee460a1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/status.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/status.rs
@@ -66,6 +66,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
None => format!("{}", krate.into_raw()),
};
format_to!(buf, "Crate: {}\n", display_crate(krate));
+ format_to!(buf, "Enabled cfgs: {:?}\n", crate_graph[krate].cfg_options);
let deps = crate_graph[krate]
.dependencies
.iter()
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
index ae9723640..bb01c81d6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
@@ -395,10 +395,10 @@ fn traverse(
NodeOrToken::Token(token) if token.kind() != COMMENT => {
let token = match attr_or_derive_item {
Some(AttrOrDerive::Attr(_)) => {
- sema.descend_into_macros_with_kind_preference(token)
+ sema.descend_into_macros_with_kind_preference(token, 0.into())
}
Some(AttrOrDerive::Derive(_)) | None => {
- sema.descend_into_macros_single(token)
+ sema.descend_into_macros_single(token, 0.into())
}
};
match token.parent().and_then(ast::NameLike::cast) {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
index 2ed57e201..2ef131594 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
@@ -17,6 +17,7 @@ pub(super) fn highlight_format_string(
return;
}
+ // FIXME: Replace this with the HIR info we have now.
lex_format_specifiers(string, &mut |piece_range, kind| {
if let Some(highlight) = highlight_format_specifier(kind) {
stack.add(HlRange {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
index 8e96bfa01..7d00282fc 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
@@ -617,6 +617,7 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
CONST => SymbolKind::Const,
STATIC => SymbolKind::Static,
IDENT_PAT => SymbolKind::Local,
+ FORMAT_ARGS_ARG => SymbolKind::Local,
_ => return default.into(),
};
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
index 2657a6414..71f4d0724 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/inject.rs
@@ -5,8 +5,8 @@ use std::mem;
use either::Either;
use hir::{InFile, Semantics};
use ide_db::{
- active_parameter::ActiveParameter, base_db::FileId, defs::Definition, rust_doc::is_rust_fence,
- SymbolKind,
+ active_parameter::ActiveParameter, base_db::FileId, defs::Definition,
+ documentation::docs_with_rangemap, rust_doc::is_rust_fence, SymbolKind,
};
use syntax::{
ast::{self, AstNode, IsString, QuoteOffsets},
@@ -118,7 +118,7 @@ pub(super) fn doc_comment(
let src_file_id = src_file_id.into();
// Extract intra-doc links and emit highlights for them.
- if let Some((docs, doc_mapping)) = attributes.docs_with_rangemap(sema.db) {
+ if let Some((docs, doc_mapping)) = docs_with_rangemap(sema.db, &attributes) {
extract_definitions_from_docs(&docs)
.into_iter()
.filter_map(|(range, link, ns)| {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index 3ac8aa9cc..64e614cec 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -45,17 +45,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
</style>
<pre><code><span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">println</span> <span class="brace">{</span>
<span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="brace">{</span>
- <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>io<span class="colon">:</span><span class="colon">:</span>_print<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>format_args_nl<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+ <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>io<span class="colon">:</span><span class="colon">:</span>_print<span class="parenthesis">(</span>format_args_nl<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span><span class="parenthesis">)</span>
<span class="brace">}</span>
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">format_args</span> <span class="brace">{</span><span class="brace">}</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">const_format_args</span> <span class="brace">{</span><span class="brace">}</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute_bracket attribute">]</span>
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">format_args_nl</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">mod</span> <span class="module declaration">panic</span> <span class="brace">{</span>
@@ -75,7 +69,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_display<span class="parenthesis">(</span><span class="punctuation">&</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span>
<span class="parenthesis">)</span><span class="comma">,</span>
<span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="colon">:</span>expr<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span>
- <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_fmt<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>const_format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span><span class="parenthesis">)</span>
+ <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panicking<span class="colon">:</span><span class="colon">:</span>panic_fmt<span class="parenthesis">(</span>const_format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span><span class="parenthesis">)</span>
<span class="parenthesis">)</span><span class="comma">,</span>
<span class="brace">}</span>
<span class="brace">}</span>
@@ -92,7 +86,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">toho</span> <span class="brace">{</span>
<span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panic<span class="punctuation">!</span><span class="parenthesis">(</span><span class="string_literal">"not yet implemented"</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
- <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panic<span class="punctuation">!</span><span class="parenthesis">(</span><span class="string_literal">"not yet implemented: {}"</span><span class="comma">,</span> <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+ <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panic<span class="punctuation">!</span><span class="parenthesis">(</span><span class="string_literal">"not yet implemented: {}"</span><span class="comma">,</span> format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
@@ -114,18 +108,18 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"world"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "Hello, world!"</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"The number is </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "The number is 1"</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="parenthesis macro">(</span><span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="numeric_literal macro">4</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "(3, 4)"</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">value</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">value</span><span class="operator macro">=</span><span class="numeric_literal macro">4</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "4"</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">value</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">value</span><span class="operator macro">=</span><span class="numeric_literal macro">4</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "4"</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "1 2"</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">4</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">42</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "0042" with leading zerosV</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "2 1 1 2"</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">argument</span> <span class="operator macro">=</span> <span class="string_literal macro">"test"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "test"</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="none macro">name</span> <span class="operator macro">=</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "2 1"</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">a</span><span class="operator macro">=</span><span class="string_literal macro">"a"</span><span class="comma macro">,</span> <span class="none macro">b</span><span class="operator macro">=</span><span class="char_literal macro">'b'</span><span class="comma macro">,</span> <span class="none macro">c</span><span class="operator macro">=</span><span class="numeric_literal macro">3</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "a 3 b"</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">argument</span> <span class="operator macro">=</span> <span class="string_literal macro">"test"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "test"</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span> <span class="operator macro">=</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "2 1"</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">a</span><span class="operator macro">=</span><span class="string_literal macro">"a"</span><span class="comma macro">,</span> <span class="variable declaration macro">b</span><span class="operator macro">=</span><span class="char_literal macro">'b'</span><span class="comma macro">,</span> <span class="variable declaration macro">c</span><span class="operator macro">=</span><span class="numeric_literal macro">3</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "a 3 b"</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span> <span class="comment">// =&gt; "{2}"</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">width</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="none macro">width</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">width</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="variable declaration macro">width</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">&lt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">-</span><span class="format_specifier">&lt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">^</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
@@ -140,10 +134,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="variable">number</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="variable">prec</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="none macro">prec</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="none macro">number</span> <span class="operator macro">=</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 fractional digits"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="none macro">name</span><span class="operator macro">=</span><span class="numeric_literal macro">1234.56</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="none macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">&gt;</span><span class="numeric_literal">8</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 right-aligned characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="none macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="variable">number</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="variable">prec</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="variable declaration macro">prec</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="variable declaration macro">number</span> <span class="operator macro">=</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 fractional digits"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="numeric_literal macro">1234.56</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">&gt;</span><span class="numeric_literal">8</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 right-aligned characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">"{}"</span>
<span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">"{{}}"</span><span class="semicolon">;</span>
@@ -167,16 +161,24 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">c"</span><span class="escape_sequence">\u{FF}</span><span class="escape_sequence">\xFF</span><span class="string_literal">"</span><span class="semicolon">;</span> <span class="comment">// valid bytes, valid unicodes</span>
<span class="keyword">let</span> <span class="variable declaration reference">backslash</span> <span class="operator">=</span> <span class="string_literal">r"\\"</span><span class="semicolon">;</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">A</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">ничоси</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">A</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">ничоси</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">x</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> "</span><span class="comma macro">,</span> <span class="unresolved_reference macro">thingy</span><span class="comma macro">,</span> <span class="unresolved_reference macro">n2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">panic</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">panic</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"more </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> asdasd"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">toho</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"mov eax, </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">concat</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
- <span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="none macro">format_args</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="none macro">toho</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">panic</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">panic</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"more {}"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"{} asdasd"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro">toho</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="keyword">let</span> <span class="variable declaration">i</span><span class="colon">:</span> <span class="builtin_type">u64</span> <span class="operator">=</span> <span class="numeric_literal">3</span><span class="semicolon">;</span>
+ <span class="keyword">let</span> <span class="variable declaration">o</span><span class="colon">:</span> <span class="builtin_type">u64</span><span class="semicolon">;</span>
+ <span class="macro unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+ <span class="string_literal macro">"mov {0}, {1}"</span><span class="comma macro">,</span>
+ <span class="string_literal macro">"add {0}, 5"</span><span class="comma macro">,</span>
+ <span class="none macro">out</span><span class="parenthesis macro">(</span><span class="none macro">reg</span><span class="parenthesis macro">)</span> <span class="none macro">o</span><span class="comma macro">,</span>
+ <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="none macro">reg</span><span class="parenthesis macro">)</span> <span class="none macro">i</span><span class="comma macro">,</span>
+ <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
+ <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="macro macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+ <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="macro default_library library macro">format_args</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="macro macro">toho</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="brace">}</span></code></pre> \ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
index 8749d355c..542d89925 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
@@ -401,19 +401,14 @@ fn test_string_highlighting() {
// thus, we have to copy the macro definition from `std`
check_highlighting(
r#"
+//- minicore: fmt
macro_rules! println {
($($arg:tt)*) => ({
- $crate::io::_print($crate::format_args_nl!($($arg)*));
+ $crate::io::_print(format_args_nl!($($arg)*));
})
}
#[rustc_builtin_macro]
#[macro_export]
-macro_rules! format_args {}
-#[rustc_builtin_macro]
-#[macro_export]
-macro_rules! const_format_args {}
-#[rustc_builtin_macro]
-#[macro_export]
macro_rules! format_args_nl {}
mod panic {
@@ -433,7 +428,7 @@ mod panic {
$crate::panicking::panic_display(&$arg)
),
($fmt:expr, $($arg:tt)+) => (
- $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
+ $crate::panicking::panic_fmt(const_format_args!($fmt, $($arg)+))
),
}
}
@@ -450,7 +445,7 @@ macro_rules! concat {}
macro_rules! toho {
() => ($crate::panic!("not yet implemented"));
- ($($arg:tt)+) => ($crate::panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
+ ($($arg:tt)+) => ($crate::panic!("not yet implemented: {}", format_args!($($arg)+)));
}
fn main() {
@@ -534,7 +529,15 @@ fn main() {
assert!(true, "{}", 1);
assert!(true, "{} asdasd", 1);
toho!("{}fmt", 0);
- asm!("mov eax, {0}");
+ let i: u64 = 3;
+ let o: u64;
+ asm!(
+ "mov {0}, {1}",
+ "add {0}, 5",
+ out(reg) o,
+ in(reg) i,
+ );
+
format_args!(concat!("{}"), "{}");
format_args!("{} {} {} {} {} {}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash);
}"#,
diff --git a/src/tools/rust-analyzer/crates/ide/src/typing.rs b/src/tools/rust-analyzer/crates/ide/src/typing.rs
index c7e403f6b..b40509715 100644
--- a/src/tools/rust-analyzer/crates/ide/src/typing.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/typing.rs
@@ -32,7 +32,7 @@ use crate::SourceChange;
pub(crate) use on_enter::on_enter;
// Don't forget to add new trigger characters to `server_capabilities` in `caps.rs`.
-pub(crate) const TRIGGER_CHARS: &str = ".=<>{";
+pub(crate) const TRIGGER_CHARS: &str = ".=<>{(";
struct ExtendedTextEdit {
edit: TextEdit,
@@ -86,45 +86,57 @@ fn on_char_typed_inner(
if !stdx::always!(TRIGGER_CHARS.contains(char_typed)) {
return None;
}
- return match char_typed {
+ let conv = |text_edit: Option<TextEdit>| {
+ Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false })
+ };
+ match char_typed {
'.' => conv(on_dot_typed(&file.tree(), offset)),
'=' => conv(on_eq_typed(&file.tree(), offset)),
'<' => on_left_angle_typed(&file.tree(), offset),
'>' => conv(on_right_angle_typed(&file.tree(), offset)),
- '{' => conv(on_opening_brace_typed(file, offset)),
- _ => return None,
- };
-
- fn conv(text_edit: Option<TextEdit>) -> Option<ExtendedTextEdit> {
- Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false })
+ '{' => conv(on_opening_bracket_typed(file, offset, '{')),
+ '(' => conv(on_opening_bracket_typed(file, offset, '(')),
+ _ => None,
}
}
-/// Inserts a closing `}` when the user types an opening `{`, wrapping an existing expression in a
-/// block, or a part of a `use` item.
-fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<TextEdit> {
- if !stdx::always!(file.tree().syntax().text().char_at(offset) == Some('{')) {
+/// Inserts a closing bracket when the user types an opening bracket, wrapping an existing expression in a
+/// block, or a part of a `use` item (for `{`).
+fn on_opening_bracket_typed(
+ file: &Parse<SourceFile>,
+ offset: TextSize,
+ opening_bracket: char,
+) -> Option<TextEdit> {
+ let (closing_bracket, expected_ast_bracket) = match opening_bracket {
+ '{' => ('}', SyntaxKind::L_CURLY),
+ '(' => (')', SyntaxKind::L_PAREN),
+ _ => return None,
+ };
+
+ if !stdx::always!(file.tree().syntax().text().char_at(offset) == Some(opening_bracket)) {
return None;
}
let brace_token = file.tree().syntax().token_at_offset(offset).right_biased()?;
- if brace_token.kind() != SyntaxKind::L_CURLY {
+ if brace_token.kind() != expected_ast_bracket {
return None;
}
- // Remove the `{` to get a better parse tree, and reparse.
+ // Remove the opening bracket to get a better parse tree, and reparse.
let range = brace_token.text_range();
- if !stdx::always!(range.len() == TextSize::of('{')) {
+ if !stdx::always!(range.len() == TextSize::of(opening_bracket)) {
return None;
}
let file = file.reparse(&Indel::delete(range));
- if let Some(edit) = brace_expr(&file.tree(), offset) {
+ if let Some(edit) = bracket_expr(&file.tree(), offset, opening_bracket, closing_bracket) {
return Some(edit);
}
- if let Some(edit) = brace_use_path(&file.tree(), offset) {
- return Some(edit);
+ if closing_bracket == '}' {
+ if let Some(edit) = brace_use_path(&file.tree(), offset) {
+ return Some(edit);
+ }
}
return None;
@@ -143,7 +155,12 @@ fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<
))
}
- fn brace_expr(file: &SourceFile, offset: TextSize) -> Option<TextEdit> {
+ fn bracket_expr(
+ file: &SourceFile,
+ offset: TextSize,
+ opening_bracket: char,
+ closing_bracket: char,
+ ) -> Option<TextEdit> {
let mut expr: ast::Expr = find_node_at_offset(file.syntax(), offset)?;
if expr.syntax().text_range().start() != offset {
return None;
@@ -166,10 +183,10 @@ fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<
return None;
}
- // Insert `}` right after the expression.
+ // Insert the closing bracket right after the expression.
Some(TextEdit::insert(
- expr.syntax().text_range().end() + TextSize::of("{"),
- "}".to_string(),
+ expr.syntax().text_range().end() + TextSize::of(opening_bracket),
+ closing_bracket.to_string(),
))
}
}
@@ -938,6 +955,193 @@ use some::pa$0th::to::Item;
}
#[test]
+ fn adds_closing_parenthesis_for_expr() {
+ type_char(
+ '(',
+ r#"
+fn f() { match () { _ => $0() } }
+ "#,
+ r#"
+fn f() { match () { _ => (()) } }
+ "#,
+ );
+ type_char(
+ '(',
+ r#"
+fn f() { $0() }
+ "#,
+ r#"
+fn f() { (()) }
+ "#,
+ );
+ type_char(
+ '(',
+ r#"
+fn f() { let x = $0(); }
+ "#,
+ r#"
+fn f() { let x = (()); }
+ "#,
+ );
+ type_char(
+ '(',
+ r#"
+fn f() { let x = $0a.b(); }
+ "#,
+ r#"
+fn f() { let x = (a.b()); }
+ "#,
+ );
+ type_char(
+ '(',
+ r#"
+const S: () = $0();
+fn f() {}
+ "#,
+ r#"
+const S: () = (());
+fn f() {}
+ "#,
+ );
+ type_char(
+ '(',
+ r#"
+const S: () = $0a.b();
+fn f() {}
+ "#,
+ r#"
+const S: () = (a.b());
+fn f() {}
+ "#,
+ );
+ type_char(
+ '(',
+ r#"
+fn f() {
+ match x {
+ 0 => $0(),
+ 1 => (),
+ }
+}
+ "#,
+ r#"
+fn f() {
+ match x {
+ 0 => (()),
+ 1 => (),
+ }
+}
+ "#,
+ );
+ type_char(
+ '(',
+ r#"
+ fn f() {
+ let z = Some($03);
+ }
+ "#,
+ r#"
+ fn f() {
+ let z = Some((3));
+ }
+ "#,
+ );
+ }
+
+ #[test]
+ fn parenthesis_noop_in_string_literal() {
+ // Regression test for #9351
+ type_char_noop(
+ '(',
+ r##"
+fn check_with(ra_fixture: &str, expect: Expect) {
+ let base = r#"
+enum E { T(), R$0, C }
+use self::E::X;
+const Z: E = E::C;
+mod m {}
+asdasdasdasdasdasda
+sdasdasdasdasdasda
+sdasdasdasdasd
+"#;
+ let actual = completion_list(&format!("{}\n{}", base, ra_fixture));
+ expect.assert_eq(&actual)
+}
+ "##,
+ );
+ }
+
+ #[test]
+ fn parenthesis_noop_in_item_position_with_macro() {
+ type_char_noop('(', r#"$0println!();"#);
+ type_char_noop(
+ '(',
+ r#"
+fn main() $0println!("hello");
+}"#,
+ );
+ }
+
+ #[test]
+ fn parenthesis_noop_in_use_tree() {
+ type_char_noop(
+ '(',
+ r#"
+use some::$0Path;
+ "#,
+ );
+ type_char_noop(
+ '(',
+ r#"
+use some::{Path, $0Other};
+ "#,
+ );
+ type_char_noop(
+ '(',
+ r#"
+use some::{$0Path, Other};
+ "#,
+ );
+ type_char_noop(
+ '(',
+ r#"
+use some::path::$0to::Item;
+ "#,
+ );
+ type_char_noop(
+ '(',
+ r#"
+use some::$0path::to::Item;
+ "#,
+ );
+ type_char_noop(
+ '(',
+ r#"
+use $0some::path::to::Item;
+ "#,
+ );
+ type_char_noop(
+ '(',
+ r#"
+use some::path::$0to::{Item};
+ "#,
+ );
+ type_char_noop(
+ '(',
+ r#"
+use $0Thing as _;
+ "#,
+ );
+
+ type_char_noop(
+ '(',
+ r#"
+use some::pa$0th::to::Item;
+ "#,
+ );
+ }
+
+ #[test]
fn adds_closing_angle_bracket_for_generic_args() {
type_char(
'<',
diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml
index 4d56c7719..89b302c79 100644
--- a/src/tools/rust-analyzer/crates/intern/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml
@@ -16,6 +16,5 @@ doctest = false
# We need to freeze the version of the crate, as the raw-api feature is considered unstable
dashmap = { version = "=5.4.0", features = ["raw-api"] }
hashbrown.workspace = true
-once_cell = "1.17.0"
rustc-hash = "1.1.0"
triomphe.workspace = true
diff --git a/src/tools/rust-analyzer/crates/intern/src/lib.rs b/src/tools/rust-analyzer/crates/intern/src/lib.rs
index dabbf3a38..2934d2667 100644
--- a/src/tools/rust-analyzer/crates/intern/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/lib.rs
@@ -6,11 +6,11 @@ use std::{
fmt::{self, Debug, Display},
hash::{BuildHasherDefault, Hash, Hasher},
ops::Deref,
+ sync::OnceLock,
};
use dashmap::{DashMap, SharedValue};
use hashbrown::{hash_map::RawEntryMut, HashMap};
-use once_cell::sync::OnceCell;
use rustc_hash::FxHasher;
use triomphe::Arc;
@@ -177,12 +177,12 @@ impl<T: Display + Internable + ?Sized> Display for Interned<T> {
}
pub struct InternStorage<T: ?Sized> {
- map: OnceCell<InternMap<T>>,
+ map: OnceLock<InternMap<T>>,
}
impl<T: ?Sized> InternStorage<T> {
pub const fn new() -> Self {
- Self { map: OnceCell::new() }
+ Self { map: OnceLock::new() }
}
}
diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
index 62b2accf5..7b9bb61e6 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
@@ -961,6 +961,7 @@ impl TtTreeSink<'_> {
if has_pseudo_dot {
assert!(right.is_empty(), "{left}.{right}");
} else {
+ assert!(!right.is_empty(), "{left}.{right}");
self.inner.start_node(SyntaxKind::NAME_REF);
self.inner.token(SyntaxKind::INT_NUMBER, right);
self.inner.finish_node();
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
index 333318f53..6a2a9adce 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
@@ -184,7 +184,9 @@ pub(crate) mod entry {
};
p.bump_any();
while !p.at(EOF) && !p.at(closing_paren_kind) {
- expressions::expr(p);
+ if expressions::expr(p).is_none() {
+ break;
+ }
if !p.at(EOF) && !p.at(closing_paren_kind) {
p.expect(T![,]);
}
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
index d8553d3f9..4197f248e 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
@@ -1,3 +1,5 @@
+use crate::grammar::types::type_;
+
use super::*;
// test expr_literals
@@ -73,6 +75,9 @@ pub(super) fn atom_expr(
if let Some(m) = literal(p) {
return Some((m, BlockLike::NotBlock));
}
+ if p.at_contextual_kw(T![builtin]) && p.nth_at(1, T![#]) {
+ return Some((builtin_expr(p)?, BlockLike::NotBlock));
+ }
if paths::is_path_start(p) {
return Some(path_expr(p, r));
}
@@ -93,7 +98,6 @@ pub(super) fn atom_expr(
m.complete(p, UNDERSCORE_EXPR)
}
T![loop] => loop_expr(p, None),
- T![box] => box_expr(p, None),
T![while] => while_expr(p, None),
T![try] => try_block_expr(p, None),
T![match] => match_expr(p),
@@ -212,6 +216,72 @@ fn tuple_expr(p: &mut Parser<'_>) -> CompletedMarker {
m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
}
+// test builtin_expr
+// fn foo() {
+// builtin#asm(0);
+// builtin#format_args("", 0, 1, a = 2 + 3, a + b);
+// builtin#offset_of(Foo, bar.baz.0);
+// }
+fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
+ let m = p.start();
+ p.bump_remap(T![builtin]);
+ p.bump(T![#]);
+ if p.at_contextual_kw(T![offset_of]) {
+ p.bump_remap(T![offset_of]);
+ p.expect(T!['(']);
+ type_(p);
+ p.expect(T![,]);
+ while !p.at(EOF) && !p.at(T![')']) {
+ if p.at(IDENT) || p.at(INT_NUMBER) {
+ name_ref_or_index(p);
+ // } else if p.at(FLOAT_NUMBER) {
+ // FIXME: needs float hack
+ } else {
+ p.err_and_bump("expected field name or number");
+ }
+ if !p.at(T![')']) {
+ p.expect(T![.]);
+ }
+ }
+ p.expect(T![')']);
+ Some(m.complete(p, OFFSET_OF_EXPR))
+ } else if p.at_contextual_kw(T![format_args]) {
+ p.bump_remap(T![format_args]);
+ p.expect(T!['(']);
+ expr(p);
+ if p.eat(T![,]) {
+ while !p.at(EOF) && !p.at(T![')']) {
+ let m = p.start();
+ if p.at(IDENT) && p.nth_at(1, T![=]) {
+ name(p);
+ p.bump(T![=]);
+ }
+ if expr(p).is_none() {
+ m.abandon(p);
+ break;
+ }
+ m.complete(p, FORMAT_ARGS_ARG);
+
+ if !p.at(T![')']) {
+ p.expect(T![,]);
+ }
+ }
+ }
+ p.expect(T![')']);
+ Some(m.complete(p, FORMAT_ARGS_EXPR))
+ } else if p.at_contextual_kw(T![asm]) {
+ p.bump_remap(T![asm]);
+ p.expect(T!['(']);
+ // FIXME: We just put expression here so highlighting kind of keeps working
+ expr(p);
+ p.expect(T![')']);
+ Some(m.complete(p, ASM_EXPR))
+ } else {
+ m.abandon(p);
+ None
+ }
+}
+
// test array_expr
// fn foo() {
// [];
@@ -662,19 +732,3 @@ fn try_block_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
}
m.complete(p, BLOCK_EXPR)
}
-
-// test box_expr
-// fn foo() {
-// let x = box 1i32;
-// let y = (box 1i32, box 2i32);
-// let z = Foo(box 1i32, box 2i32);
-// }
-fn box_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
- assert!(p.at(T![box]));
- let m = m.unwrap_or_else(|| p.start());
- p.bump(T![box]);
- if p.at_ts(EXPR_FIRST) {
- expr(p);
- }
- m.complete(p, BOX_EXPR)
-}
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
index 8ed1c84c4..29d9b05d3 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
@@ -88,7 +88,7 @@ fn const_param(p: &mut Parser<'_>, m: Marker) {
// test const_param_default_path
// struct A<const N: i32 = i32::MAX>;
- generic_args::const_arg_expr(p);
+ generic_args::const_arg(p);
}
m.complete(p, CONST_PARAM);
diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
index e4dce21f3..36c52953a 100644
--- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
@@ -221,6 +221,7 @@ impl<'a> Converter<'a> {
rustc_lexer::TokenKind::Caret => T![^],
rustc_lexer::TokenKind::Percent => T![%],
rustc_lexer::TokenKind::Unknown => ERROR,
+ rustc_lexer::TokenKind::UnknownPrefix if token_text == "builtin" => IDENT,
rustc_lexer::TokenKind::UnknownPrefix => {
err = "unknown literal prefix";
IDENT
diff --git a/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs b/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
index 53cdad649..2c47e3d08 100644
--- a/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
@@ -46,12 +46,16 @@ impl LexedStr<'_> {
// Tag the token as joint if it is float with a fractional part
// we use this jointness to inform the parser about what token split
// event to emit when we encounter a float literal in a field access
- if kind == SyntaxKind::FLOAT_NUMBER && !self.text(i).ends_with('.') {
- res.was_joint();
+ if kind == SyntaxKind::FLOAT_NUMBER {
+ if !self.text(i).ends_with('.') {
+ res.was_joint();
+ } else {
+ was_joint = false;
+ }
+ } else {
+ was_joint = true;
}
}
-
- was_joint = true;
}
}
res
@@ -204,6 +208,7 @@ impl Builder<'_, '_> {
assert!(right.is_empty(), "{left}.{right}");
self.state = State::Normal;
} else {
+ assert!(!right.is_empty(), "{left}.{right}");
(self.sink)(StrStep::Enter { kind: SyntaxKind::NAME_REF });
(self.sink)(StrStep::Token { kind: SyntaxKind::INT_NUMBER, text: right });
(self.sink)(StrStep::Exit);
diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
index 48f407623..db5278f89 100644
--- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs
@@ -105,12 +105,16 @@ pub enum SyntaxKind {
WHILE_KW,
YIELD_KW,
AUTO_KW,
+ BUILTIN_KW,
DEFAULT_KW,
EXISTENTIAL_KW,
UNION_KW,
RAW_KW,
MACRO_RULES_KW,
YEET_KW,
+ OFFSET_OF_KW,
+ ASM_KW,
+ FORMAT_ARGS_KW,
INT_NUMBER,
FLOAT_NUMBER,
CHAR,
@@ -203,7 +207,10 @@ pub enum SyntaxKind {
RECORD_EXPR,
RECORD_EXPR_FIELD_LIST,
RECORD_EXPR_FIELD,
- BOX_EXPR,
+ OFFSET_OF_EXPR,
+ ASM_EXPR,
+ FORMAT_ARGS_EXPR,
+ FORMAT_ARGS_ARG,
CALL_EXPR,
INDEX_EXPR,
METHOD_CALL_EXPR,
@@ -315,12 +322,16 @@ impl SyntaxKind {
| WHILE_KW
| YIELD_KW
| AUTO_KW
+ | BUILTIN_KW
| DEFAULT_KW
| EXISTENTIAL_KW
| UNION_KW
| RAW_KW
| MACRO_RULES_KW
| YEET_KW
+ | OFFSET_OF_KW
+ | ASM_KW
+ | FORMAT_ARGS_KW
)
}
pub fn is_punct(self) -> bool {
@@ -435,12 +446,16 @@ impl SyntaxKind {
pub fn from_contextual_keyword(ident: &str) -> Option<SyntaxKind> {
let kw = match ident {
"auto" => AUTO_KW,
+ "builtin" => BUILTIN_KW,
"default" => DEFAULT_KW,
"existential" => EXISTENTIAL_KW,
"union" => UNION_KW,
"raw" => RAW_KW,
"macro_rules" => MACRO_RULES_KW,
"yeet" => YEET_KW,
+ "offset_of" => OFFSET_OF_KW,
+ "asm" => ASM_KW,
+ "format_args" => FORMAT_ARGS_KW,
_ => return None,
};
Some(kw)
@@ -481,5 +496,5 @@ impl SyntaxKind {
}
}
#[macro_export]
-macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
+macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
pub use T;
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast
index 809ad1b8d..49f163b16 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast
@@ -20,7 +20,8 @@ SOURCE_FILE
IDENT "i32"
WHITESPACE " "
EQ "="
- WHITESPACE " "
+ WHITESPACE " "
+ CONST_ARG
COMMA ","
WHITESPACE " "
CONST_PARAM
@@ -37,8 +38,9 @@ SOURCE_FILE
IDENT "i32"
WHITESPACE " "
EQ "="
+ CONST_ARG
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
-error 23: expected a generic const argument
+error 24: expected a generic const argument
error 40: expected a generic const argument
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rast
deleted file mode 100644
index b21f37cd8..000000000
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rast
+++ /dev/null
@@ -1,90 +0,0 @@
-SOURCE_FILE
- FN
- FN_KW "fn"
- WHITESPACE " "
- NAME
- IDENT "foo"
- PARAM_LIST
- L_PAREN "("
- R_PAREN ")"
- WHITESPACE " "
- BLOCK_EXPR
- STMT_LIST
- L_CURLY "{"
- WHITESPACE "\n "
- LET_STMT
- LET_KW "let"
- WHITESPACE " "
- IDENT_PAT
- NAME
- IDENT "x"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- BOX_EXPR
- BOX_KW "box"
- WHITESPACE " "
- LITERAL
- INT_NUMBER "1i32"
- SEMICOLON ";"
- WHITESPACE "\n "
- LET_STMT
- LET_KW "let"
- WHITESPACE " "
- IDENT_PAT
- NAME
- IDENT "y"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- TUPLE_EXPR
- L_PAREN "("
- BOX_EXPR
- BOX_KW "box"
- WHITESPACE " "
- LITERAL
- INT_NUMBER "1i32"
- COMMA ","
- WHITESPACE " "
- BOX_EXPR
- BOX_KW "box"
- WHITESPACE " "
- LITERAL
- INT_NUMBER "2i32"
- R_PAREN ")"
- SEMICOLON ";"
- WHITESPACE "\n "
- LET_STMT
- LET_KW "let"
- WHITESPACE " "
- IDENT_PAT
- NAME
- IDENT "z"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- CALL_EXPR
- PATH_EXPR
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Foo"
- ARG_LIST
- L_PAREN "("
- BOX_EXPR
- BOX_KW "box"
- WHITESPACE " "
- LITERAL
- INT_NUMBER "1i32"
- COMMA ","
- WHITESPACE " "
- BOX_EXPR
- BOX_KW "box"
- WHITESPACE " "
- LITERAL
- INT_NUMBER "2i32"
- R_PAREN ")"
- SEMICOLON ";"
- WHITESPACE "\n"
- R_CURLY "}"
- WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rs
deleted file mode 100644
index fc9923b71..000000000
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0132_box_expr.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn foo() {
- let x = box 1i32;
- let y = (box 1i32, box 2i32);
- let z = Foo(box 1i32, box 2i32);
-}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast
index 11002bf98..3f5fb47d2 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast
@@ -21,16 +21,17 @@ SOURCE_FILE
WHITESPACE " "
EQ "="
WHITESPACE " "
- PATH_EXPR
- PATH
+ CONST_ARG
+ PATH_EXPR
PATH
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "i32"
+ COLON2 "::"
PATH_SEGMENT
NAME_REF
- IDENT "i32"
- COLON2 "::"
- PATH_SEGMENT
- NAME_REF
- IDENT "MAX"
+ IDENT "MAX"
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast
index 0607ff54f..d65011374 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast
@@ -21,14 +21,15 @@ SOURCE_FILE
WHITESPACE " "
EQ "="
WHITESPACE " "
- BLOCK_EXPR
- STMT_LIST
- L_CURLY "{"
- WHITESPACE " "
- LITERAL
- INT_NUMBER "1"
- WHITESPACE " "
- R_CURLY "}"
+ CONST_ARG
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ LITERAL
+ INT_NUMBER "1"
+ WHITESPACE " "
+ R_CURLY "}"
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast
index 8e5231365..6de10353b 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast
@@ -21,10 +21,11 @@ SOURCE_FILE
WHITESPACE " "
EQ "="
WHITESPACE " "
- PREFIX_EXPR
- MINUS "-"
- LITERAL
- INT_NUMBER "1"
+ CONST_ARG
+ PREFIX_EXPR
+ MINUS "-"
+ LITERAL
+ INT_NUMBER "1"
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast
new file mode 100644
index 000000000..361900b6d
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rast
@@ -0,0 +1,105 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "foo"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ EXPR_STMT
+ ASM_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ ASM_KW "asm"
+ L_PAREN "("
+ LITERAL
+ INT_NUMBER "0"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n "
+ EXPR_STMT
+ FORMAT_ARGS_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ FORMAT_ARGS_KW "format_args"
+ L_PAREN "("
+ LITERAL
+ STRING "\"\""
+ COMMA ","
+ WHITESPACE " "
+ FORMAT_ARGS_ARG
+ LITERAL
+ INT_NUMBER "0"
+ COMMA ","
+ WHITESPACE " "
+ FORMAT_ARGS_ARG
+ LITERAL
+ INT_NUMBER "1"
+ COMMA ","
+ WHITESPACE " "
+ FORMAT_ARGS_ARG
+ NAME
+ IDENT "a"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ BIN_EXPR
+ LITERAL
+ INT_NUMBER "2"
+ WHITESPACE " "
+ PLUS "+"
+ WHITESPACE " "
+ LITERAL
+ INT_NUMBER "3"
+ COMMA ","
+ WHITESPACE " "
+ FORMAT_ARGS_ARG
+ BIN_EXPR
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "a"
+ WHITESPACE " "
+ PLUS "+"
+ WHITESPACE " "
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "b"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n "
+ EXPR_STMT
+ OFFSET_OF_EXPR
+ BUILTIN_KW "builtin"
+ POUND "#"
+ OFFSET_OF_KW "offset_of"
+ L_PAREN "("
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Foo"
+ COMMA ","
+ WHITESPACE " "
+ NAME_REF
+ IDENT "bar"
+ DOT "."
+ NAME_REF
+ IDENT "baz"
+ DOT "."
+ NAME_REF
+ INT_NUMBER "0"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ R_CURLY "}"
+ WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs
new file mode 100644
index 000000000..14431b021
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0207_builtin_expr.rs
@@ -0,0 +1,5 @@
+fn foo() {
+ builtin#asm(0);
+ builtin#format_args("", 0, 1, a = 2 + 3, a + b);
+ builtin#offset_of(Foo, bar.baz.0);
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-test/build.rs b/src/tools/rust-analyzer/crates/proc-macro-test/build.rs
index 19a5caa4c..782715786 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-test/build.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-test/build.rs
@@ -71,6 +71,10 @@ fn main() {
.arg("--target-dir")
.arg(&target_dir);
+ if let Ok(target) = std::env::var("TARGET") {
+ cmd.args(["--target", &target]);
+ }
+
println!("Running {cmd:?}");
let output = cmd.output().unwrap();
diff --git a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
index 71303d5a6..814a02574 100644
--- a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
+++ b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
@@ -10,13 +10,13 @@ pub struct StopWatch {
time: Instant,
#[cfg(target_os = "linux")]
counter: Option<perf_event::Counter>,
- memory: Option<MemoryUsage>,
+ memory: MemoryUsage,
}
pub struct StopWatchSpan {
pub time: Duration,
pub instructions: Option<u64>,
- pub memory: Option<MemoryUsage>,
+ pub memory: MemoryUsage,
}
impl StopWatch {
@@ -45,20 +45,16 @@ impl StopWatch {
None
}
};
+ let memory = MemoryUsage::now();
let time = Instant::now();
StopWatch {
time,
#[cfg(target_os = "linux")]
counter,
- memory: None,
+ memory,
}
}
- pub fn memory(mut self, yes: bool) -> StopWatch {
- if yes {
- self.memory = Some(MemoryUsage::now());
- }
- self
- }
+
pub fn elapsed(&mut self) -> StopWatchSpan {
let time = self.time.elapsed();
@@ -69,7 +65,7 @@ impl StopWatch {
#[cfg(not(target_os = "linux"))]
let instructions = None;
- let memory = self.memory.map(|it| MemoryUsage::now() - it);
+ let memory = MemoryUsage::now() - self.memory;
StopWatchSpan { time, instructions, memory }
}
}
@@ -93,9 +89,7 @@ impl fmt::Display for StopWatchSpan {
}
write!(f, ", {instructions}{prefix}instr")?;
}
- if let Some(memory) = self.memory {
- write!(f, ", {memory}")?;
- }
+ write!(f, ", {}", self.memory)?;
Ok(())
}
}
diff --git a/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs b/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs
index 8392718b2..c5d55f7d2 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs
@@ -2,14 +2,29 @@
use std::process::Command;
+use anyhow::Context;
use rustc_hash::FxHashMap;
-use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath};
+use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
+
+/// Determines how `rustc --print cfg` is discovered and invoked.
+///
+/// There options are supported:
+/// - [`RustcCfgConfig::Cargo`], which relies on `cargo rustc --print cfg`
+/// and `RUSTC_BOOTSTRAP`.
+/// - [`RustcCfgConfig::Explicit`], which uses an explicit path to the `rustc`
+/// binary in the sysroot.
+/// - [`RustcCfgConfig::Discover`], which uses [`toolchain::rustc`].
+pub(crate) enum RustcCfgConfig<'a> {
+ Cargo(&'a ManifestPath),
+ Explicit(&'a Sysroot),
+ Discover,
+}
pub(crate) fn get(
- cargo_toml: Option<&ManifestPath>,
target: Option<&str>,
extra_env: &FxHashMap<String, String>,
+ config: RustcCfgConfig<'_>,
) -> Vec<CfgFlag> {
let _p = profile::span("rustc_cfg::get");
let mut res = Vec::with_capacity(6 * 2 + 1);
@@ -25,49 +40,67 @@ pub(crate) fn get(
// Add miri cfg, which is useful for mir eval in stdlib
res.push(CfgFlag::Atom("miri".into()));
- match get_rust_cfgs(cargo_toml, target, extra_env) {
+ let rustc_cfgs = get_rust_cfgs(target, extra_env, config);
+
+ let rustc_cfgs = match rustc_cfgs {
+ Ok(cfgs) => cfgs,
+ Err(e) => {
+ tracing::error!(?e, "failed to get rustc cfgs");
+ return res;
+ }
+ };
+
+ let rustc_cfgs =
+ rustc_cfgs.lines().map(|it| it.parse::<CfgFlag>()).collect::<Result<Vec<_>, _>>();
+
+ match rustc_cfgs {
Ok(rustc_cfgs) => {
- tracing::debug!(
- "rustc cfgs found: {:?}",
- rustc_cfgs
- .lines()
- .map(|it| it.parse::<CfgFlag>().map(|it| it.to_string()))
- .collect::<Vec<_>>()
- );
- res.extend(rustc_cfgs.lines().filter_map(|it| it.parse().ok()));
+ tracing::debug!(?rustc_cfgs, "rustc cfgs found");
+ res.extend(rustc_cfgs);
+ }
+ Err(e) => {
+ tracing::error!(?e, "failed to get rustc cfgs")
}
- Err(e) => tracing::error!("failed to get rustc cfgs: {e:?}"),
}
res
}
fn get_rust_cfgs(
- cargo_toml: Option<&ManifestPath>,
target: Option<&str>,
extra_env: &FxHashMap<String, String>,
+ config: RustcCfgConfig<'_>,
) -> anyhow::Result<String> {
- if let Some(cargo_toml) = cargo_toml {
- let mut cargo_config = Command::new(toolchain::cargo());
- cargo_config.envs(extra_env);
- cargo_config
- .current_dir(cargo_toml.parent())
- .args(["rustc", "-Z", "unstable-options", "--print", "cfg"])
- .env("RUSTC_BOOTSTRAP", "1");
- if let Some(target) = target {
- cargo_config.args(["--target", target]);
+ let mut cmd = match config {
+ RustcCfgConfig::Cargo(cargo_toml) => {
+ let mut cmd = Command::new(toolchain::cargo());
+ cmd.envs(extra_env);
+ cmd.current_dir(cargo_toml.parent())
+ .args(["rustc", "-Z", "unstable-options", "--print", "cfg"])
+ .env("RUSTC_BOOTSTRAP", "1");
+ if let Some(target) = target {
+ cmd.args(["--target", target]);
+ }
+
+ return utf8_stdout(cmd).context("Unable to run `cargo rustc`");
}
- match utf8_stdout(cargo_config) {
- Ok(it) => return Ok(it),
- Err(e) => tracing::debug!("{e:?}: falling back to querying rustc for cfgs"),
+ RustcCfgConfig::Explicit(sysroot) => {
+ let rustc: std::path::PathBuf = sysroot.discover_rustc()?.into();
+ tracing::debug!(?rustc, "using explicit rustc from sysroot");
+ Command::new(rustc)
}
- }
- // using unstable cargo features failed, fall back to using plain rustc
- let mut cmd = Command::new(toolchain::rustc());
+ RustcCfgConfig::Discover => {
+ let rustc = toolchain::rustc();
+ tracing::debug!(?rustc, "using rustc from env");
+ Command::new(rustc)
+ }
+ };
+
cmd.envs(extra_env);
cmd.args(["--print", "cfg", "-O"]);
if let Some(target) = target {
cmd.args(["--target", target]);
}
- utf8_stdout(cmd)
+
+ utf8_stdout(cmd).context("Unable to run `rustc`")
}
diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
index da862c9e8..fe046dd14 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
@@ -115,10 +115,19 @@ impl Sysroot {
Ok(Sysroot::load(sysroot_dir, src))
}
- pub fn discover_rustc(&self) -> Option<ManifestPath> {
+ pub fn discover_rustc_src(&self) -> Option<ManifestPath> {
get_rustc_src(&self.root)
}
+ pub fn discover_rustc(&self) -> Result<AbsPathBuf, std::io::Error> {
+ let rustc = self.root.join("bin/rustc");
+ tracing::debug!(?rustc, "checking for rustc binary at location");
+ match fs::metadata(&rustc) {
+ Ok(_) => Ok(rustc),
+ Err(e) => Err(e),
+ }
+ }
+
pub fn with_sysroot_dir(sysroot_dir: AbsPathBuf) -> Result<Sysroot> {
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir).ok_or_else(|| {
format_err!("can't load standard library from sysroot path {sysroot_dir}")
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index f51ea7eeb..e0209ca15 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -2,7 +2,7 @@
//! metadata` or `rust-project.json`) into representation stored in the salsa
//! database -- `CrateGraph`.
-use std::{collections::VecDeque, fmt, fs, process::Command, sync};
+use std::{collections::VecDeque, fmt, fs, iter, process::Command, str::FromStr, sync};
use anyhow::{format_err, Context};
use base_db::{
@@ -21,7 +21,7 @@ use crate::{
cargo_workspace::{DepKind, PackageData, RustLibSource},
cfg_flag::CfgFlag,
project_json::Crate,
- rustc_cfg,
+ rustc_cfg::{self, RustcCfgConfig},
sysroot::SysrootCrate,
target_data_layout, utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath,
Package, ProjectJson, ProjectManifest, Sysroot, TargetData, TargetKind, WorkspaceBuildScripts,
@@ -167,7 +167,8 @@ impl ProjectWorkspace {
cmd.envs(&config.extra_env);
cmd.arg("--version").current_dir(current_dir);
cmd
- })?;
+ })
+ .with_context(|| format!("Failed to query rust toolchain version at {current_dir}, is your toolchain setup correctly?"))?;
anyhow::Ok(
cargo_version
.get(prefix.len()..)
@@ -239,9 +240,9 @@ impl ProjectWorkspace {
Some(RustLibSource::Path(path)) => ManifestPath::try_from(path.clone())
.map_err(|p| Some(format!("rustc source path is not absolute: {p}"))),
Some(RustLibSource::Discover) => {
- sysroot.as_ref().ok().and_then(Sysroot::discover_rustc).ok_or_else(|| {
- Some(format!("Failed to discover rustc source for sysroot."))
- })
+ sysroot.as_ref().ok().and_then(Sysroot::discover_rustc_src).ok_or_else(
+ || Some(format!("Failed to discover rustc source for sysroot.")),
+ )
}
None => Err(None),
};
@@ -278,8 +279,11 @@ impl ProjectWorkspace {
}
});
- let rustc_cfg =
- rustc_cfg::get(Some(&cargo_toml), config.target.as_deref(), &config.extra_env);
+ let rustc_cfg = rustc_cfg::get(
+ config.target.as_deref(),
+ &config.extra_env,
+ RustcCfgConfig::Cargo(cargo_toml),
+ );
let cfg_overrides = config.cfg_overrides.clone();
let data_layout = target_data_layout::get(
@@ -330,11 +334,18 @@ impl ProjectWorkspace {
}
(None, None) => Err(None),
};
- if let Ok(sysroot) = &sysroot {
- tracing::info!(src_root = %sysroot.src_root(), root = %sysroot.root(), "Using sysroot");
- }
+ let config = match &sysroot {
+ Ok(sysroot) => {
+ tracing::debug!(src_root = %sysroot.src_root(), root = %sysroot.root(), "Using sysroot");
+ RustcCfgConfig::Explicit(sysroot)
+ }
+ Err(_) => {
+ tracing::debug!("discovering sysroot");
+ RustcCfgConfig::Discover
+ }
+ };
- let rustc_cfg = rustc_cfg::get(None, target, extra_env);
+ let rustc_cfg = rustc_cfg::get(target, extra_env, config);
ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg, toolchain }
}
@@ -356,10 +367,18 @@ impl ProjectWorkspace {
}
None => Err(None),
};
- if let Ok(sysroot) = &sysroot {
- tracing::info!(src_root = %sysroot.src_root(), root = %sysroot.root(), "Using sysroot");
- }
- let rustc_cfg = rustc_cfg::get(None, None, &Default::default());
+ let rustc_config = match &sysroot {
+ Ok(sysroot) => {
+ tracing::info!(src_root = %sysroot.src_root(), root = %sysroot.root(), "Using sysroot");
+ RustcCfgConfig::Explicit(sysroot)
+ }
+ Err(_) => {
+ tracing::info!("discovering sysroot");
+ RustcCfgConfig::Discover
+ }
+ };
+
+ let rustc_cfg = rustc_cfg::get(None, &FxHashMap::default(), rustc_config);
Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg })
}
@@ -729,6 +748,7 @@ fn project_json_to_crate_graph(
)
});
+ let r_a_cfg_flag = CfgFlag::Atom("rust_analyzer".to_owned());
let mut cfg_cache: FxHashMap<&str, Vec<CfgFlag>> = FxHashMap::default();
let crates: FxHashMap<CrateId, CrateId> = project
.crates()
@@ -753,9 +773,14 @@ fn project_json_to_crate_graph(
let env = env.clone().into_iter().collect();
let target_cfgs = match target.as_deref() {
- Some(target) => cfg_cache
- .entry(target)
- .or_insert_with(|| rustc_cfg::get(None, Some(target), extra_env)),
+ Some(target) => cfg_cache.entry(target).or_insert_with(|| {
+ let rustc_cfg = match sysroot {
+ Some(sysroot) => RustcCfgConfig::Explicit(sysroot),
+ None => RustcCfgConfig::Discover,
+ };
+
+ rustc_cfg::get(Some(target), extra_env, rustc_cfg)
+ }),
None => &rustc_cfg,
};
@@ -764,7 +789,12 @@ fn project_json_to_crate_graph(
*edition,
display_name.clone(),
version.clone(),
- target_cfgs.iter().chain(cfg.iter()).cloned().collect(),
+ target_cfgs
+ .iter()
+ .chain(cfg.iter())
+ .chain(iter::once(&r_a_cfg_flag))
+ .cloned()
+ .collect(),
None,
env,
*is_proc_macro,
@@ -819,7 +849,7 @@ fn cargo_to_crate_graph(
sysroot: Option<&Sysroot>,
rustc_cfg: Vec<CfgFlag>,
override_cfg: &CfgOverrides,
- // Don't compute cfg and use this if present
+ // Don't compute cfg and use this if present, only used for the sysroot experiment hack
forced_cfg: Option<CfgOptions>,
build_scripts: &WorkspaceBuildScripts,
target_layout: TargetLayoutLoadResult,
@@ -841,12 +871,7 @@ fn cargo_to_crate_graph(
None => (SysrootPublicDeps::default(), None),
};
- let cfg_options = {
- let mut cfg_options = CfgOptions::default();
- cfg_options.extend(rustc_cfg);
- cfg_options.insert_atom("debug_assertions".into());
- cfg_options
- };
+ let cfg_options = create_cfg_options(rustc_cfg);
// Mapping of a package to its library target
let mut pkg_to_lib_crate = FxHashMap::default();
@@ -865,6 +890,9 @@ fn cargo_to_crate_graph(
if cargo[pkg].is_local {
cfg_options.insert_atom("test".into());
}
+ if cargo[pkg].is_member {
+ cfg_options.insert_atom("rust_analyzer".into());
+ }
if !override_cfg.global.is_empty() {
cfg_options.apply_diff(override_cfg.global.clone());
@@ -1028,8 +1056,8 @@ fn detached_files_to_crate_graph(
None => (SysrootPublicDeps::default(), None),
};
- let mut cfg_options = CfgOptions::default();
- cfg_options.extend(rustc_cfg);
+ let mut cfg_options = create_cfg_options(rustc_cfg);
+ cfg_options.insert_atom("rust_analyzer".into());
for detached_file in detached_files {
let file_id = match load(detached_file) {
@@ -1227,6 +1255,10 @@ fn add_target_crate_root(
let mut env = Env::default();
inject_cargo_env(pkg, &mut env);
+ if let Ok(cname) = String::from_str(cargo_name) {
+ // CARGO_CRATE_NAME is the name of the Cargo target with - converted to _, such as the name of the library, binary, example, integration test, or benchmark.
+ env.set("CARGO_CRATE_NAME", cname.replace("-", "_"));
+ }
if let Some(envs) = build_data.map(|it| &it.envs) {
for (k, v) in envs {
@@ -1290,8 +1322,7 @@ fn sysroot_to_crate_graph(
channel: Option<ReleaseChannel>,
) -> (SysrootPublicDeps, Option<CrateId>) {
let _p = profile::span("sysroot_to_crate_graph");
- let mut cfg_options = CfgOptions::default();
- cfg_options.extend(rustc_cfg.clone());
+ let cfg_options = create_cfg_options(rustc_cfg.clone());
let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = match &sysroot.hack_cargo_workspace {
Some(cargo) => handle_hack_cargo_workspace(
load,
@@ -1470,3 +1501,10 @@ fn inject_cargo_env(package: &PackageData, env: &mut Env) {
env.set("CARGO_PKG_LICENSE_FILE", String::new());
}
+
+fn create_cfg_options(rustc_cfg: Vec<CfgFlag>) -> CfgOptions {
+ let mut cfg_options = CfgOptions::default();
+ cfg_options.extend(rustc_cfg);
+ cfg_options.insert_atom("debug_assertions".into());
+ cfg_options
+}
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt
index e595cd827..727d39a30 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt
@@ -18,6 +18,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -81,6 +82,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -151,6 +153,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -162,7 +165,7 @@
"CARGO_MANIFEST_DIR": "$ROOT$hello-world",
"CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "an_example",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
@@ -221,6 +224,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -232,7 +236,7 @@
"CARGO_MANIFEST_DIR": "$ROOT$hello-world",
"CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "it",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt
index e595cd827..727d39a30 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt
@@ -18,6 +18,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -81,6 +82,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -151,6 +153,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -162,7 +165,7 @@
"CARGO_MANIFEST_DIR": "$ROOT$hello-world",
"CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "an_example",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
@@ -221,6 +224,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
"test",
],
),
@@ -232,7 +236,7 @@
"CARGO_MANIFEST_DIR": "$ROOT$hello-world",
"CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "it",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt
index f10c55d04..89728babd 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt
@@ -18,6 +18,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
],
),
potential_cfg_options: None,
@@ -80,6 +81,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
],
),
potential_cfg_options: None,
@@ -149,6 +151,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
],
),
potential_cfg_options: None,
@@ -159,7 +162,7 @@
"CARGO_MANIFEST_DIR": "$ROOT$hello-world",
"CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "an_example",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
@@ -218,6 +221,7 @@
cfg_options: CfgOptions(
[
"debug_assertions",
+ "rust_analyzer",
],
),
potential_cfg_options: None,
@@ -228,7 +232,7 @@
"CARGO_MANIFEST_DIR": "$ROOT$hello-world",
"CARGO_PKG_VERSION": "0.1.0",
"CARGO_PKG_AUTHORS": "",
- "CARGO_CRATE_NAME": "hello_world",
+ "CARGO_CRATE_NAME": "it",
"CARGO_PKG_LICENSE_FILE": "",
"CARGO_PKG_HOMEPAGE": "",
"CARGO_PKG_DESCRIPTION": "",
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
index fb3f5933b..b7bf6cb27 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
@@ -14,7 +14,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -53,7 +55,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -84,7 +88,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -115,7 +121,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -146,7 +154,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -192,7 +202,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -223,7 +235,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -311,7 +325,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -342,7 +358,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -373,7 +391,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "debug_assertions",
+ ],
),
potential_cfg_options: None,
env: Env {
@@ -404,7 +424,9 @@
},
),
cfg_options: CfgOptions(
- [],
+ [
+ "rust_analyzer",
+ ],
),
potential_cfg_options: None,
env: Env {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index 5bfac7ee4..7410f0a3a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -24,7 +24,7 @@ crossbeam-channel = "0.5.5"
dissimilar = "1.0.4"
itertools = "0.10.5"
scip = "0.1.1"
-lsp-types = { version = "=0.94", features = ["proposed"] }
+lsp-types = { version = "=0.94.0", features = ["proposed"] }
parking_lot = "0.12.1"
xflags = "0.3.0"
oorandom = "11.1.3"
@@ -50,7 +50,6 @@ always-assert = "0.1.2"
# These 3 deps are not used by r-a directly, but we list them here to lock in their versions
# in our transitive deps to prevent them from pulling in windows-sys 0.45.0
mio = "=0.8.5"
-filetime = "=0.2.19"
parking_lot_core = "=0.9.6"
cfg.workspace = true
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs
index ab06b9681..8c9261ab0 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs
@@ -16,10 +16,12 @@ use lsp_types::{
};
use serde_json::json;
-use crate::config::{Config, RustfmtConfig};
-use crate::line_index::PositionEncoding;
-use crate::lsp_ext::negotiated_encoding;
-use crate::semantic_tokens;
+use crate::{
+ config::{Config, RustfmtConfig},
+ line_index::PositionEncoding,
+ lsp::semantic_tokens,
+ lsp_ext::negotiated_encoding,
+};
pub fn server_capabilities(config: &Config) -> ServerCapabilities {
ServerCapabilities {
@@ -218,7 +220,7 @@ fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProvi
}
fn more_trigger_character(config: &Config) -> Vec<String> {
- let mut res = vec![".".to_string(), ">".to_string(), "{".to_string()];
+ let mut res = vec![".".to_string(), ">".to_string(), "{".to_string(), "(".to_string()];
if config.snippet_cap() {
res.push("<".to_string());
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index f446a7c05..dcb3ca658 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -15,7 +15,10 @@ use hir_def::{
hir::{ExprId, PatId},
};
use hir_ty::{Interner, Substitution, TyExt, TypeFlags};
-use ide::{Analysis, AnnotationConfig, DiagnosticsConfig, InlayHintsConfig, LineCol, RootDatabase};
+use ide::{
+ Analysis, AnnotationConfig, DiagnosticsConfig, InlayFieldsToResolve, InlayHintsConfig, LineCol,
+ RootDatabase,
+};
use ide_db::{
base_db::{
salsa::{self, debug::DebugQueryTable, ParallelDatabase},
@@ -235,9 +238,7 @@ impl flags::AnalysisStats {
if let Some(instructions) = total_span.instructions {
report_metric("total instructions", instructions, "#instr");
}
- if let Some(memory) = total_span.memory {
- report_metric("total memory", memory.allocated.megabytes() as u64, "MB");
- }
+ report_metric("total memory", total_span.memory.allocated.megabytes() as u64, "MB");
if env::var("RA_COUNT").is_ok() {
eprintln!("{}", profile::countme::get_all());
@@ -257,7 +258,7 @@ impl flags::AnalysisStats {
eprintln!("source files: {total_file_size}, macro files: {total_macro_file_size}");
}
- if self.memory_usage && verbosity.is_verbose() {
+ if verbosity.is_verbose() {
print_memory_usage(host, vfs);
}
@@ -319,9 +320,13 @@ impl flags::AnalysisStats {
fn run_mir_lowering(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: Verbosity) {
let mut sw = self.stop_watch();
- let all = bodies.len() as u64;
+ let mut all = 0;
let mut fail = 0;
for &body in bodies {
+ if matches!(body, DefWithBody::Variant(_)) {
+ continue;
+ }
+ all += 1;
let Err(e) = db.mir_body(body.into()) else {
continue;
};
@@ -784,6 +789,7 @@ impl flags::AnalysisStats {
closure_style: hir::ClosureStyle::ImplFn,
max_length: Some(25),
closing_brace_hints_min_lines: Some(20),
+ fields_to_resolve: InlayFieldsToResolve::empty(),
},
file_id,
None,
@@ -814,7 +820,7 @@ impl flags::AnalysisStats {
}
fn stop_watch(&self) -> StopWatch {
- StopWatch::start().memory(self.memory_usage)
+ StopWatch::start()
}
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
index 13b7f039b..419440b6d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
@@ -62,8 +62,6 @@ xflags::xflags! {
optional --randomize
/// Run type inference in parallel.
optional --parallel
- /// Collect memory usage statistics.
- optional --memory-usage
/// Print the total length of all source and macro files (whitespace is not counted).
optional --source-stats
@@ -191,7 +189,6 @@ pub struct AnalysisStats {
pub output: Option<OutputFormat>,
pub randomize: bool,
pub parallel: bool,
- pub memory_usage: bool,
pub source_stats: bool,
pub only: Option<String>,
pub with_deps: bool,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
index 42d180114..d6a45ce06 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
@@ -21,7 +21,7 @@ use vfs::{AbsPathBuf, Vfs};
use crate::{
cli::flags,
line_index::{LineEndings, LineIndex, PositionEncoding},
- to_proto,
+ lsp::to_proto,
version::version,
};
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
index 44337f955..8c056fff0 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -51,7 +51,7 @@ impl flags::Scip {
version: scip_types::ProtocolVersion::UnspecifiedProtocolVersion.into(),
tool_info: Some(scip_types::ToolInfo {
name: "rust-analyzer".to_owned(),
- version: "0.1".to_owned(),
+ version: format!("{}", crate::version::version()),
arguments: vec![],
special_fields: Default::default(),
})
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index fa20c796e..ea3a21241 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -13,8 +13,9 @@ use cfg::{CfgAtom, CfgDiff};
use flycheck::FlycheckConfig;
use ide::{
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
- HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayHintsConfig,
- JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, Snippet, SnippetScope,
+ HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve,
+ InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind,
+ Snippet, SnippetScope,
};
use ide_db::{
imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
@@ -150,18 +151,22 @@ config_data! {
///
/// Set to `"all"` to pass `--all-features` to Cargo.
check_features | checkOnSave_features: Option<CargoFeaturesDef> = "null",
+ /// List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
+ ///
+ /// For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
+ check_ignore: FxHashSet<String> = "[]",
/// Specifies the working directory for running checks.
/// - "workspace": run checks for workspaces in the corresponding workspaces' root directories.
// FIXME: Ideally we would support this in some way
- /// This falls back to "root" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.
+ /// This falls back to "root" if `#rust-analyzer.cargo.check.invocationStrategy#` is set to `once`.
/// - "root": run checks in the project's root directory.
- /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+ /// This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
/// is set.
check_invocationLocation | checkOnSave_invocationLocation: InvocationLocation = "\"workspace\"",
- /// Specifies the invocation strategy to use when running the checkOnSave command.
+ /// Specifies the invocation strategy to use when running the check command.
/// If `per_workspace` is set, the command will be executed for each workspace.
/// If `once` is set, the command will be executed once.
- /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+ /// This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
/// is set.
check_invocationStrategy | checkOnSave_invocationStrategy: InvocationStrategy = "\"per_workspace\"",
/// Whether to pass `--no-default-features` to Cargo. Defaults to
@@ -1098,6 +1103,7 @@ impl Config {
remap_prefix: self.data.diagnostics_remapPrefix.clone(),
warnings_as_info: self.data.diagnostics_warningsAsInfo.clone(),
warnings_as_hint: self.data.diagnostics_warningsAsHint.clone(),
+ check_ignore: self.data.check_ignore.clone(),
}
}
@@ -1330,6 +1336,18 @@ impl Config {
}
pub fn inlay_hints(&self) -> InlayHintsConfig {
+ let client_capability_fields = self
+ .caps
+ .text_document
+ .as_ref()
+ .and_then(|text| text.inlay_hint.as_ref())
+ .and_then(|inlay_hint_caps| inlay_hint_caps.resolve_support.as_ref())
+ .map(|inlay_resolve| inlay_resolve.properties.iter())
+ .into_iter()
+ .flatten()
+ .cloned()
+ .collect::<FxHashSet<_>>();
+
InlayHintsConfig {
render_colons: self.data.inlayHints_renderColons,
type_hints: self.data.inlayHints_typeHints_enable,
@@ -1390,6 +1408,13 @@ impl Config {
} else {
None
},
+ fields_to_resolve: InlayFieldsToResolve {
+ resolve_text_edits: client_capability_fields.contains("textEdits"),
+ resolve_hint_tooltip: client_capability_fields.contains("tooltip"),
+ resolve_label_tooltip: client_capability_fields.contains("label.tooltip"),
+ resolve_label_location: client_capability_fields.contains("label.location"),
+ resolve_label_command: client_capability_fields.contains("label.command"),
+ },
}
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
index 33422fd05..71701ef16 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
@@ -6,9 +6,10 @@ use std::mem;
use ide::FileId;
use ide_db::FxHashMap;
use nohash_hasher::{IntMap, IntSet};
+use rustc_hash::FxHashSet;
use triomphe::Arc;
-use crate::lsp_ext;
+use crate::{global_state::GlobalStateSnapshot, lsp, lsp_ext};
pub(crate) type CheckFixes = Arc<IntMap<usize, IntMap<FileId, Vec<Fix>>>>;
@@ -17,6 +18,7 @@ pub struct DiagnosticsMapConfig {
pub remap_prefix: FxHashMap<String, String>,
pub warnings_as_info: Vec<String>,
pub warnings_as_hint: Vec<String>,
+ pub check_ignore: FxHashSet<String>,
}
#[derive(Debug, Default, Clone)]
@@ -120,3 +122,41 @@ fn are_diagnostics_equal(left: &lsp_types::Diagnostic, right: &lsp_types::Diagno
&& left.range == right.range
&& left.message == right.message
}
+
+pub(crate) fn fetch_native_diagnostics(
+ snapshot: GlobalStateSnapshot,
+ subscriptions: Vec<FileId>,
+) -> Vec<(FileId, Vec<lsp_types::Diagnostic>)> {
+ let _p = profile::span("fetch_native_diagnostics");
+ let _ctx = stdx::panic_context::enter("fetch_native_diagnostics".to_owned());
+ subscriptions
+ .into_iter()
+ .filter_map(|file_id| {
+ let line_index = snapshot.file_line_index(file_id).ok()?;
+ let diagnostics = snapshot
+ .analysis
+ .diagnostics(
+ &snapshot.config.diagnostics(),
+ ide::AssistResolveStrategy::None,
+ file_id,
+ )
+ .ok()?
+ .into_iter()
+ .map(move |d| lsp_types::Diagnostic {
+ range: lsp::to_proto::range(&line_index, d.range),
+ severity: Some(lsp::to_proto::diagnostic_severity(d.severity)),
+ code: Some(lsp_types::NumberOrString::String(d.code.as_str().to_string())),
+ code_description: Some(lsp_types::CodeDescription {
+ href: lsp_types::Url::parse(&d.code.url()).unwrap(),
+ }),
+ source: Some("rust-analyzer".to_string()),
+ message: d.message,
+ related_information: None,
+ tags: d.unused.then(|| vec![lsp_types::DiagnosticTag::UNNECESSARY]),
+ data: None,
+ })
+ .collect::<Vec<_>>();
+ Some((file_id, diagnostics))
+ })
+ .collect()
+}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
index e1d1130ff..731580557 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -8,8 +8,8 @@ use stdx::format_to;
use vfs::{AbsPath, AbsPathBuf};
use crate::{
- global_state::GlobalStateSnapshot, line_index::PositionEncoding, lsp_ext,
- to_proto::url_from_abs_path,
+ global_state::GlobalStateSnapshot, line_index::PositionEncoding,
+ lsp::to_proto::url_from_abs_path, lsp_ext,
};
use super::{DiagnosticsMapConfig, Fix};
@@ -292,6 +292,13 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
let mut source = String::from("rustc");
let mut code = rd.code.as_ref().map(|c| c.code.clone());
+
+ if let Some(code_val) = &code {
+ if config.check_ignore.contains(code_val) {
+ return Vec::new();
+ }
+ }
+
if let Some(code_val) = &code {
// See if this is an RFC #2103 scoped lint (e.g. from Clippy)
let scoped_code: Vec<&str> = code_val.split("::").collect();
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/dispatch.rs
index 5e5cd9a02..7da431188 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/dispatch.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/dispatch.rs
@@ -8,9 +8,9 @@ use stdx::thread::ThreadIntent;
use crate::{
global_state::{GlobalState, GlobalStateSnapshot},
+ lsp::LspError,
main_loop::Task,
version::version,
- LspError,
};
/// A visitor for routing a raw JSON request to an appropriate handler function.
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index ea8a69751..c09f57252 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -12,25 +12,27 @@ use ide_db::base_db::{CrateId, FileLoader, ProcMacroPaths, SourceDatabase};
use load_cargo::SourceRootConfig;
use lsp_types::{SemanticTokens, Url};
use nohash_hasher::IntMap;
-use parking_lot::{Mutex, RwLock};
+use parking_lot::{
+ MappedRwLockReadGuard, Mutex, RwLock, RwLockReadGuard, RwLockUpgradableReadGuard,
+ RwLockWriteGuard,
+};
use proc_macro_api::ProcMacroServer;
use project_model::{CargoWorkspace, ProjectWorkspace, Target, WorkspaceBuildScripts};
use rustc_hash::{FxHashMap, FxHashSet};
use triomphe::Arc;
-use vfs::AnchoredPathBuf;
+use vfs::{AnchoredPathBuf, Vfs};
use crate::{
config::{Config, ConfigError},
diagnostics::{CheckFixes, DiagnosticCollection},
- from_proto,
line_index::{LineEndings, LineIndex},
+ lsp::{from_proto, to_proto::url_from_abs_path},
lsp_ext,
main_loop::Task,
mem_docs::MemDocs,
op_queue::OpQueue,
reload,
task_pool::TaskPool,
- to_proto::url_from_abs_path,
};
// Enforces drop order
@@ -40,7 +42,7 @@ pub(crate) struct Handle<H, C> {
}
pub(crate) type ReqHandler = fn(&mut GlobalState, lsp_server::Response);
-pub(crate) type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>;
+type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>;
/// `GlobalState` is the primary mutable state of the language server
///
@@ -49,6 +51,7 @@ pub(crate) type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>;
/// incremental salsa database.
///
/// Note that this struct has more than one impl in various modules!
+#[doc(alias = "GlobalMess")]
pub(crate) struct GlobalState {
sender: Sender<lsp_server::Message>,
req_queue: ReqQueue,
@@ -66,6 +69,7 @@ pub(crate) struct GlobalState {
// status
pub(crate) shutdown_requested: bool,
+ pub(crate) send_hint_refresh_query: bool,
pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
// proc macros
@@ -177,6 +181,7 @@ impl GlobalState {
mem_docs: MemDocs::default(),
semantic_tokens_cache: Arc::new(Default::default()),
shutdown_requested: false,
+ send_hint_refresh_query: false,
last_reported_status: None,
source_root_config: SourceRootConfig::default(),
config_errors: Default::default(),
@@ -216,12 +221,15 @@ impl GlobalState {
let mut file_changes = FxHashMap::default();
let (change, changed_files, workspace_structure_change) = {
let mut change = Change::new();
- let (vfs, line_endings_map) = &mut *self.vfs.write();
- let changed_files = vfs.take_changes();
+ let mut guard = self.vfs.write();
+ let changed_files = guard.0.take_changes();
if changed_files.is_empty() {
return false;
}
+ // downgrade to read lock to allow more readers while we are normalizing text
+ let guard = RwLockWriteGuard::downgrade_to_upgradable(guard);
+ let vfs: &Vfs = &guard.0;
// We need to fix up the changed events a bit. If we have a create or modify for a file
// id that is followed by a delete we actually skip observing the file text from the
// earlier event, to avoid problems later on.
@@ -272,6 +280,7 @@ impl GlobalState {
let mut workspace_structure_change = None;
// A file was added or deleted
let mut has_structure_changes = false;
+ let mut bytes = vec![];
for file in &changed_files {
let vfs_path = &vfs.file_path(file.file_id);
if let Some(path) = vfs_path.as_path() {
@@ -293,16 +302,28 @@ impl GlobalState {
let text = if file.exists() {
let bytes = vfs.file_contents(file.file_id).to_vec();
+
String::from_utf8(bytes).ok().and_then(|text| {
+ // FIXME: Consider doing normalization in the `vfs` instead? That allows
+ // getting rid of some locking
let (text, line_endings) = LineEndings::normalize(text);
- line_endings_map.insert(file.file_id, line_endings);
- Some(Arc::from(text))
+ Some((Arc::from(text), line_endings))
})
} else {
None
};
- change.change_file(file.file_id, text);
+ // delay `line_endings_map` changes until we are done normalizing the text
+ // this allows delaying the re-acquisition of the write lock
+ bytes.push((file.file_id, text));
}
+ let (vfs, line_endings_map) = &mut *RwLockUpgradableReadGuard::upgrade(guard);
+ bytes.into_iter().for_each(|(file_id, text)| match text {
+ None => change.change_file(file_id, None),
+ Some((text, line_endings)) => {
+ line_endings_map.insert(file_id, line_endings);
+ change.change_file(file_id, Some(text));
+ }
+ });
if has_structure_changes {
let roots = self.source_root_config.partition(vfs);
change.set_roots(roots);
@@ -422,12 +443,16 @@ impl Drop for GlobalState {
}
impl GlobalStateSnapshot {
+ fn vfs_read(&self) -> MappedRwLockReadGuard<'_, vfs::Vfs> {
+ RwLockReadGuard::map(self.vfs.read(), |(it, _)| it)
+ }
+
pub(crate) fn url_to_file_id(&self, url: &Url) -> anyhow::Result<FileId> {
- url_to_file_id(&self.vfs.read().0, url)
+ url_to_file_id(&self.vfs_read(), url)
}
pub(crate) fn file_id_to_url(&self, id: FileId) -> Url {
- file_id_to_url(&self.vfs.read().0, id)
+ file_id_to_url(&self.vfs_read(), id)
}
pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancellable<LineIndex> {
@@ -443,7 +468,7 @@ impl GlobalStateSnapshot {
}
pub(crate) fn anchored_path(&self, path: &AnchoredPathBuf) -> Url {
- let mut base = self.vfs.read().0.file_path(path.anchor);
+ let mut base = self.vfs_read().file_path(path.anchor);
base.pop();
let path = base.join(&path.path).unwrap();
let path = path.as_path().unwrap();
@@ -451,7 +476,7 @@ impl GlobalStateSnapshot {
}
pub(crate) fn file_id_to_file_path(&self, file_id: FileId) -> vfs::VfsPath {
- self.vfs.read().0.file_path(file_id)
+ self.vfs_read().file_path(file_id)
}
pub(crate) fn cargo_target_for_crate_root(
@@ -459,7 +484,7 @@ impl GlobalStateSnapshot {
crate_id: CrateId,
) -> Option<(&CargoWorkspace, Target)> {
let file_id = self.analysis.crate_root(crate_id).ok()?;
- let path = self.vfs.read().0.file_path(file_id);
+ let path = self.vfs_read().file_path(file_id);
let path = path.as_path()?;
self.workspaces.iter().find_map(|ws| match ws {
ProjectWorkspace::Cargo { cargo, .. } => {
@@ -471,7 +496,11 @@ impl GlobalStateSnapshot {
}
pub(crate) fn vfs_memory_usage(&self) -> usize {
- self.vfs.read().0.memory_usage()
+ self.vfs_read().memory_usage()
+ }
+
+ pub(crate) fn file_exists(&self, file_id: FileId) -> bool {
+ self.vfs.read().0.exists(file_id)
}
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
index e830e5e9a..f9070d273 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
@@ -13,8 +13,12 @@ use triomphe::Arc;
use vfs::{AbsPathBuf, ChangeKind, VfsPath};
use crate::{
- config::Config, from_proto, global_state::GlobalState, lsp_ext::RunFlycheckParams,
- lsp_utils::apply_document_changes, mem_docs::DocumentData, reload,
+ config::Config,
+ global_state::GlobalState,
+ lsp::{from_proto, utils::apply_document_changes},
+ lsp_ext::RunFlycheckParams,
+ mem_docs::DocumentData,
+ reload,
};
pub(crate) fn handle_cancel(state: &mut GlobalState, params: CancelParams) -> anyhow::Result<()> {
@@ -84,15 +88,16 @@ pub(crate) fn handle_did_change_text_document(
}
};
- let vfs = &mut state.vfs.write().0;
- let file_id = vfs.file_id(&path).unwrap();
let text = apply_document_changes(
state.config.position_encoding(),
- || std::str::from_utf8(vfs.file_contents(file_id)).unwrap().into(),
+ || {
+ let vfs = &state.vfs.read().0;
+ let file_id = vfs.file_id(&path).unwrap();
+ std::str::from_utf8(vfs.file_contents(file_id)).unwrap().into()
+ },
params.content_changes,
);
-
- vfs.set_file_contents(path, Some(text.into_bytes()));
+ state.vfs.write().0.set_file_contents(path, Some(text.into_bytes()));
}
Ok(())
}
@@ -108,6 +113,10 @@ pub(crate) fn handle_did_close_text_document(
tracing::error!("orphan DidCloseTextDocument: {}", path);
}
+ if let Some(file_id) = state.vfs.read().0.file_id(&path) {
+ state.diagnostics.clear_native_for(file_id);
+ }
+
state.semantic_tokens_cache.lock().remove(&params.text_document.uri);
if let Some(path) = path.as_path() {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index 5f1f731cf..b8a1a39be 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -11,8 +11,8 @@ use anyhow::Context;
use ide::{
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
- HoverAction, HoverGotoTypeData, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
- SingleResolve, SourceChange, TextEdit,
+ HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory,
+ Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
};
use ide_db::SymbolKind;
use lsp_server::ErrorCode;
@@ -30,21 +30,23 @@ use serde_json::json;
use stdx::{format_to, never};
use syntax::{algo, ast, AstNode, TextRange, TextSize};
use triomphe::Arc;
-use vfs::{AbsPath, AbsPathBuf, VfsPath};
+use vfs::{AbsPath, AbsPathBuf, FileId, VfsPath};
use crate::{
cargo_target_spec::CargoTargetSpec,
config::{Config, RustfmtConfig, WorkspaceSymbolConfig},
diff::diff,
- from_proto,
global_state::{GlobalState, GlobalStateSnapshot},
line_index::LineEndings,
+ lsp::{
+ from_proto, to_proto,
+ utils::{all_edits_are_disjoint, invalid_params_error},
+ LspError,
+ },
lsp_ext::{
self, CrateInfoResult, ExternalDocsPair, ExternalDocsResponse, FetchDependencyListParams,
FetchDependencyListResult, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams,
},
- lsp_utils::{all_edits_are_disjoint, invalid_params_error},
- to_proto, LspError,
};
pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> anyhow::Result<()> {
@@ -354,7 +356,7 @@ pub(crate) fn handle_on_type_formatting(
// This should be a single-file edit
let (_, (text_edit, snippet_edit)) = edit.source_file_edits.into_iter().next().unwrap();
- stdx::never!(snippet_edit.is_none(), "on type formatting shouldn't use structured snippets");
+ stdx::always!(snippet_edit.is_none(), "on type formatting shouldn't use structured snippets");
let change = to_proto::snippet_text_edit_vec(&line_index, edit.is_snippet, text_edit);
Ok(Some(change))
@@ -972,7 +974,7 @@ pub(crate) fn handle_hover(
PositionOrRange::Range(range) => range,
};
- let file_range = from_proto::file_range(&snap, params.text_document, range)?;
+ let file_range = from_proto::file_range(&snap, &params.text_document, range)?;
let info = match snap.analysis.hover(&snap.config.hover(), file_range)? {
None => return Ok(None),
Some(info) => info,
@@ -1128,7 +1130,7 @@ pub(crate) fn handle_code_action(
let line_index =
snap.file_line_index(from_proto::file_id(&snap, &params.text_document.uri)?)?;
- let frange = from_proto::file_range(&snap, params.text_document.clone(), params.range)?;
+ let frange = from_proto::file_range(&snap, &params.text_document, params.range)?;
let mut assists_config = snap.config.assist();
assists_config.allowed = params
@@ -1381,7 +1383,7 @@ pub(crate) fn handle_ssr(
let selections = params
.selections
.iter()
- .map(|range| from_proto::file_range(&snap, params.position.text_document.clone(), *range))
+ .map(|range| from_proto::file_range(&snap, &params.position.text_document, *range))
.collect::<Result<Vec<_>, _>>()?;
let position = from_proto::file_position(&snap, params.position)?;
let source_change = snap.analysis.structural_search_replace(
@@ -1401,7 +1403,7 @@ pub(crate) fn handle_inlay_hints(
let document_uri = &params.text_document.uri;
let FileRange { file_id, range } = from_proto::file_range(
&snap,
- TextDocumentIdentifier::new(document_uri.to_owned()),
+ &TextDocumentIdentifier::new(document_uri.to_owned()),
params.range,
)?;
let line_index = snap.file_line_index(file_id)?;
@@ -1410,17 +1412,73 @@ pub(crate) fn handle_inlay_hints(
snap.analysis
.inlay_hints(&inlay_hints_config, file_id, Some(range))?
.into_iter()
- .map(|it| to_proto::inlay_hint(&snap, &line_index, it))
+ .map(|it| {
+ to_proto::inlay_hint(
+ &snap,
+ &inlay_hints_config.fields_to_resolve,
+ &line_index,
+ file_id,
+ it,
+ )
+ })
.collect::<Cancellable<Vec<_>>>()?,
))
}
pub(crate) fn handle_inlay_hints_resolve(
- _snap: GlobalStateSnapshot,
- hint: InlayHint,
+ snap: GlobalStateSnapshot,
+ mut original_hint: InlayHint,
) -> anyhow::Result<InlayHint> {
let _p = profile::span("handle_inlay_hints_resolve");
- Ok(hint)
+
+ let data = match original_hint.data.take() {
+ Some(it) => it,
+ None => return Ok(original_hint),
+ };
+
+ let resolve_data: lsp_ext::InlayHintResolveData = serde_json::from_value(data)?;
+ let file_id = FileId(resolve_data.file_id);
+ anyhow::ensure!(snap.file_exists(file_id), "Invalid LSP resolve data");
+
+ let line_index = snap.file_line_index(file_id)?;
+ let range = from_proto::text_range(
+ &line_index,
+ lsp_types::Range { start: original_hint.position, end: original_hint.position },
+ )?;
+ let range_start = range.start();
+ let range_end = range.end();
+ let large_range = TextRange::new(
+ range_start.checked_sub(1.into()).unwrap_or(range_start),
+ range_end.checked_add(1.into()).unwrap_or(range_end),
+ );
+ let mut forced_resolve_inlay_hints_config = snap.config.inlay_hints();
+ forced_resolve_inlay_hints_config.fields_to_resolve = InlayFieldsToResolve::empty();
+ let resolve_hints = snap.analysis.inlay_hints(
+ &forced_resolve_inlay_hints_config,
+ file_id,
+ Some(large_range),
+ )?;
+
+ let mut resolved_hints = resolve_hints
+ .into_iter()
+ .filter_map(|it| {
+ to_proto::inlay_hint(
+ &snap,
+ &forced_resolve_inlay_hints_config.fields_to_resolve,
+ &line_index,
+ file_id,
+ it,
+ )
+ .ok()
+ })
+ .filter(|hint| hint.position == original_hint.position)
+ .filter(|hint| hint.kind == original_hint.kind);
+ if let Some(resolved_hint) = resolved_hints.next() {
+ if resolved_hints.next().is_none() {
+ return Ok(resolved_hint);
+ }
+ }
+ Ok(original_hint)
}
pub(crate) fn handle_call_hierarchy_prepare(
@@ -1453,7 +1511,7 @@ pub(crate) fn handle_call_hierarchy_incoming(
let item = params.item;
let doc = TextDocumentIdentifier::new(item.uri);
- let frange = from_proto::file_range(&snap, doc, item.selection_range)?;
+ let frange = from_proto::file_range(&snap, &doc, item.selection_range)?;
let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
let call_items = match snap.analysis.incoming_calls(fpos)? {
@@ -1488,7 +1546,7 @@ pub(crate) fn handle_call_hierarchy_outgoing(
let item = params.item;
let doc = TextDocumentIdentifier::new(item.uri);
- let frange = from_proto::file_range(&snap, doc, item.selection_range)?;
+ let frange = from_proto::file_range(&snap, &doc, item.selection_range)?;
let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
let call_items = match snap.analysis.outgoing_calls(fpos)? {
@@ -1569,18 +1627,21 @@ pub(crate) fn handle_semantic_tokens_full_delta(
snap.config.highlighting_non_standard_tokens(),
);
- let mut cache = snap.semantic_tokens_cache.lock();
- let cached_tokens = cache.entry(params.text_document.uri).or_default();
+ let cached_tokens = snap.semantic_tokens_cache.lock().remove(&params.text_document.uri);
- if let Some(prev_id) = &cached_tokens.result_id {
+ if let Some(cached_tokens @ lsp_types::SemanticTokens { result_id: Some(prev_id), .. }) =
+ &cached_tokens
+ {
if *prev_id == params.previous_result_id {
let delta = to_proto::semantic_token_delta(cached_tokens, &semantic_tokens);
- *cached_tokens = semantic_tokens;
+ snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens);
return Ok(Some(delta.into()));
}
}
- *cached_tokens = semantic_tokens.clone();
+ // Clone first to keep the lock short
+ let semantic_tokens_clone = semantic_tokens.clone();
+ snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens_clone);
Ok(Some(semantic_tokens.into()))
}
@@ -1591,7 +1652,7 @@ pub(crate) fn handle_semantic_tokens_range(
) -> anyhow::Result<Option<SemanticTokensRangeResult>> {
let _p = profile::span("handle_semantic_tokens_range");
- let frange = from_proto::file_range(&snap, params.text_document, params.range)?;
+ let frange = from_proto::file_range(&snap, &params.text_document, params.range)?;
let text = snap.analysis.file_text(frange.file_id)?;
let line_index = snap.file_line_index(frange.file_id)?;
@@ -1674,7 +1735,7 @@ pub(crate) fn handle_move_item(
) -> anyhow::Result<Vec<lsp_ext::SnippetTextEdit>> {
let _p = profile::span("handle_move_item");
let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
- let range = from_proto::file_range(&snap, params.text_document, params.range)?;
+ let range = from_proto::file_range(&snap, &params.text_document, params.range)?;
let direction = match params.direction {
lsp_ext::MoveItemDirection::Up => ide::Direction::Up,
@@ -1879,12 +1940,15 @@ fn run_rustfmt(
// Determine the edition of the crate the file belongs to (if there's multiple, we pick the
// highest edition).
- let editions = snap
+ let Ok(editions) = snap
.analysis
.relevant_crates_for(file_id)?
.into_iter()
.map(|crate_id| snap.analysis.crate_edition(crate_id))
- .collect::<Result<Vec<_>, _>>()?;
+ .collect::<Result<Vec<_>, _>>()
+ else {
+ return Ok(None);
+ };
let edition = editions.iter().copied().max();
let line_index = snap.file_line_index(file_id)?;
@@ -1894,23 +1958,7 @@ fn run_rustfmt(
let mut cmd = process::Command::new(toolchain::rustfmt());
cmd.envs(snap.config.extra_env());
cmd.args(extra_args);
- // try to chdir to the file so we can respect `rustfmt.toml`
- // FIXME: use `rustfmt --config-path` once
- // https://github.com/rust-lang/rustfmt/issues/4660 gets fixed
- match text_document.uri.to_file_path() {
- Ok(mut path) => {
- // pop off file name
- if path.pop() && path.is_dir() {
- cmd.current_dir(path);
- }
- }
- Err(_) => {
- tracing::error!(
- "Unable to get file path for {}, rustfmt.toml might be ignored",
- text_document.uri
- );
- }
- }
+
if let Some(edition) = edition {
cmd.arg("--edition");
cmd.arg(edition.to_string());
@@ -1929,7 +1977,7 @@ fn run_rustfmt(
.into());
}
- let frange = from_proto::file_range(snap, text_document, range)?;
+ let frange = from_proto::file_range(snap, &text_document, range)?;
let start_line = line_index.index.line_col(frange.range.start()).line;
let end_line = line_index.index.line_col(frange.range.end()).line;
@@ -1948,12 +1996,31 @@ fn run_rustfmt(
}
RustfmtConfig::CustomCommand { command, args } => {
let mut cmd = process::Command::new(command);
+
cmd.envs(snap.config.extra_env());
cmd.args(args);
cmd
}
};
+ // try to chdir to the file so we can respect `rustfmt.toml`
+ // FIXME: use `rustfmt --config-path` once
+ // https://github.com/rust-lang/rustfmt/issues/4660 gets fixed
+ match text_document.uri.to_file_path() {
+ Ok(mut path) => {
+ // pop off file name
+ if path.pop() && path.is_dir() {
+ command.current_dir(path);
+ }
+ }
+ Err(_) => {
+ tracing::error!(
+ text_document = ?text_document.uri,
+ "Unable to get path, rustfmt.toml might be ignored"
+ );
+ }
+ }
+
let mut rustfmt = command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
index 57e26c241..6c62577f6 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
@@ -23,18 +23,13 @@ mod cargo_target_spec;
mod diagnostics;
mod diff;
mod dispatch;
-mod from_proto;
mod global_state;
mod line_index;
-mod lsp_utils;
mod main_loop;
-mod markdown;
mod mem_docs;
mod op_queue;
mod reload;
-mod semantic_tokens;
mod task_pool;
-mod to_proto;
mod version;
mod handlers {
@@ -43,13 +38,12 @@ mod handlers {
}
pub mod config;
-pub mod lsp_ext;
+pub mod lsp;
+use self::lsp::ext as lsp_ext;
#[cfg(test)]
mod integrated_benchmarks;
-use std::fmt;
-
use serde::de::DeserializeOwned;
pub use crate::{caps::server_capabilities, main_loop::main_loop, version::version};
@@ -61,23 +55,3 @@ pub fn from_json<T: DeserializeOwned>(
serde_json::from_value(json.clone())
.map_err(|e| anyhow::format_err!("Failed to deserialize {what}: {e}; {json}"))
}
-
-#[derive(Debug)]
-struct LspError {
- code: i32,
- message: String,
-}
-
-impl LspError {
- fn new(code: i32, message: String) -> LspError {
- LspError { code, message }
- }
-}
-
-impl fmt::Display for LspError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Language Server request failed with {}. ({})", self.code, self.message)
- }
-}
-
-impl std::error::Error for LspError {}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs
new file mode 100644
index 000000000..ac7e1a95e
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp.rs
@@ -0,0 +1,29 @@
+//! Custom LSP definitions and protocol conversions.
+
+use core::fmt;
+
+pub(crate) mod utils;
+pub(crate) mod semantic_tokens;
+pub mod ext;
+pub(crate) mod from_proto;
+pub(crate) mod to_proto;
+
+#[derive(Debug)]
+pub(crate) struct LspError {
+ pub(crate) code: i32,
+ pub(crate) message: String,
+}
+
+impl LspError {
+ pub(crate) fn new(code: i32, message: String) -> LspError {
+ LspError { code, message }
+ }
+}
+
+impl fmt::Display for LspError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Language Server request failed with {}. ({})", self.code, self.message)
+ }
+}
+
+impl std::error::Error for LspError {}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
index d0989b323..ad5689916 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
@@ -682,7 +682,9 @@ pub struct CompletionResolveData {
}
#[derive(Debug, Serialize, Deserialize)]
-pub struct InlayHintResolveData {}
+pub struct InlayHintResolveData {
+ pub file_id: u32,
+}
#[derive(Debug, Serialize, Deserialize)]
pub struct CompletionImport {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
index c247e1bb2..69d6aba94 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs
@@ -12,8 +12,8 @@ use crate::{
from_json,
global_state::GlobalStateSnapshot,
line_index::{LineIndex, PositionEncoding},
+ lsp::utils::invalid_params_error,
lsp_ext,
- lsp_utils::invalid_params_error,
};
pub(crate) fn abs_path(url: &lsp_types::Url) -> anyhow::Result<AbsPathBuf> {
@@ -72,7 +72,7 @@ pub(crate) fn file_position(
pub(crate) fn file_range(
snap: &GlobalStateSnapshot,
- text_document_identifier: lsp_types::TextDocumentIdentifier,
+ text_document_identifier: &lsp_types::TextDocumentIdentifier,
range: lsp_types::Range,
) -> anyhow::Result<FileRange> {
file_range_uri(snap, &text_document_identifier.uri, range)
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs
index 1fe02fc7e..1fe02fc7e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/semantic_tokens.rs
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
index 7b32180e3..23074493a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -8,11 +8,12 @@ use std::{
use ide::{
Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionItem,
CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit,
- Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint,
- InlayHintLabel, InlayHintLabelPart, InlayKind, Markup, NavigationTarget, ReferenceCategory,
- RenameError, Runnable, Severity, SignatureHelp, SnippetEdit, SourceChange, StructureNodeKind,
- SymbolKind, TextEdit, TextRange, TextSize,
+ Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel,
+ InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, Markup,
+ NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
+ SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
};
+use ide_db::rust_doc::format_docs;
use itertools::Itertools;
use serde_json::to_value;
use vfs::AbsPath;
@@ -22,9 +23,12 @@ use crate::{
config::{CallInfoConfig, Config},
global_state::GlobalStateSnapshot,
line_index::{LineEndings, LineIndex, PositionEncoding},
+ lsp::{
+ semantic_tokens::{self, standard_fallback_type},
+ utils::invalid_params_error,
+ LspError,
+ },
lsp_ext::{self, SnippetTextEdit},
- lsp_utils::invalid_params_error,
- semantic_tokens::{self, standard_fallback_type},
};
pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
@@ -102,7 +106,7 @@ pub(crate) fn diagnostic_severity(severity: Severity) -> lsp_types::DiagnosticSe
}
pub(crate) fn documentation(documentation: Documentation) -> lsp_types::Documentation {
- let value = crate::markdown::format_docs(documentation.as_str());
+ let value = format_docs(&documentation);
let markup_content = lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, value };
lsp_types::Documentation::MarkupContent(markup_content)
}
@@ -413,7 +417,7 @@ pub(crate) fn signature_help(
let documentation = call_info.doc.filter(|_| config.docs).map(|doc| {
lsp_types::Documentation::MarkupContent(lsp_types::MarkupContent {
kind: lsp_types::MarkupKind::Markdown,
- value: crate::markdown::format_docs(&doc),
+ value: format_docs(&doc),
})
});
@@ -434,10 +438,25 @@ pub(crate) fn signature_help(
pub(crate) fn inlay_hint(
snap: &GlobalStateSnapshot,
+ fields_to_resolve: &InlayFieldsToResolve,
line_index: &LineIndex,
+ file_id: FileId,
inlay_hint: InlayHint,
) -> Cancellable<lsp_types::InlayHint> {
- let (label, tooltip) = inlay_hint_label(snap, inlay_hint.label)?;
+ let needs_resolve = inlay_hint.needs_resolve;
+ let (label, tooltip, mut something_to_resolve) =
+ inlay_hint_label(snap, fields_to_resolve, needs_resolve, inlay_hint.label)?;
+ let text_edits = if needs_resolve && fields_to_resolve.resolve_text_edits {
+ something_to_resolve |= inlay_hint.text_edit.is_some();
+ None
+ } else {
+ inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it))
+ };
+ let data = if needs_resolve && something_to_resolve {
+ Some(to_value(lsp_ext::InlayHintResolveData { file_id: file_id.0 }).unwrap())
+ } else {
+ None
+ };
Ok(lsp_types::InlayHint {
position: match inlay_hint.position {
@@ -451,8 +470,8 @@ pub(crate) fn inlay_hint(
InlayKind::Type | InlayKind::Chaining => Some(lsp_types::InlayHintKind::TYPE),
_ => None,
},
- text_edits: inlay_hint.text_edit.map(|it| text_edit_vec(line_index, it)),
- data: None,
+ text_edits,
+ data,
tooltip,
label,
})
@@ -460,13 +479,18 @@ pub(crate) fn inlay_hint(
fn inlay_hint_label(
snap: &GlobalStateSnapshot,
+ fields_to_resolve: &InlayFieldsToResolve,
+ needs_resolve: bool,
mut label: InlayHintLabel,
-) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> {
- let res = match &*label.parts {
+) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>, bool)> {
+ let mut something_to_resolve = false;
+ let (label, tooltip) = match &*label.parts {
[InlayHintLabelPart { linked_location: None, .. }] => {
let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
- (
- lsp_types::InlayHintLabel::String(text),
+ let hint_tooltip = if needs_resolve && fields_to_resolve.resolve_hint_tooltip {
+ something_to_resolve |= tooltip.is_some();
+ None
+ } else {
match tooltip {
Some(ide::InlayTooltip::String(s)) => {
Some(lsp_types::InlayHintTooltip::String(s))
@@ -478,41 +502,52 @@ fn inlay_hint_label(
}))
}
None => None,
- },
- )
+ }
+ };
+ (lsp_types::InlayHintLabel::String(text), hint_tooltip)
}
_ => {
let parts = label
.parts
.into_iter()
.map(|part| {
- part.linked_location.map(|range| location(snap, range)).transpose().map(
- |location| lsp_types::InlayHintLabelPart {
- value: part.text,
- tooltip: match part.tooltip {
- Some(ide::InlayTooltip::String(s)) => {
- Some(lsp_types::InlayHintLabelPartTooltip::String(s))
- }
- Some(ide::InlayTooltip::Markdown(s)) => {
- Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
- lsp_types::MarkupContent {
- kind: lsp_types::MarkupKind::Markdown,
- value: s,
- },
- ))
- }
- None => None,
- },
- location,
- command: None,
- },
- )
+ let tooltip = if needs_resolve && fields_to_resolve.resolve_label_tooltip {
+ something_to_resolve |= part.tooltip.is_some();
+ None
+ } else {
+ match part.tooltip {
+ Some(ide::InlayTooltip::String(s)) => {
+ Some(lsp_types::InlayHintLabelPartTooltip::String(s))
+ }
+ Some(ide::InlayTooltip::Markdown(s)) => {
+ Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
+ lsp_types::MarkupContent {
+ kind: lsp_types::MarkupKind::Markdown,
+ value: s,
+ },
+ ))
+ }
+ None => None,
+ }
+ };
+ let location = if needs_resolve && fields_to_resolve.resolve_label_location {
+ something_to_resolve |= part.linked_location.is_some();
+ None
+ } else {
+ part.linked_location.map(|range| location(snap, range)).transpose()?
+ };
+ Ok(lsp_types::InlayHintLabelPart {
+ value: part.text,
+ tooltip,
+ location,
+ command: None,
+ })
})
.collect::<Cancellable<_>>()?;
(lsp_types::InlayHintLabel::LabelParts(parts), None)
}
};
- Ok(res)
+ Ok((label, tooltip, something_to_resolve))
}
static TOKEN_RESULT_COUNTER: AtomicU32 = AtomicU32::new(1);
@@ -1323,17 +1358,18 @@ pub(crate) fn code_lens(
})
}
}
- AnnotationKind::HasImpls { pos: file_range, data } => {
+ AnnotationKind::HasImpls { pos, data } => {
if !client_commands_config.show_reference {
return Ok(());
}
- let line_index = snap.file_line_index(file_range.file_id)?;
+ let line_index = snap.file_line_index(pos.file_id)?;
let annotation_range = range(&line_index, annotation.range);
- let url = url(snap, file_range.file_id);
+ let url = url(snap, pos.file_id);
+ let pos = position(&line_index, pos.offset);
let id = lsp_types::TextDocumentIdentifier { uri: url.clone() };
- let doc_pos = lsp_types::TextDocumentPositionParams::new(id, annotation_range.start);
+ let doc_pos = lsp_types::TextDocumentPositionParams::new(id, pos);
let goto_params = lsp_types::request::GotoImplementationParams {
text_document_position_params: doc_pos,
@@ -1356,7 +1392,7 @@ pub(crate) fn code_lens(
command::show_references(
implementation_title(locations.len()),
&url,
- annotation_range.start,
+ pos,
locations,
)
});
@@ -1376,28 +1412,24 @@ pub(crate) fn code_lens(
})(),
})
}
- AnnotationKind::HasReferences { pos: file_range, data } => {
+ AnnotationKind::HasReferences { pos, data } => {
if !client_commands_config.show_reference {
return Ok(());
}
- let line_index = snap.file_line_index(file_range.file_id)?;
+ let line_index = snap.file_line_index(pos.file_id)?;
let annotation_range = range(&line_index, annotation.range);
- let url = url(snap, file_range.file_id);
+ let url = url(snap, pos.file_id);
+ let pos = position(&line_index, pos.offset);
let id = lsp_types::TextDocumentIdentifier { uri: url.clone() };
- let doc_pos = lsp_types::TextDocumentPositionParams::new(id, annotation_range.start);
+ let doc_pos = lsp_types::TextDocumentPositionParams::new(id, pos);
let command = data.map(|ranges| {
let locations: Vec<lsp_types::Location> =
ranges.into_iter().filter_map(|range| location(snap, range).ok()).collect();
- command::show_references(
- reference_title(locations.len()),
- &url,
- annotation_range.start,
- locations,
- )
+ command::show_references(reference_title(locations.len()), &url, pos, locations)
});
acc.push(lsp_types::CodeLens {
@@ -1425,8 +1457,8 @@ pub(crate) mod command {
use crate::{
global_state::GlobalStateSnapshot,
+ lsp::to_proto::{location, location_link},
lsp_ext,
- to_proto::{location, location_link},
};
pub(crate) fn show_references(
@@ -1528,11 +1560,11 @@ pub(crate) fn markup_content(
ide::HoverDocFormat::Markdown => lsp_types::MarkupKind::Markdown,
ide::HoverDocFormat::PlainText => lsp_types::MarkupKind::PlainText,
};
- let value = crate::markdown::format_docs(markup.as_str());
+ let value = format_docs(&Documentation::new(markup.into()));
lsp_types::MarkupContent { kind, value }
}
-pub(crate) fn rename_error(err: RenameError) -> crate::LspError {
+pub(crate) fn rename_error(err: RenameError) -> LspError {
// This is wrong, but we don't have a better alternative I suppose?
// https://github.com/microsoft/language-server-protocol/issues/1341
invalid_params_error(err.to_string())
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
index 74e79e8e6..b388b3175 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs
@@ -6,10 +6,10 @@ use lsp_types::request::Request;
use triomphe::Arc;
use crate::{
- from_proto,
global_state::GlobalState,
line_index::{LineEndings, LineIndex, PositionEncoding},
- lsp_ext, LspError,
+ lsp::{from_proto, LspError},
+ lsp_ext,
};
pub(crate) fn invalid_params_error(message: String) -> LspError {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index 74036710f..cdf41c955 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -17,11 +17,14 @@ use vfs::FileId;
use crate::{
config::Config,
+ diagnostics::fetch_native_diagnostics,
dispatch::{NotificationDispatcher, RequestDispatcher},
- from_proto,
global_state::{file_id_to_url, url_to_file_id, GlobalState},
+ lsp::{
+ from_proto,
+ utils::{notification_is, Progress},
+ },
lsp_ext,
- lsp_utils::{notification_is, Progress},
reload::{BuildDataProgress, ProcMacroProgress, ProjectWorkspaceProgress},
};
@@ -317,8 +320,11 @@ impl GlobalState {
}
// Refresh inlay hints if the client supports it.
- if self.config.inlay_hints_refresh() {
+ if (self.send_hint_refresh_query || self.proc_macro_changed)
+ && self.config.inlay_hints_refresh()
+ {
self.send_request::<lsp_types::request::InlayHintRefreshRequest>((), |_, _| ());
+ self.send_hint_refresh_query = false;
}
}
@@ -420,6 +426,32 @@ impl GlobalState {
});
}
+ fn update_diagnostics(&mut self) {
+ let db = self.analysis_host.raw_database();
+ let subscriptions = self
+ .mem_docs
+ .iter()
+ .map(|path| self.vfs.read().0.file_id(path).unwrap())
+ .filter(|&file_id| {
+ let source_root = db.file_source_root(file_id);
+ // Only publish diagnostics for files in the workspace, not from crates.io deps
+ // or the sysroot.
+ // While theoretically these should never have errors, we have quite a few false
+ // positives particularly in the stdlib, and those diagnostics would stay around
+ // forever if we emitted them here.
+ !db.source_root(source_root).is_library
+ })
+ .collect::<Vec<_>>();
+ tracing::trace!("updating notifications for {:?}", subscriptions);
+
+ // Diagnostics are triggered by the user typing
+ // so we run them on a latency sensitive thread.
+ self.task_pool.handle.spawn(ThreadIntent::LatencySensitive, {
+ let snapshot = self.snapshot();
+ move || Task::Diagnostics(fetch_native_diagnostics(snapshot, subscriptions))
+ });
+ }
+
fn update_status_or_notify(&mut self) {
let status = self.current_status();
if self.last_reported_status.as_ref() != Some(&status) {
@@ -509,6 +541,7 @@ impl GlobalState {
}
self.switch_workspaces("fetched build data".to_string());
+ self.send_hint_refresh_query = true;
(Some(Progress::End), None)
}
@@ -525,7 +558,7 @@ impl GlobalState {
ProcMacroProgress::End(proc_macro_load_result) => {
self.fetch_proc_macros_queue.op_completed(true);
self.set_proc_macros(proc_macro_load_result);
-
+ self.send_hint_refresh_query = true;
(Some(Progress::End), None)
}
};
@@ -670,6 +703,7 @@ impl GlobalState {
}
use crate::handlers::request as handlers;
+ use lsp_types::request as lsp_request;
dispatcher
// Request handlers that must run on the main thread
@@ -682,30 +716,30 @@ impl GlobalState {
// are run on the main thread to reduce latency:
.on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines)
.on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter)
- .on_sync::<lsp_types::request::SelectionRangeRequest>(handlers::handle_selection_range)
+ .on_sync::<lsp_request::SelectionRangeRequest>(handlers::handle_selection_range)
.on_sync::<lsp_ext::MatchingBrace>(handlers::handle_matching_brace)
.on_sync::<lsp_ext::OnTypeFormatting>(handlers::handle_on_type_formatting)
// Formatting should be done immediately as the editor might wait on it, but we can't
// put it on the main thread as we do not want the main thread to block on rustfmt.
// So we have an extra thread just for formatting requests to make sure it gets handled
// as fast as possible.
- .on_fmt_thread::<lsp_types::request::Formatting>(handlers::handle_formatting)
- .on_fmt_thread::<lsp_types::request::RangeFormatting>(handlers::handle_range_formatting)
+ .on_fmt_thread::<lsp_request::Formatting>(handlers::handle_formatting)
+ .on_fmt_thread::<lsp_request::RangeFormatting>(handlers::handle_range_formatting)
// We can’t run latency-sensitive request handlers which do semantic
// analysis on the main thread because that would block other
// requests. Instead, we run these request handlers on higher priority
// threads in the threadpool.
- .on_latency_sensitive::<lsp_types::request::Completion>(handlers::handle_completion)
- .on_latency_sensitive::<lsp_types::request::ResolveCompletionItem>(
+ .on_latency_sensitive::<lsp_request::Completion>(handlers::handle_completion)
+ .on_latency_sensitive::<lsp_request::ResolveCompletionItem>(
handlers::handle_completion_resolve,
)
- .on_latency_sensitive::<lsp_types::request::SemanticTokensFullRequest>(
+ .on_latency_sensitive::<lsp_request::SemanticTokensFullRequest>(
handlers::handle_semantic_tokens_full,
)
- .on_latency_sensitive::<lsp_types::request::SemanticTokensFullDeltaRequest>(
+ .on_latency_sensitive::<lsp_request::SemanticTokensFullDeltaRequest>(
handlers::handle_semantic_tokens_full_delta,
)
- .on_latency_sensitive::<lsp_types::request::SemanticTokensRangeRequest>(
+ .on_latency_sensitive::<lsp_request::SemanticTokensRangeRequest>(
handlers::handle_semantic_tokens_range,
)
// All other request handlers
@@ -729,29 +763,25 @@ impl GlobalState {
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
.on::<lsp_ext::MoveItem>(handlers::handle_move_item)
.on::<lsp_ext::WorkspaceSymbol>(handlers::handle_workspace_symbol)
- .on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
- .on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition)
- .on::<lsp_types::request::GotoDeclaration>(handlers::handle_goto_declaration)
- .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation)
- .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition)
- .on_no_retry::<lsp_types::request::InlayHintRequest>(handlers::handle_inlay_hints)
- .on::<lsp_types::request::InlayHintResolveRequest>(handlers::handle_inlay_hints_resolve)
- .on::<lsp_types::request::CodeLensRequest>(handlers::handle_code_lens)
- .on::<lsp_types::request::CodeLensResolve>(handlers::handle_code_lens_resolve)
- .on::<lsp_types::request::FoldingRangeRequest>(handlers::handle_folding_range)
- .on::<lsp_types::request::SignatureHelpRequest>(handlers::handle_signature_help)
- .on::<lsp_types::request::PrepareRenameRequest>(handlers::handle_prepare_rename)
- .on::<lsp_types::request::Rename>(handlers::handle_rename)
- .on::<lsp_types::request::References>(handlers::handle_references)
- .on::<lsp_types::request::DocumentHighlightRequest>(handlers::handle_document_highlight)
- .on::<lsp_types::request::CallHierarchyPrepare>(handlers::handle_call_hierarchy_prepare)
- .on::<lsp_types::request::CallHierarchyIncomingCalls>(
- handlers::handle_call_hierarchy_incoming,
- )
- .on::<lsp_types::request::CallHierarchyOutgoingCalls>(
- handlers::handle_call_hierarchy_outgoing,
- )
- .on::<lsp_types::request::WillRenameFiles>(handlers::handle_will_rename_files)
+ .on::<lsp_request::DocumentSymbolRequest>(handlers::handle_document_symbol)
+ .on::<lsp_request::GotoDefinition>(handlers::handle_goto_definition)
+ .on::<lsp_request::GotoDeclaration>(handlers::handle_goto_declaration)
+ .on::<lsp_request::GotoImplementation>(handlers::handle_goto_implementation)
+ .on::<lsp_request::GotoTypeDefinition>(handlers::handle_goto_type_definition)
+ .on_no_retry::<lsp_request::InlayHintRequest>(handlers::handle_inlay_hints)
+ .on::<lsp_request::InlayHintResolveRequest>(handlers::handle_inlay_hints_resolve)
+ .on::<lsp_request::CodeLensRequest>(handlers::handle_code_lens)
+ .on::<lsp_request::CodeLensResolve>(handlers::handle_code_lens_resolve)
+ .on::<lsp_request::FoldingRangeRequest>(handlers::handle_folding_range)
+ .on::<lsp_request::SignatureHelpRequest>(handlers::handle_signature_help)
+ .on::<lsp_request::PrepareRenameRequest>(handlers::handle_prepare_rename)
+ .on::<lsp_request::Rename>(handlers::handle_rename)
+ .on::<lsp_request::References>(handlers::handle_references)
+ .on::<lsp_request::DocumentHighlightRequest>(handlers::handle_document_highlight)
+ .on::<lsp_request::CallHierarchyPrepare>(handlers::handle_call_hierarchy_prepare)
+ .on::<lsp_request::CallHierarchyIncomingCalls>(handlers::handle_call_hierarchy_incoming)
+ .on::<lsp_request::CallHierarchyOutgoingCalls>(handlers::handle_call_hierarchy_outgoing)
+ .on::<lsp_request::WillRenameFiles>(handlers::handle_will_rename_files)
.on::<lsp_ext::Ssr>(handlers::handle_ssr)
.on::<lsp_ext::ViewRecursiveMemoryLayout>(handlers::handle_view_recursive_memory_layout)
.finish();
@@ -788,77 +818,4 @@ impl GlobalState {
.finish();
Ok(())
}
-
- fn update_diagnostics(&mut self) {
- let db = self.analysis_host.raw_database();
- let subscriptions = self
- .mem_docs
- .iter()
- .map(|path| self.vfs.read().0.file_id(path).unwrap())
- .filter(|&file_id| {
- let source_root = db.file_source_root(file_id);
- // Only publish diagnostics for files in the workspace, not from crates.io deps
- // or the sysroot.
- // While theoretically these should never have errors, we have quite a few false
- // positives particularly in the stdlib, and those diagnostics would stay around
- // forever if we emitted them here.
- !db.source_root(source_root).is_library
- })
- .collect::<Vec<_>>();
-
- tracing::trace!("updating notifications for {:?}", subscriptions);
-
- let snapshot = self.snapshot();
-
- // Diagnostics are triggered by the user typing
- // so we run them on a latency sensitive thread.
- self.task_pool.handle.spawn(ThreadIntent::LatencySensitive, move || {
- let _p = profile::span("publish_diagnostics");
- let _ctx = stdx::panic_context::enter("publish_diagnostics".to_owned());
- let diagnostics = subscriptions
- .into_iter()
- .filter_map(|file_id| {
- let line_index = snapshot.file_line_index(file_id).ok()?;
- Some((
- file_id,
- line_index,
- snapshot
- .analysis
- .diagnostics(
- &snapshot.config.diagnostics(),
- ide::AssistResolveStrategy::None,
- file_id,
- )
- .ok()?,
- ))
- })
- .map(|(file_id, line_index, it)| {
- (
- file_id,
- it.into_iter()
- .map(move |d| lsp_types::Diagnostic {
- range: crate::to_proto::range(&line_index, d.range),
- severity: Some(crate::to_proto::diagnostic_severity(d.severity)),
- code: Some(lsp_types::NumberOrString::String(
- d.code.as_str().to_string(),
- )),
- code_description: Some(lsp_types::CodeDescription {
- href: lsp_types::Url::parse(&d.code.url()).unwrap(),
- }),
- source: Some("rust-analyzer".to_string()),
- message: d.message,
- related_information: None,
- tags: if d.unused {
- Some(vec![lsp_types::DiagnosticTag::UNNECESSARY])
- } else {
- None
- },
- data: None,
- })
- .collect::<Vec<_>>(),
- )
- });
- Task::Diagnostics(diagnostics.collect())
- });
- }
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/markdown.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/markdown.rs
deleted file mode 100644
index 58426c66a..000000000
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/markdown.rs
+++ /dev/null
@@ -1,165 +0,0 @@
-//! Transforms markdown
-use ide_db::rust_doc::is_rust_fence;
-
-const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
-
-pub(crate) fn format_docs(src: &str) -> String {
- let mut processed_lines = Vec::new();
- let mut in_code_block = false;
- let mut is_rust = false;
-
- for mut line in src.lines() {
- if in_code_block && is_rust && code_line_ignored_by_rustdoc(line) {
- continue;
- }
-
- if let Some(header) = RUSTDOC_FENCES.into_iter().find_map(|fence| line.strip_prefix(fence))
- {
- in_code_block ^= true;
-
- if in_code_block {
- is_rust = is_rust_fence(header);
-
- if is_rust {
- line = "```rust";
- }
- }
- }
-
- if in_code_block {
- let trimmed = line.trim_start();
- if is_rust && trimmed.starts_with("##") {
- line = &trimmed[1..];
- }
- }
-
- processed_lines.push(line);
- }
- processed_lines.join("\n")
-}
-
-fn code_line_ignored_by_rustdoc(line: &str) -> bool {
- let trimmed = line.trim();
- trimmed == "#" || trimmed.starts_with("# ") || trimmed.starts_with("#\t")
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_format_docs_adds_rust() {
- let comment = "```\nfn some_rust() {}\n```";
- assert_eq!(format_docs(comment), "```rust\nfn some_rust() {}\n```");
- }
-
- #[test]
- fn test_format_docs_handles_plain_text() {
- let comment = "```text\nthis is plain text\n```";
- assert_eq!(format_docs(comment), "```text\nthis is plain text\n```");
- }
-
- #[test]
- fn test_format_docs_handles_non_rust() {
- let comment = "```sh\nsupposedly shell code\n```";
- assert_eq!(format_docs(comment), "```sh\nsupposedly shell code\n```");
- }
-
- #[test]
- fn test_format_docs_handles_rust_alias() {
- let comment = "```ignore\nlet z = 55;\n```";
- assert_eq!(format_docs(comment), "```rust\nlet z = 55;\n```");
- }
-
- #[test]
- fn test_format_docs_handles_complex_code_block_attrs() {
- let comment = "```rust,no_run\nlet z = 55;\n```";
- assert_eq!(format_docs(comment), "```rust\nlet z = 55;\n```");
- }
-
- #[test]
- fn test_format_docs_handles_error_codes() {
- let comment = "```compile_fail,E0641\nlet b = 0 as *const _;\n```";
- assert_eq!(format_docs(comment), "```rust\nlet b = 0 as *const _;\n```");
- }
-
- #[test]
- fn test_format_docs_skips_comments_in_rust_block() {
- let comment =
- "```rust\n # skip1\n# skip2\n#stay1\nstay2\n#\n #\n # \n #\tskip3\n\t#\t\n```";
- assert_eq!(format_docs(comment), "```rust\n#stay1\nstay2\n```");
- }
-
- #[test]
- fn test_format_docs_does_not_skip_lines_if_plain_text() {
- let comment =
- "```text\n # stay1\n# stay2\n#stay3\nstay4\n#\n #\n # \n #\tstay5\n\t#\t\n```";
- assert_eq!(
- format_docs(comment),
- "```text\n # stay1\n# stay2\n#stay3\nstay4\n#\n #\n # \n #\tstay5\n\t#\t\n```",
- );
- }
-
- #[test]
- fn test_format_docs_keeps_comments_outside_of_rust_block() {
- let comment = " # stay1\n# stay2\n#stay3\nstay4\n#\n #\n # \n #\tstay5\n\t#\t";
- assert_eq!(format_docs(comment), comment);
- }
-
- #[test]
- fn test_format_docs_preserves_newlines() {
- let comment = "this\nis\nmultiline";
- assert_eq!(format_docs(comment), comment);
- }
-
- #[test]
- fn test_code_blocks_in_comments_marked_as_rust() {
- let comment = r#"```rust
-fn main(){}
-```
-Some comment.
-```
-let a = 1;
-```"#;
-
- assert_eq!(
- format_docs(comment),
- "```rust\nfn main(){}\n```\nSome comment.\n```rust\nlet a = 1;\n```"
- );
- }
-
- #[test]
- fn test_code_blocks_in_comments_marked_as_text() {
- let comment = r#"```text
-filler
-text
-```
-Some comment.
-```
-let a = 1;
-```"#;
-
- assert_eq!(
- format_docs(comment),
- "```text\nfiller\ntext\n```\nSome comment.\n```rust\nlet a = 1;\n```"
- );
- }
-
- #[test]
- fn test_format_docs_handles_escape_double_hashes() {
- let comment = r#"```rust
-let s = "foo
-## bar # baz";
-```"#;
-
- assert_eq!(format_docs(comment), "```rust\nlet s = \"foo\n# bar # baz\";\n```");
- }
-
- #[test]
- fn test_format_docs_handles_double_hashes_non_rust() {
- let comment = r#"```markdown
-## A second-level heading
-```"#;
- assert_eq!(format_docs(comment), "```markdown\n## A second-level heading\n```");
- }
-}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index 0a2bb8224..3fae08b82 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -12,6 +12,7 @@
//! correct. Instead, we try to provide a best-effort service. Even if the
//! project is currently loading and we don't have a full project model, we
//! still want to respond to various requests.
+// FIXME: This is a mess that needs some untangling work
use std::{iter, mem};
use flycheck::{FlycheckConfig, FlycheckHandle};
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
index 0bb29e708..d59914298 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -29,7 +29,7 @@ use lsp_types::{
PartialResultParams, Position, Range, RenameFilesParams, TextDocumentItem,
TextDocumentPositionParams, WorkDoneProgressParams,
};
-use rust_analyzer::lsp_ext::{OnEnter, Runnables, RunnablesParams};
+use rust_analyzer::lsp::ext::{OnEnter, Runnables, RunnablesParams};
use serde_json::json;
use test_utils::skip_slow_tests;
@@ -861,6 +861,7 @@ edition = "2021"
bar = {path = "../bar"}
//- /foo/src/main.rs
+#![allow(internal_features)]
#![feature(rustc_attrs, decl_macro)]
use bar::Bar;
@@ -938,7 +939,7 @@ pub fn foo(_input: TokenStream) -> TokenStream {
let res = server.send_request::<HoverRequest>(HoverParams {
text_document_position_params: TextDocumentPositionParams::new(
server.doc_id("foo/src/main.rs"),
- Position::new(11, 9),
+ Position::new(12, 9),
),
work_done_progress_params: Default::default(),
});
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs
index 3c52ef5ef..e49b5768f 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs
@@ -9,7 +9,7 @@ use std::{
use crossbeam_channel::{after, select, Receiver};
use lsp_server::{Connection, Message, Notification, Request};
use lsp_types::{notification::Exit, request::Shutdown, TextDocumentIdentifier, Url};
-use rust_analyzer::{config::Config, lsp_ext, main_loop};
+use rust_analyzer::{config::Config, lsp, main_loop};
use serde::Serialize;
use serde_json::{json, to_string_pretty, Value};
use test_utils::FixtureWithProjectMeta;
@@ -260,9 +260,9 @@ impl Server {
Message::Notification(n) if n.method == "experimental/serverStatus" => {
let status = n
.clone()
- .extract::<lsp_ext::ServerStatusParams>("experimental/serverStatus")
+ .extract::<lsp::ext::ServerStatusParams>("experimental/serverStatus")
.unwrap();
- if status.health != lsp_ext::Health::Ok {
+ if status.health != lsp::ext::Health::Ok {
panic!("server errored/warned while loading workspace: {:?}", status.message);
}
status.quiescent
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs
index f230cba2b..8b5c92c66 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/tidy.rs
@@ -35,7 +35,7 @@ fn check_lsp_extensions_docs() {
let expected_hash = {
let lsp_ext_rs = sh
- .read_file(sourcegen::project_root().join("crates/rust-analyzer/src/lsp_ext.rs"))
+ .read_file(sourcegen::project_root().join("crates/rust-analyzer/src/lsp/ext.rs"))
.unwrap();
stable_hash(lsp_ext_rs.as_str())
};
@@ -45,7 +45,7 @@ fn check_lsp_extensions_docs() {
sh.read_file(sourcegen::project_root().join("docs/dev/lsp-extensions.md")).unwrap();
let text = lsp_extensions_md
.lines()
- .find_map(|line| line.strip_prefix("lsp_ext.rs hash:"))
+ .find_map(|line| line.strip_prefix("lsp/ext.rs hash:"))
.unwrap()
.trim();
u64::from_str_radix(text, 16).unwrap()
@@ -54,7 +54,7 @@ fn check_lsp_extensions_docs() {
if actual_hash != expected_hash {
panic!(
"
-lsp_ext.rs was changed without touching lsp-extensions.md.
+lsp/ext.rs was changed without touching lsp-extensions.md.
Expected hash: {expected_hash:x}
Actual hash: {actual_hash:x}
@@ -158,7 +158,7 @@ Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT
Apache-2.0/MIT
BSD-3-Clause
BlueOak-1.0.0 OR MIT OR Apache-2.0
-CC0-1.0 OR Artistic-2.0
+CC0-1.0
ISC
MIT
MIT / Apache-2.0
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 138ddd208..3603560d3 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -296,7 +296,7 @@ TypeParam =
ConstParam =
Attr* 'const' Name ':' Type
- ('=' default_val:Expr)?
+ ('=' default_val:ConstArg)?
LifetimeParam =
Attr* Lifetime (':' TypeBoundList?)?
@@ -340,10 +340,10 @@ ExprStmt =
Expr =
ArrayExpr
+| AsmExpr
| AwaitExpr
| BinExpr
| BlockExpr
-| BoxExpr
| BreakExpr
| CallExpr
| CastExpr
@@ -351,6 +351,7 @@ Expr =
| ContinueExpr
| FieldExpr
| ForExpr
+| FormatArgsExpr
| IfExpr
| IndexExpr
| Literal
@@ -358,6 +359,7 @@ Expr =
| MacroExpr
| MatchExpr
| MethodCallExpr
+| OffsetOfExpr
| ParenExpr
| PathExpr
| PrefixExpr
@@ -373,6 +375,21 @@ Expr =
| LetExpr
| UnderscoreExpr
+OffsetOfExpr =
+ Attr* 'builtin' '#' 'offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')'
+
+AsmExpr =
+ Attr* 'builtin' '#' 'asm' '(' Expr ')'
+
+FormatArgsExpr =
+ Attr* 'builtin' '#' 'format_args' '('
+ template:Expr
+ (',' args:(FormatArgsArg (',' FormatArgsArg)* ','?)? )?
+ ')'
+
+FormatArgsArg =
+ (Name '=')? Expr
+
MacroExpr =
MacroCall
@@ -526,9 +543,6 @@ UnderscoreExpr =
AwaitExpr =
Attr* Expr '.' 'await'
-BoxExpr =
- Attr* 'box' Expr
-
//*************************//
// Types //
//*************************//
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index 0b27faa53..7ba0d4dc6 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -709,7 +709,7 @@ impl ConstParam {
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
- pub fn default_val(&self) -> Option<Expr> { support::child(&self.syntax) }
+ pub fn default_val(&self) -> Option<ConstArg> { support::child(&self.syntax) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -805,6 +805,20 @@ impl ArrayExpr {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmExpr {
+ pub(crate) syntax: SyntaxNode,
+}
+impl ast::HasAttrs for AsmExpr {}
+impl AsmExpr {
+ pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
+ pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
+ pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) }
+ pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+ pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+ pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AwaitExpr {
pub(crate) syntax: SyntaxNode,
}
@@ -823,16 +837,6 @@ impl ast::HasAttrs for BinExpr {}
impl BinExpr {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BoxExpr {
- pub(crate) syntax: SyntaxNode,
-}
-impl ast::HasAttrs for BoxExpr {}
-impl BoxExpr {
- pub fn box_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![box]) }
- pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct BreakExpr {
pub(crate) syntax: SyntaxNode,
}
@@ -916,6 +920,24 @@ impl ForExpr {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct FormatArgsExpr {
+ pub(crate) syntax: SyntaxNode,
+}
+impl ast::HasAttrs for FormatArgsExpr {}
+impl FormatArgsExpr {
+ pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
+ pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
+ pub fn format_args_token(&self) -> Option<SyntaxToken> {
+ support::token(&self.syntax, T![format_args])
+ }
+ pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+ pub fn template(&self) -> Option<Expr> { support::child(&self.syntax) }
+ pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
+ pub fn args(&self) -> AstChildren<FormatArgsArg> { support::children(&self.syntax) }
+ pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct IfExpr {
pub(crate) syntax: SyntaxNode,
}
@@ -985,6 +1007,24 @@ impl MethodCallExpr {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct OffsetOfExpr {
+ pub(crate) syntax: SyntaxNode,
+}
+impl ast::HasAttrs for OffsetOfExpr {}
+impl OffsetOfExpr {
+ pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
+ pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
+ pub fn offset_of_token(&self) -> Option<SyntaxToken> {
+ support::token(&self.syntax, T![offset_of])
+ }
+ pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+ pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
+ pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
+ pub fn fields(&self) -> AstChildren<NameRef> { support::children(&self.syntax) }
+ pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ParenExpr {
pub(crate) syntax: SyntaxNode,
}
@@ -1127,6 +1167,16 @@ impl UnderscoreExpr {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct FormatArgsArg {
+ pub(crate) syntax: SyntaxNode,
+}
+impl ast::HasName for FormatArgsArg {}
+impl FormatArgsArg {
+ pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+ pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StmtList {
pub(crate) syntax: SyntaxNode,
}
@@ -1555,10 +1605,10 @@ pub enum Type {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Expr {
ArrayExpr(ArrayExpr),
+ AsmExpr(AsmExpr),
AwaitExpr(AwaitExpr),
BinExpr(BinExpr),
BlockExpr(BlockExpr),
- BoxExpr(BoxExpr),
BreakExpr(BreakExpr),
CallExpr(CallExpr),
CastExpr(CastExpr),
@@ -1566,6 +1616,7 @@ pub enum Expr {
ContinueExpr(ContinueExpr),
FieldExpr(FieldExpr),
ForExpr(ForExpr),
+ FormatArgsExpr(FormatArgsExpr),
IfExpr(IfExpr),
IndexExpr(IndexExpr),
Literal(Literal),
@@ -1573,6 +1624,7 @@ pub enum Expr {
MacroExpr(MacroExpr),
MatchExpr(MatchExpr),
MethodCallExpr(MethodCallExpr),
+ OffsetOfExpr(OffsetOfExpr),
ParenExpr(ParenExpr),
PathExpr(PathExpr),
PrefixExpr(PrefixExpr),
@@ -2453,8 +2505,8 @@ impl AstNode for ArrayExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
-impl AstNode for AwaitExpr {
- fn can_cast(kind: SyntaxKind) -> bool { kind == AWAIT_EXPR }
+impl AstNode for AsmExpr {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_EXPR }
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
@@ -2464,8 +2516,8 @@ impl AstNode for AwaitExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
-impl AstNode for BinExpr {
- fn can_cast(kind: SyntaxKind) -> bool { kind == BIN_EXPR }
+impl AstNode for AwaitExpr {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == AWAIT_EXPR }
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
@@ -2475,8 +2527,8 @@ impl AstNode for BinExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
-impl AstNode for BoxExpr {
- fn can_cast(kind: SyntaxKind) -> bool { kind == BOX_EXPR }
+impl AstNode for BinExpr {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == BIN_EXPR }
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
@@ -2563,6 +2615,17 @@ impl AstNode for ForExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for FormatArgsExpr {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_EXPR }
+ fn cast(syntax: SyntaxNode) -> Option<Self> {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
impl AstNode for IfExpr {
fn can_cast(kind: SyntaxKind) -> bool { kind == IF_EXPR }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2640,6 +2703,17 @@ impl AstNode for MethodCallExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for OffsetOfExpr {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == OFFSET_OF_EXPR }
+ fn cast(syntax: SyntaxNode) -> Option<Self> {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
impl AstNode for ParenExpr {
fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_EXPR }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2794,6 +2868,17 @@ impl AstNode for UnderscoreExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for FormatArgsArg {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_ARG }
+ fn cast(syntax: SyntaxNode) -> Option<Self> {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
impl AstNode for StmtList {
fn can_cast(kind: SyntaxKind) -> bool { kind == STMT_LIST }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3373,6 +3458,9 @@ impl AstNode for Type {
impl From<ArrayExpr> for Expr {
fn from(node: ArrayExpr) -> Expr { Expr::ArrayExpr(node) }
}
+impl From<AsmExpr> for Expr {
+ fn from(node: AsmExpr) -> Expr { Expr::AsmExpr(node) }
+}
impl From<AwaitExpr> for Expr {
fn from(node: AwaitExpr) -> Expr { Expr::AwaitExpr(node) }
}
@@ -3382,9 +3470,6 @@ impl From<BinExpr> for Expr {
impl From<BlockExpr> for Expr {
fn from(node: BlockExpr) -> Expr { Expr::BlockExpr(node) }
}
-impl From<BoxExpr> for Expr {
- fn from(node: BoxExpr) -> Expr { Expr::BoxExpr(node) }
-}
impl From<BreakExpr> for Expr {
fn from(node: BreakExpr) -> Expr { Expr::BreakExpr(node) }
}
@@ -3406,6 +3491,9 @@ impl From<FieldExpr> for Expr {
impl From<ForExpr> for Expr {
fn from(node: ForExpr) -> Expr { Expr::ForExpr(node) }
}
+impl From<FormatArgsExpr> for Expr {
+ fn from(node: FormatArgsExpr) -> Expr { Expr::FormatArgsExpr(node) }
+}
impl From<IfExpr> for Expr {
fn from(node: IfExpr) -> Expr { Expr::IfExpr(node) }
}
@@ -3427,6 +3515,9 @@ impl From<MatchExpr> for Expr {
impl From<MethodCallExpr> for Expr {
fn from(node: MethodCallExpr) -> Expr { Expr::MethodCallExpr(node) }
}
+impl From<OffsetOfExpr> for Expr {
+ fn from(node: OffsetOfExpr) -> Expr { Expr::OffsetOfExpr(node) }
+}
impl From<ParenExpr> for Expr {
fn from(node: ParenExpr) -> Expr { Expr::ParenExpr(node) }
}
@@ -3474,10 +3565,10 @@ impl AstNode for Expr {
matches!(
kind,
ARRAY_EXPR
+ | ASM_EXPR
| AWAIT_EXPR
| BIN_EXPR
| BLOCK_EXPR
- | BOX_EXPR
| BREAK_EXPR
| CALL_EXPR
| CAST_EXPR
@@ -3485,6 +3576,7 @@ impl AstNode for Expr {
| CONTINUE_EXPR
| FIELD_EXPR
| FOR_EXPR
+ | FORMAT_ARGS_EXPR
| IF_EXPR
| INDEX_EXPR
| LITERAL
@@ -3492,6 +3584,7 @@ impl AstNode for Expr {
| MACRO_EXPR
| MATCH_EXPR
| METHOD_CALL_EXPR
+ | OFFSET_OF_EXPR
| PAREN_EXPR
| PATH_EXPR
| PREFIX_EXPR
@@ -3511,10 +3604,10 @@ impl AstNode for Expr {
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
ARRAY_EXPR => Expr::ArrayExpr(ArrayExpr { syntax }),
+ ASM_EXPR => Expr::AsmExpr(AsmExpr { syntax }),
AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
BIN_EXPR => Expr::BinExpr(BinExpr { syntax }),
BLOCK_EXPR => Expr::BlockExpr(BlockExpr { syntax }),
- BOX_EXPR => Expr::BoxExpr(BoxExpr { syntax }),
BREAK_EXPR => Expr::BreakExpr(BreakExpr { syntax }),
CALL_EXPR => Expr::CallExpr(CallExpr { syntax }),
CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
@@ -3522,6 +3615,7 @@ impl AstNode for Expr {
CONTINUE_EXPR => Expr::ContinueExpr(ContinueExpr { syntax }),
FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
FOR_EXPR => Expr::ForExpr(ForExpr { syntax }),
+ FORMAT_ARGS_EXPR => Expr::FormatArgsExpr(FormatArgsExpr { syntax }),
IF_EXPR => Expr::IfExpr(IfExpr { syntax }),
INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }),
LITERAL => Expr::Literal(Literal { syntax }),
@@ -3529,6 +3623,7 @@ impl AstNode for Expr {
MACRO_EXPR => Expr::MacroExpr(MacroExpr { syntax }),
MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }),
METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }),
+ OFFSET_OF_EXPR => Expr::OffsetOfExpr(OffsetOfExpr { syntax }),
PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }),
PATH_EXPR => Expr::PathExpr(PathExpr { syntax }),
PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
@@ -3550,10 +3645,10 @@ impl AstNode for Expr {
fn syntax(&self) -> &SyntaxNode {
match self {
Expr::ArrayExpr(it) => &it.syntax,
+ Expr::AsmExpr(it) => &it.syntax,
Expr::AwaitExpr(it) => &it.syntax,
Expr::BinExpr(it) => &it.syntax,
Expr::BlockExpr(it) => &it.syntax,
- Expr::BoxExpr(it) => &it.syntax,
Expr::BreakExpr(it) => &it.syntax,
Expr::CallExpr(it) => &it.syntax,
Expr::CastExpr(it) => &it.syntax,
@@ -3561,6 +3656,7 @@ impl AstNode for Expr {
Expr::ContinueExpr(it) => &it.syntax,
Expr::FieldExpr(it) => &it.syntax,
Expr::ForExpr(it) => &it.syntax,
+ Expr::FormatArgsExpr(it) => &it.syntax,
Expr::IfExpr(it) => &it.syntax,
Expr::IndexExpr(it) => &it.syntax,
Expr::Literal(it) => &it.syntax,
@@ -3568,6 +3664,7 @@ impl AstNode for Expr {
Expr::MacroExpr(it) => &it.syntax,
Expr::MatchExpr(it) => &it.syntax,
Expr::MethodCallExpr(it) => &it.syntax,
+ Expr::OffsetOfExpr(it) => &it.syntax,
Expr::ParenExpr(it) => &it.syntax,
Expr::PathExpr(it) => &it.syntax,
Expr::PrefixExpr(it) => &it.syntax,
@@ -4028,9 +4125,9 @@ impl AstNode for AnyHasAttrs {
| TYPE_PARAM
| LET_STMT
| ARRAY_EXPR
+ | ASM_EXPR
| AWAIT_EXPR
| BIN_EXPR
- | BOX_EXPR
| BREAK_EXPR
| CALL_EXPR
| CAST_EXPR
@@ -4038,12 +4135,14 @@ impl AstNode for AnyHasAttrs {
| CONTINUE_EXPR
| FIELD_EXPR
| FOR_EXPR
+ | FORMAT_ARGS_EXPR
| IF_EXPR
| INDEX_EXPR
| LITERAL
| LOOP_EXPR
| MATCH_EXPR
| METHOD_CALL_EXPR
+ | OFFSET_OF_EXPR
| PAREN_EXPR
| PATH_EXPR
| PREFIX_EXPR
@@ -4179,6 +4278,7 @@ impl AstNode for AnyHasName {
| VARIANT
| CONST_PARAM
| TYPE_PARAM
+ | FORMAT_ARGS_ARG
| IDENT_PAT
)
}
@@ -4620,17 +4720,17 @@ impl std::fmt::Display for ArrayExpr {
std::fmt::Display::fmt(self.syntax(), f)
}
}
-impl std::fmt::Display for AwaitExpr {
+impl std::fmt::Display for AsmExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
}
-impl std::fmt::Display for BinExpr {
+impl std::fmt::Display for AwaitExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
}
-impl std::fmt::Display for BoxExpr {
+impl std::fmt::Display for BinExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
@@ -4670,6 +4770,11 @@ impl std::fmt::Display for ForExpr {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for FormatArgsExpr {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for IfExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
@@ -4705,6 +4810,11 @@ impl std::fmt::Display for MethodCallExpr {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for OffsetOfExpr {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for ParenExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
@@ -4775,6 +4885,11 @@ impl std::fmt::Display for UnderscoreExpr {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for FormatArgsArg {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for StmtList {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 4c6db0ef0..17e311c0c 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -503,11 +503,16 @@ pub fn hacky_block_expr(
pub fn expr_unit() -> ast::Expr {
expr_from_text("()")
}
+
pub fn expr_literal(text: &str) -> ast::Literal {
assert_eq!(text.trim(), text);
ast_from_text(&format!("fn f() {{ let _ = {text}; }}"))
}
+pub fn expr_const_value(text: &str) -> ast::ConstArg {
+ ast_from_text(&format!("trait Foo<const N: usize = {text}> {{}}"))
+}
+
pub fn expr_empty_block() -> ast::Expr {
expr_from_text("{}")
}
@@ -1100,7 +1105,7 @@ pub mod tokens {
pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| {
SourceFile::parse(
- "const C: <()>::Item = (1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p)\n;\n\n",
+ "const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p)\n;\n\n",
)
});
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
index 3308077da..691d0c618 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
@@ -61,6 +61,14 @@ impl ast::BlockExpr {
pub fn tail_expr(&self) -> Option<ast::Expr> {
self.stmt_list()?.tail_expr()
}
+ /// Block expressions accept outer and inner attributes, but only when they are the outer
+ /// expression of an expression statement or the final expression of another block expression.
+ pub fn may_carry_attributes(&self) -> bool {
+ matches!(
+ self.syntax().parent().map(|it| it.kind()),
+ Some(SyntaxKind::BLOCK_EXPR | SyntaxKind::EXPR_STMT)
+ )
+ }
}
#[derive(Debug, PartialEq, Eq, Clone)]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
index 4ec388914..8e04ab8be 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
@@ -130,7 +130,8 @@ impl Expr {
//
ContinueExpr(_) => (0, 0),
- ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | BreakExpr(_) => (0, 1),
+ ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | BreakExpr(_)
+ | OffsetOfExpr(_) | FormatArgsExpr(_) | AsmExpr(_) => (0, 1),
RangeExpr(_) => (5, 5),
@@ -160,7 +161,7 @@ impl Expr {
CastExpr(_) => (25, 26),
- BoxExpr(_) | RefExpr(_) | LetExpr(_) | PrefixExpr(_) => (0, 27),
+ RefExpr(_) | LetExpr(_) | PrefixExpr(_) => (0, 27),
AwaitExpr(_) | CallExpr(_) | MethodCallExpr(_) | IndexExpr(_) | TryExpr(_)
| MacroExpr(_) => (29, 0),
@@ -202,7 +203,6 @@ impl Expr {
let rhs = match self {
RefExpr(e) => e.expr(),
BinExpr(e) => e.rhs(),
- BoxExpr(e) => e.expr(),
BreakExpr(e) => e.expr(),
LetExpr(e) => e.expr(),
RangeExpr(e) => e.end(),
@@ -279,7 +279,6 @@ impl Expr {
CastExpr(e) => e.as_token(),
FieldExpr(e) => e.dot_token(),
AwaitExpr(e) => e.dot_token(),
- BoxExpr(e) => e.box_token(),
BreakExpr(e) => e.break_token(),
CallExpr(e) => e.arg_list().and_then(|args| args.l_paren_token()),
ClosureExpr(e) => e.param_list().and_then(|params| params.l_paren_token()),
@@ -293,7 +292,9 @@ impl Expr {
YieldExpr(e) => e.yield_token(),
YeetExpr(e) => e.do_token(),
LetExpr(e) => e.let_token(),
-
+ OffsetOfExpr(e) => e.builtin_token(),
+ FormatArgsExpr(e) => e.builtin_token(),
+ AsmExpr(e) => e.builtin_token(),
ArrayExpr(_) | TupleExpr(_) | Literal(_) | PathExpr(_) | ParenExpr(_)
| IfExpr(_) | WhileExpr(_) | ForExpr(_) | LoopExpr(_) | MatchExpr(_)
| BlockExpr(_) | RecordExpr(_) | UnderscoreExpr(_) | MacroExpr(_) => None,
@@ -310,12 +311,12 @@ impl Expr {
ArrayExpr(_) | AwaitExpr(_) | BlockExpr(_) | CallExpr(_) | CastExpr(_)
| ClosureExpr(_) | FieldExpr(_) | IndexExpr(_) | Literal(_) | LoopExpr(_)
| MacroExpr(_) | MethodCallExpr(_) | ParenExpr(_) | PathExpr(_) | RecordExpr(_)
- | TryExpr(_) | TupleExpr(_) | UnderscoreExpr(_) => false,
+ | TryExpr(_) | TupleExpr(_) | UnderscoreExpr(_) | OffsetOfExpr(_)
+ | FormatArgsExpr(_) | AsmExpr(_) => false,
// For BinExpr and RangeExpr this is technically wrong -- the child can be on the left...
- BinExpr(_) | RangeExpr(_) | BoxExpr(_) | BreakExpr(_) | ContinueExpr(_)
- | PrefixExpr(_) | RefExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_)
- | LetExpr(_) => self
+ BinExpr(_) | RangeExpr(_) | BreakExpr(_) | ContinueExpr(_) | PrefixExpr(_)
+ | RefExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | LetExpr(_) => self
.syntax()
.parent()
.and_then(Expr::cast)
diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
index 4cd668a0c..27c8a13e5 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
@@ -195,11 +195,16 @@ impl ast::TokenTree {
// Tag the token as joint if it is float with a fractional part
// we use this jointness to inform the parser about what token split
// event to emit when we encounter a float literal in a field access
- if kind == SyntaxKind::FLOAT_NUMBER && !t.text().ends_with('.') {
- parser_input.was_joint();
+ if kind == SyntaxKind::FLOAT_NUMBER {
+ if !t.text().ends_with('.') {
+ parser_input.was_joint();
+ } else {
+ was_joint = false;
+ }
+ } else {
+ was_joint = true;
}
}
- was_joint = true;
}
}
@@ -250,6 +255,7 @@ impl ast::TokenTree {
if has_pseudo_dot {
assert!(right.is_empty(), "{left}.{right}");
} else {
+ assert!(!right.is_empty(), "{left}.{right}");
builder.start_node(SyntaxKind::NAME_REF);
builder.token(SyntaxKind::INT_NUMBER, right);
builder.finish_node();
diff --git a/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs b/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs
index e4db33f1c..341bda892 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/tests/ast_src.rs
@@ -70,7 +70,19 @@ pub(crate) const KINDS_SRC: KindsSrc<'_> = KindsSrc {
"match", "mod", "move", "mut", "pub", "ref", "return", "self", "Self", "static", "struct",
"super", "trait", "true", "try", "type", "unsafe", "use", "where", "while", "yield",
],
- contextual_keywords: &["auto", "default", "existential", "union", "raw", "macro_rules", "yeet"],
+ contextual_keywords: &[
+ "auto",
+ "builtin",
+ "default",
+ "existential",
+ "union",
+ "raw",
+ "macro_rules",
+ "yeet",
+ "offset_of",
+ "asm",
+ "format_args",
+ ],
literals: &["INT_NUMBER", "FLOAT_NUMBER", "CHAR", "BYTE", "STRING", "BYTE_STRING", "C_STRING"],
tokens: &["ERROR", "IDENT", "WHITESPACE", "LIFETIME_IDENT", "COMMENT", "SHEBANG"],
nodes: &[
@@ -154,7 +166,10 @@ pub(crate) const KINDS_SRC: KindsSrc<'_> = KindsSrc {
"RECORD_EXPR",
"RECORD_EXPR_FIELD_LIST",
"RECORD_EXPR_FIELD",
- "BOX_EXPR",
+ "OFFSET_OF_EXPR",
+ "ASM_EXPR",
+ "FORMAT_ARGS_EXPR",
+ "FORMAT_ARGS_ARG",
// postfix
"CALL_EXPR",
"INDEX_EXPR",
diff --git a/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs b/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs
index c49c5fa10..56227fce9 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs
@@ -623,7 +623,7 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
}
fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, rule: &Rule) {
- if lower_comma_list(acc, grammar, label, rule) {
+ if lower_seperated_list(acc, grammar, label, rule) {
return;
}
@@ -689,7 +689,7 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, r
}
// (T (',' T)* ','?)
-fn lower_comma_list(
+fn lower_seperated_list(
acc: &mut Vec<Field>,
grammar: &Grammar,
label: Option<&String>,
@@ -699,19 +699,23 @@ fn lower_comma_list(
Rule::Seq(it) => it,
_ => return false,
};
- let (node, repeat, trailing_comma) = match rule.as_slice() {
- [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_comma)] => {
- (node, repeat, trailing_comma)
+ let (node, repeat, trailing_sep) = match rule.as_slice() {
+ [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_sep)] => {
+ (node, repeat, Some(trailing_sep))
}
+ [Rule::Node(node), Rule::Rep(repeat)] => (node, repeat, None),
_ => return false,
};
let repeat = match &**repeat {
Rule::Seq(it) => it,
_ => return false,
};
- match repeat.as_slice() {
- [comma, Rule::Node(n)] if comma == &**trailing_comma && n == node => (),
- _ => return false,
+ if !matches!(
+ repeat.as_slice(),
+ [comma, Rule::Node(n)]
+ if trailing_sep.map_or(true, |it| comma == &**it) && n == node
+ ) {
+ return false;
}
let ty = grammar[*node].name.clone();
let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
index 75e7a3fec..3f8b5a089 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
@@ -313,7 +313,7 @@ impl FixtureWithProjectMeta {
}
impl MiniCore {
- const RAW_SOURCE: &str = include_str!("./minicore.rs");
+ const RAW_SOURCE: &'static str = include_str!("./minicore.rs");
fn has_flag(&self, flag: &str) -> bool {
self.activated_flags.iter().any(|it| it == flag)
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
index c765f4244..573f56b00 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
@@ -899,32 +899,90 @@ pub mod fmt {
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
}
- extern "C" {
- type Opaque;
- }
+ mod rt {
- #[lang = "format_argument"]
- pub struct Argument<'a> {
- value: &'a Opaque,
- formatter: fn(&Opaque, &mut Formatter<'_>) -> Result,
- }
+ extern "C" {
+ type Opaque;
+ }
+
+ #[lang = "format_argument"]
+ pub struct Argument<'a> {
+ value: &'a Opaque,
+ formatter: fn(&Opaque, &mut Formatter<'_>) -> Result,
+ }
+
+ impl<'a> Argument<'a> {
+ pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'b> {
+ use crate::mem::transmute;
+ unsafe { Argument { formatter: transmute(f), value: transmute(x) } }
+ }
+ }
+
+ #[lang = "format_alignment"]
+ pub enum Alignment {
+ Left,
+ Right,
+ Center,
+ Unknown,
+ }
+
+ #[lang = "format_count"]
+ pub enum Count {
+ Is(usize),
+ Param(usize),
+ Implied,
+ }
+
+ #[lang = "format_placeholder"]
+ pub struct Placeholder {
+ pub position: usize,
+ pub fill: char,
+ pub align: Alignment,
+ pub flags: u32,
+ pub precision: Count,
+ pub width: Count,
+ }
+
+ impl Placeholder {
+ pub const fn new(
+ position: usize,
+ fill: char,
+ align: Alignment,
+ flags: u32,
+ precision: Count,
+ width: Count,
+ ) -> Self;
+ }
+
+ #[lang = "format_unsafe_arg"]
+ pub struct UnsafeArg {
+ _private: (),
+ }
- impl<'a> Argument<'a> {
- pub fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'b> {
- use crate::mem::transmute;
- unsafe { Argument { formatter: transmute(f), value: transmute(x) } }
+ impl UnsafeArg {
+ pub unsafe fn new() -> Self;
}
}
#[lang = "format_arguments"]
pub struct Arguments<'a> {
pieces: &'a [&'static str],
- args: &'a [Argument<'a>],
+ fmt: Option<&'a [rt::Placeholder]>,
+ args: &'a [rt::Argument<'a>],
}
impl<'a> Arguments<'a> {
pub const fn new_v1(pieces: &'a [&'static str], args: &'a [Argument<'a>]) -> Arguments<'a> {
- Arguments { pieces, args }
+ Arguments { pieces, fmt: None, args }
+ }
+
+ pub fn new_v1_formatted(
+ pieces: &'a [&'static str],
+ args: &'a [rt::Argument<'a>],
+ fmt: &'a [rt::Placeholder],
+ _unsafe_arg: rt::UnsafeArg,
+ ) -> Arguments<'a> {
+ Arguments { pieces, fmt: Some(fmt), args }
}
}
@@ -1294,8 +1352,6 @@ mod macros {
/* compiler built-in */
};
}
-
- pub(crate) use panic;
// endregion:panic
// region:fmt
@@ -1306,7 +1362,20 @@ mod macros {
($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
}
- pub(crate) use const_format_args;
+ #[macro_export]
+ #[rustc_builtin_macro]
+ macro_rules! format_args {
+ ($fmt:expr) => {{ /* compiler built-in */ }};
+ ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
+ }
+
+ #[macro_export]
+ macro_rules! print {
+ ($($arg:tt)*) => {{
+ $crate::io::_print($crate::format_args!($($arg)*));
+ }};
+ }
+
// endregion:fmt
// region:derive
diff --git a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
index 95c514251..11055f028 100644
--- a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
@@ -16,7 +16,7 @@ tracing = "0.1.35"
walkdir = "2.3.2"
crossbeam-channel = "0.5.5"
# We demand 5.1.0 as any higher version pulls in a new windows-sys dupe
-notify = "=5.1.0"
+notify = "6.1.1"
stdx.workspace = true
vfs.workspace = true
diff --git a/src/tools/rust-analyzer/crates/vfs/src/lib.rs b/src/tools/rust-analyzer/crates/vfs/src/lib.rs
index fe3dfe619..06004adad 100644
--- a/src/tools/rust-analyzer/crates/vfs/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/vfs/src/lib.rs
@@ -184,6 +184,11 @@ impl Vfs {
mem::take(&mut self.changes)
}
+ /// Provides a panic-less way to verify file_id validity.
+ pub fn exists(&self, file_id: FileId) -> bool {
+ self.get(file_id).is_some()
+ }
+
/// Returns the id associated with `path`
///
/// - If `path` does not exists in the `Vfs`, allocate a new id for it, associated with a
diff --git a/src/tools/rust-analyzer/docs/dev/architecture.md b/src/tools/rust-analyzer/docs/dev/architecture.md
index 895de5798..b7d585caf 100644
--- a/src/tools/rust-analyzer/docs/dev/architecture.md
+++ b/src/tools/rust-analyzer/docs/dev/architecture.md
@@ -268,7 +268,7 @@ They are independent from the rest of the code.
And it also handles the actual parsing and expansion of declarative macro (a-la "Macros By Example" or mbe).
For proc macros, the client-server model are used.
-We pass an argument `--proc-macro` to `rust-analyzer` binary to start a separate process (`proc_macro_srv`).
+We start a separate process (`proc_macro_srv`) which loads and runs the proc-macros for us.
And the client (`proc_macro_api`) provides an interface to talk to that server separately.
And then token trees are passed from client, and the server will load the corresponding dynamic library (which built by `cargo`).
diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
index 024acb877..0801e988f 100644
--- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
+++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
<!---
-lsp_ext.rs hash: 149a5be3c5e469d1
+lsp/ext.rs hash: 121482ee911854da
If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue:
@@ -322,7 +322,7 @@ Position[]
```rust
fn main() {
- let x: Vec<()>/*cursor here*/ = vec![]
+ let x: Vec<()>/*cursor here*/ = vec![];
}
```
@@ -362,7 +362,7 @@ interface RunnablesParams {
```typescript
interface Runnable {
label: string;
- /// If this Runnable is associated with a specific function/module, etc, the location of this item
+ /// If this Runnable is associated with a specific function/module, etc., the location of this item
location?: LocationLink;
/// Running things is necessary technology specific, `kind` needs to be advertised via server capabilities,
// the type of `args` is specific to `kind`. The actual running is handled by the client.
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index ea00c9540..71feed0f7 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -161,23 +161,30 @@ List of features to activate. Defaults to
Set to `"all"` to pass `--all-features` to Cargo.
--
+[[rust-analyzer.check.ignore]]rust-analyzer.check.ignore (default: `[]`)::
++
+--
+List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
+
+For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
+--
[[rust-analyzer.check.invocationLocation]]rust-analyzer.check.invocationLocation (default: `"workspace"`)::
+
--
Specifies the working directory for running checks.
- "workspace": run checks for workspaces in the corresponding workspaces' root directories.
- This falls back to "root" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.
+ This falls back to "root" if `#rust-analyzer.cargo.check.invocationStrategy#` is set to `once`.
- "root": run checks in the project's root directory.
-This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
is set.
--
[[rust-analyzer.check.invocationStrategy]]rust-analyzer.check.invocationStrategy (default: `"per_workspace"`)::
+
--
-Specifies the invocation strategy to use when running the checkOnSave command.
+Specifies the invocation strategy to use when running the check command.
If `per_workspace` is set, the command will be executed for each workspace.
If `once` is set, the command will be executed once.
-This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
is set.
--
[[rust-analyzer.check.noDefaultFeatures]]rust-analyzer.check.noDefaultFeatures (default: `null`)::
diff --git a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
index 01707d301..7ec3247e9 100644
--- a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
+++ b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "lsp-server"
-version = "0.7.2"
+version = "0.7.4"
description = "Generic LSP server scaffold."
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server"
diff --git a/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs b/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs
index 49a825e57..e487b9b46 100644
--- a/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs
+++ b/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs
@@ -3,6 +3,8 @@ use std::{
thread,
};
+use log::debug;
+
use crossbeam_channel::{bounded, Receiver, Sender};
use crate::Message;
@@ -23,7 +25,8 @@ pub(crate) fn stdio_transport() -> (Sender<Message>, Receiver<Message>, IoThread
while let Some(msg) = Message::read(&mut stdin)? {
let is_exit = matches!(&msg, Message::Notification(n) if n.is_exit());
- reader_sender.send(msg).unwrap();
+ debug!("sending message {:#?}", msg);
+ reader_sender.send(msg).expect("receiver was dropped, failed to send a message");
if is_exit {
break;
diff --git a/src/tools/rust-analyzer/xtask/src/flags.rs b/src/tools/rust-analyzer/xtask/src/flags.rs
index 7720ad69f..e52cbfca3 100644
--- a/src/tools/rust-analyzer/xtask/src/flags.rs
+++ b/src/tools/rust-analyzer/xtask/src/flags.rs
@@ -114,6 +114,7 @@ pub enum MeasurementType {
AnalyzeRipgrep,
AnalyzeWebRender,
AnalyzeDiesel,
+ AnalyzeHyper,
}
impl FromStr for MeasurementType {
@@ -122,13 +123,26 @@ impl FromStr for MeasurementType {
match s {
"build" => Ok(Self::Build),
"self" => Ok(Self::AnalyzeSelf),
- "ripgrep" => Ok(Self::AnalyzeRipgrep),
- "webrender" => Ok(Self::AnalyzeWebRender),
- "diesel" => Ok(Self::AnalyzeDiesel),
+ "ripgrep-13.0.0" => Ok(Self::AnalyzeRipgrep),
+ "webrender-2022" => Ok(Self::AnalyzeWebRender),
+ "diesel-1.4.8" => Ok(Self::AnalyzeDiesel),
+ "hyper-0.14.18" => Ok(Self::AnalyzeHyper),
_ => Err("Invalid option".to_string()),
}
}
}
+impl AsRef<str> for MeasurementType {
+ fn as_ref(&self) -> &str {
+ match self {
+ Self::Build => "build",
+ Self::AnalyzeSelf => "self",
+ Self::AnalyzeRipgrep => "ripgrep-13.0.0",
+ Self::AnalyzeWebRender => "webrender-2022",
+ Self::AnalyzeDiesel => "diesel-1.4.8",
+ Self::AnalyzeHyper => "hyper-0.14.18",
+ }
+ }
+}
#[derive(Debug)]
pub struct Metrics {
diff --git a/src/tools/rust-analyzer/xtask/src/metrics.rs b/src/tools/rust-analyzer/xtask/src/metrics.rs
index 685374231..59d41d8e4 100644
--- a/src/tools/rust-analyzer/xtask/src/metrics.rs
+++ b/src/tools/rust-analyzer/xtask/src/metrics.rs
@@ -29,46 +29,38 @@ impl flags::Metrics {
let _env = sh.push_env("RA_METRICS", "1");
- let filename = match self.measurement_type {
- Some(ms) => match ms {
- MeasurementType::Build => {
- metrics.measure_build(sh)?;
- "build.json"
- }
- MeasurementType::AnalyzeSelf => {
- metrics.measure_analysis_stats_self(sh)?;
- "self.json"
- }
- MeasurementType::AnalyzeRipgrep => {
- metrics.measure_analysis_stats(sh, "ripgrep")?;
- "ripgrep.json"
- }
- MeasurementType::AnalyzeWebRender => {
- {
- // https://github.com/rust-lang/rust-analyzer/issues/9997
- let _d = sh.push_dir("target/rustc-perf/collector/benchmarks/webrender");
- cmd!(sh, "cargo update -p url --precise 1.6.1").run()?;
+ let name = match &self.measurement_type {
+ Some(ms) => {
+ let name = ms.as_ref();
+ match ms {
+ MeasurementType::Build => {
+ metrics.measure_build(sh)?;
}
- metrics.measure_analysis_stats(sh, "webrender")?;
- "webrender.json"
- }
- MeasurementType::AnalyzeDiesel => {
- metrics.measure_analysis_stats(sh, "diesel/diesel")?;
- "diesel.json"
- }
- },
+ MeasurementType::AnalyzeSelf => {
+ metrics.measure_analysis_stats_self(sh)?;
+ }
+ MeasurementType::AnalyzeRipgrep
+ | MeasurementType::AnalyzeWebRender
+ | MeasurementType::AnalyzeDiesel
+ | MeasurementType::AnalyzeHyper => {
+ metrics.measure_analysis_stats(sh, name)?;
+ }
+ };
+ name
+ }
None => {
metrics.measure_build(sh)?;
metrics.measure_analysis_stats_self(sh)?;
- metrics.measure_analysis_stats(sh, "ripgrep")?;
- metrics.measure_analysis_stats(sh, "webrender")?;
- metrics.measure_analysis_stats(sh, "diesel/diesel")?;
- "all.json"
+ metrics.measure_analysis_stats(sh, MeasurementType::AnalyzeRipgrep.as_ref())?;
+ metrics.measure_analysis_stats(sh, MeasurementType::AnalyzeWebRender.as_ref())?;
+ metrics.measure_analysis_stats(sh, MeasurementType::AnalyzeDiesel.as_ref())?;
+ metrics.measure_analysis_stats(sh, MeasurementType::AnalyzeHyper.as_ref())?;
+ "all"
}
};
let mut file =
- fs::File::options().write(true).create(true).open(format!("target/{}", filename))?;
+ fs::File::options().write(true).create(true).open(format!("target/{}.json", name))?;
writeln!(file, "{}", metrics.json())?;
eprintln!("{metrics:#?}");
Ok(())
@@ -93,7 +85,7 @@ impl Metrics {
self.measure_analysis_stats_path(
sh,
bench,
- &format!("./target/rustc-perf/collector/benchmarks/{bench}"),
+ &format!("./target/rustc-perf/collector/compile-benchmarks/{bench}"),
)
}
fn measure_analysis_stats_path(
@@ -102,10 +94,9 @@ impl Metrics {
name: &str,
path: &str,
) -> anyhow::Result<()> {
+ assert!(Path::new(path).exists(), "unable to find bench in {path}");
eprintln!("\nMeasuring analysis-stats/{name}");
- let output =
- cmd!(sh, "./target/release/rust-analyzer -q analysis-stats --memory-usage {path}")
- .read()?;
+ let output = cmd!(sh, "./target/release/rust-analyzer -q analysis-stats {path}").read()?;
for (metric, value, unit) in parse_metrics(&output) {
self.report(&format!("analysis-stats/{name}/{metric}"), value, unit.into());
}
@@ -147,7 +138,7 @@ impl Metrics {
let host = Host::new(sh)?;
let timestamp = SystemTime::now();
let revision = cmd!(sh, "git rev-parse HEAD").read()?;
- let perf_revision = "c52ee623e231e7690a93be88d943016968c1036b".into();
+ let perf_revision = "a584462e145a0c04760fd9391daefb4f6bd13a99".into();
Ok(Metrics { host, timestamp, revision, perf_revision, metrics: BTreeMap::new() })
}
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 416517d15..c7e6dd361 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -23,7 +23,9 @@ function contentToDiffLine(key, value) {
}
function shouldIgnoreField(fieldName) {
- return fieldName === "query" || fieldName === "correction";
+ return fieldName === "query" || fieldName === "correction" ||
+ fieldName === "proposeCorrectionFrom" ||
+ fieldName === "proposeCorrectionTo";
}
// This function is only called when no matching result was found and therefore will only display
diff --git a/src/tools/rustdoc-themes/main.rs b/src/tools/rustdoc-themes/main.rs
index 7cac985a9..1eba83a80 100644
--- a/src/tools/rustdoc-themes/main.rs
+++ b/src/tools/rustdoc-themes/main.rs
@@ -1,25 +1,38 @@
use std::env::args;
-use std::fs::read_dir;
+use std::fs::{create_dir_all, File};
+use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::Path;
use std::process::{exit, Command};
-const FILES_TO_IGNORE: &[&str] = &["light.css"];
-
-fn get_folders<P: AsRef<Path>>(folder_path: P) -> Vec<String> {
+fn get_themes<P: AsRef<Path>>(style_path: P) -> Vec<String> {
let mut ret = Vec::with_capacity(10);
- for entry in read_dir(folder_path.as_ref()).expect("read_dir failed") {
- let entry = entry.expect("Couldn't unwrap entry");
- let path = entry.path();
+ const BEGIN_THEME_MARKER: &'static str = "/* Begin theme: ";
+ const END_THEME_MARKER: &'static str = "/* End theme: ";
+
+ let timestamp =
+ std::time::SystemTime::UNIX_EPOCH.elapsed().expect("time is after UNIX epoch").as_millis();
- if !path.is_file() {
- continue;
+ let mut in_theme = None;
+ create_dir_all("build/tmp").expect("failed to create temporary test directory");
+ for line in BufReader::new(File::open(style_path).expect("read rustdoc.css failed")).lines() {
+ let line = line.expect("read line from rustdoc.css failed");
+ let line = line.trim();
+ if line.starts_with(BEGIN_THEME_MARKER) {
+ let theme_name = &line[BEGIN_THEME_MARKER.len()..].trim().trim_end_matches("*/").trim();
+ let filename = format!("build/tmp/rustdoc.bootstrap.{timestamp}.{theme_name}.css");
+ in_theme = Some(BufWriter::new(
+ File::create(&filename).expect("failed to create temporary test css file"),
+ ));
+ ret.push(filename);
+ }
+ if let Some(in_theme) = in_theme.as_mut() {
+ in_theme.write_all(line.as_bytes()).expect("write to temporary test css file");
+ in_theme.write_all(b"\n").expect("write to temporary test css file");
}
- let filename = path.file_name().expect("file_name failed");
- if FILES_TO_IGNORE.iter().any(|x| x == &filename) {
- continue;
+ if line.starts_with(END_THEME_MARKER) {
+ in_theme = None;
}
- ret.push(format!("{}", path.display()));
}
ret
}
@@ -32,10 +45,10 @@ fn main() {
exit(1);
}
let rustdoc_bin = &argv[1];
- let themes_folder = &argv[2];
- let themes = get_folders(&themes_folder);
+ let style_path = &argv[2];
+ let themes = get_themes(&style_path);
if themes.is_empty() {
- eprintln!("No theme found in \"{}\"...", themes_folder);
+ eprintln!("No themes found in \"{}\"...", style_path);
exit(1);
}
let arg_name = "--check-theme".to_owned();
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index c3c07f310..03cdddc41 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -664,7 +664,7 @@ struct ControlFlow<'a> {
fn extract_pats_and_cond(expr: &ast::Expr) -> (Option<&ast::Pat>, &ast::Expr) {
match expr.kind {
- ast::ExprKind::Let(ref pat, ref cond, _) => (Some(pat), cond),
+ ast::ExprKind::Let(ref pat, ref cond, _, _) => (Some(pat), cond),
_ => (None, expr),
}
}
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 945e3e42f..3f94bb299 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -1,8 +1,8 @@
use std::path::Path;
use std::sync::atomic::{AtomicBool, Ordering};
-use rustc_data_structures::sync::{Lrc, Send};
-use rustc_errors::emitter::{Emitter, EmitterWriter};
+use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
+use rustc_errors::emitter::{DynEmitter, Emitter, EmitterWriter};
use rustc_errors::translation::Translate;
use rustc_errors::{ColorConfig, Diagnostic, Handler, Level as DiagnosticLevel};
use rustc_session::parse::ParseSess as RawParseSess;
@@ -48,15 +48,15 @@ impl Emitter for SilentEmitter {
fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
}
-fn silent_emitter() -> Box<dyn Emitter + Send> {
+fn silent_emitter() -> Box<DynEmitter> {
Box::new(SilentEmitter {})
}
/// Emit errors against every files expect ones specified in the `ignore_path_set`.
struct SilentOnIgnoredFilesEmitter {
- ignore_path_set: Lrc<IgnorePathSet>,
+ ignore_path_set: IntoDynSyncSend<Lrc<IgnorePathSet>>,
source_map: Lrc<SourceMap>,
- emitter: Box<dyn Emitter + Send>,
+ emitter: Box<DynEmitter>,
has_non_ignorable_parser_errors: bool,
can_reset: Lrc<AtomicBool>,
}
@@ -145,7 +145,7 @@ fn default_handler(
has_non_ignorable_parser_errors: false,
source_map,
emitter,
- ignore_path_set,
+ ignore_path_set: IntoDynSyncSend(ignore_path_set),
can_reset,
}))
}
@@ -268,7 +268,7 @@ impl ParseSess {
let source_file = self.parse_sess.source_map().lookup_char_pos(span.lo()).file;
SnippetProvider::new(
source_file.start_pos,
- source_file.end_pos,
+ source_file.end_position(),
Lrc::clone(source_file.src.as_ref().unwrap()),
)
}
@@ -396,7 +396,7 @@ mod tests {
has_non_ignorable_parser_errors: false,
source_map,
emitter: Box::new(emitter_writer),
- ignore_path_set,
+ ignore_path_set: IntoDynSyncSend(ignore_path_set),
can_reset,
}
}
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 18a08f17b..5e8edd8f8 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -819,6 +819,8 @@ impl Rewrite for ast::Ty {
ast::TyKind::Tup(ref items) => {
rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
}
+ ast::TyKind::AnonStruct(_) => Some(context.snippet(self.span).to_owned()),
+ ast::TyKind::AnonUnion(_) => Some(context.snippet(self.span).to_owned()),
ast::TyKind::Path(ref q_self, ref path) => {
rewrite_path(context, PathContext::Type, q_self, path, shape)
}
diff --git a/src/tools/rustfmt/tests/target/anonymous-types.rs b/src/tools/rustfmt/tests/target/anonymous-types.rs
new file mode 100644
index 000000000..8e08c314e
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/anonymous-types.rs
@@ -0,0 +1,19 @@
+// Test for issue 85480
+// Pretty print anonymous struct and union types
+
+// pp-exact
+// pretty-compare-only
+
+struct Foo {
+ _: union {
+ _: struct {
+ a: u8,
+ b: u16,
+ },
+ c: u32,
+ },
+ d: u64,
+ e: f32,
+}
+
+fn main() {}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 410852b6a..7d3ef4197 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -18,6 +18,7 @@ const LICENSES: &[&str] = &[
"Apache-2.0/MIT",
"ISC",
"MIT / Apache-2.0",
+ "MIT OR Apache-2.0 OR LGPL-2.1-or-later", // r-efi, r-efi-alloc
"MIT OR Apache-2.0 OR Zlib", // tinyvec_macros
"MIT OR Apache-2.0",
"MIT OR Zlib OR Apache-2.0", // miniz_oxide
@@ -57,14 +58,14 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
// tidy-alphabetical-start
("bitmaps", "MPL-2.0+"),
("bytesize", "Apache-2.0"),
+ ("byteyarn", "Apache-2.0"),
("ciborium", "Apache-2.0"),
("ciborium-io", "Apache-2.0"),
("ciborium-ll", "Apache-2.0"),
("dunce", "CC0-1.0 OR MIT-0 OR Apache-2.0"),
+ ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"),
("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"),
("im-rc", "MPL-2.0+"),
- ("imara-diff", "Apache-2.0"),
- ("instant", "BSD-3-Clause"),
("normalize-line-endings", "Apache-2.0"),
("openssl", "Apache-2.0"),
("ryu", "Apache-2.0 OR BSL-1.0"),
@@ -120,7 +121,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"annotate-snippets",
"ar_archive_writer",
"arrayvec",
- "atty",
"autocfg",
"bitflags",
"block-buffer",
@@ -180,7 +180,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"instant",
"intl-memoizer",
"intl_pluralrules",
- "io-lifetimes",
+ "is-terminal",
"itertools",
"itoa",
"jobserver",
@@ -217,6 +217,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"pulldown-cmark",
"punycode",
"quote",
+ "r-efi",
+ "r-efi-alloc",
"rand",
"rand_chacha",
"rand_core",
diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs
index 417ace58c..3e67bac49 100644
--- a/src/tools/tidy/src/error_codes.rs
+++ b/src/tools/tidy/src/error_codes.rs
@@ -354,7 +354,12 @@ fn check_error_codes_used(
for code in error_codes {
if !found_codes.contains(code) && !no_longer_emitted.contains(code) {
- errors.push(format!("Error code `{code}` exists, but is not emitted by the compiler!"))
+ errors.push(format!(
+ "Error code `{code}` exists, but is not emitted by the compiler!\n\
+ Please mark the code as no longer emitted by adding the following note to the top of the `EXXXX.md` file:\n\
+ `#### Note: this error code is no longer emitted by the compiler`\n\
+ Also, do not forget to mark doctests that no longer apply as `ignore (error is no longer emitted)`."
+ ));
}
if found_codes.contains(code) && no_longer_emitted.contains(code) {
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 9b19b8eec..fc69c1432 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -63,7 +63,7 @@ pub mod features;
pub mod fluent_alphabetical;
pub mod mir_opt_tests;
pub mod pal;
-pub mod primitive_docs;
+pub mod rustdoc_css_themes;
pub mod rustdoc_gui_tests;
pub mod style;
pub mod target_specific_tests;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 5fa91715a..80e58ba00 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -104,6 +104,7 @@ fn main() {
check!(ui_tests, &tests_path);
check!(mir_opt_tests, &tests_path, bless);
check!(rustdoc_gui_tests, &tests_path);
+ check!(rustdoc_css_themes, &librustdoc_path);
// Checks that only make sense for the compiler.
check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose);
@@ -111,7 +112,6 @@ fn main() {
// Checks that only make sense for the std libs.
check!(pal, &library_path);
- check!(primitive_docs, &library_path);
// Checks that need to be done for both the compiler and std libraries.
check!(unit_tests, &src_path);
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 3a4d9c53d..5f6b63a67 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -56,6 +56,7 @@ const EXCEPTION_PATHS: &[&str] = &[
"library/std/src/path.rs",
"library/std/src/sys_common", // Should only contain abstractions over platforms
"library/std/src/net/test.rs", // Utility helpers for tests
+ "library/std/src/io/error.rs", // Repr unpacked needed for UEFI
];
pub fn check(path: &Path, bad: &mut bool) {
diff --git a/src/tools/tidy/src/primitive_docs.rs b/src/tools/tidy/src/primitive_docs.rs
deleted file mode 100644
index f3200e0af..000000000
--- a/src/tools/tidy/src/primitive_docs.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//! Tidy check to make sure `library/{std,core}/src/primitive_docs.rs` are the same file. These are
-//! different files so that relative links work properly without having to have `CARGO_PKG_NAME`
-//! set, but conceptually they should always be the same.
-
-use std::path::Path;
-
-pub fn check(library_path: &Path, bad: &mut bool) {
- let std_name = "std/src/primitive_docs.rs";
- let core_name = "core/src/primitive_docs.rs";
- let std_contents = std::fs::read_to_string(library_path.join(std_name))
- .unwrap_or_else(|e| panic!("failed to read library/{std_name}: {e}"));
- let core_contents = std::fs::read_to_string(library_path.join(core_name))
- .unwrap_or_else(|e| panic!("failed to read library/{core_name}: {e}"));
- if std_contents != core_contents {
- tidy_error!(bad, "library/{core_name} and library/{std_name} have different contents");
- }
-}
diff --git a/src/tools/tidy/src/rustdoc_css_themes.rs b/src/tools/tidy/src/rustdoc_css_themes.rs
new file mode 100644
index 000000000..852d6e14e
--- /dev/null
+++ b/src/tools/tidy/src/rustdoc_css_themes.rs
@@ -0,0 +1,99 @@
+//! Tidy check to make sure light and dark themes are synchronized between
+//! JS-controlled rustdoc.css and noscript.css
+
+use std::path::Path;
+
+pub fn check(librustdoc_path: &Path, bad: &mut bool) {
+ let rustdoc_css = "html/static/css/rustdoc.css";
+ let noscript_css = "html/static/css/noscript.css";
+ let rustdoc_css_contents = std::fs::read_to_string(librustdoc_path.join(rustdoc_css))
+ .unwrap_or_else(|e| panic!("failed to read librustdoc/{rustdoc_css}: {e}"));
+ let noscript_css_contents = std::fs::read_to_string(librustdoc_path.join(noscript_css))
+ .unwrap_or_else(|e| panic!("failed to read librustdoc/{noscript_css}: {e}"));
+ compare_themes_from_files(
+ "light",
+ rustdoc_css_contents.lines().enumerate().map(|(i, l)| (i + 1, l.trim())),
+ noscript_css_contents.lines().enumerate().map(|(i, l)| (i + 1, l.trim())),
+ bad,
+ );
+ compare_themes_from_files(
+ "dark",
+ rustdoc_css_contents.lines().enumerate(),
+ noscript_css_contents.lines().enumerate(),
+ bad,
+ );
+}
+
+fn compare_themes_from_files<'a>(
+ name: &str,
+ mut rustdoc_css_lines: impl Iterator<Item = (usize, &'a str)>,
+ mut noscript_css_lines: impl Iterator<Item = (usize, &'a str)>,
+ bad: &mut bool,
+) {
+ let begin_theme_pat = format!("/* Begin theme: {name}");
+ let mut found_theme = None;
+ let mut found_theme_noscript = None;
+ while let Some((rustdoc_css_line_number, rustdoc_css_line)) = rustdoc_css_lines.next() {
+ if !rustdoc_css_line.starts_with(&begin_theme_pat) {
+ continue;
+ }
+ if let Some(found_theme) = found_theme {
+ tidy_error!(
+ bad,
+ "rustdoc.css contains two {name} themes on lines {rustdoc_css_line_number} and {found_theme}",
+ );
+ return;
+ }
+ found_theme = Some(rustdoc_css_line_number);
+ while let Some((noscript_css_line_number, noscript_css_line)) = noscript_css_lines.next() {
+ if !noscript_css_line.starts_with(&begin_theme_pat) {
+ continue;
+ }
+ if let Some(found_theme_noscript) = found_theme_noscript {
+ tidy_error!(
+ bad,
+ "noscript.css contains two {name} themes on lines {noscript_css_line_number} and {found_theme_noscript}",
+ );
+ return;
+ }
+ found_theme_noscript = Some(noscript_css_line_number);
+ compare_themes(name, &mut rustdoc_css_lines, &mut noscript_css_lines, bad);
+ }
+ }
+}
+
+fn compare_themes<'a>(
+ name: &str,
+ rustdoc_css_lines: impl Iterator<Item = (usize, &'a str)>,
+ noscript_css_lines: impl Iterator<Item = (usize, &'a str)>,
+ bad: &mut bool,
+) {
+ let end_theme_pat = format!("/* End theme: {name}");
+ for (
+ (rustdoc_css_line_number, rustdoc_css_line),
+ (noscript_css_line_number, noscript_css_line),
+ ) in rustdoc_css_lines.zip(noscript_css_lines)
+ {
+ if noscript_css_line.starts_with(":root {")
+ && rustdoc_css_line.starts_with(&format!(r#":root[data-theme="{name}"] {{"#))
+ {
+ // selectors are different between rustdoc.css and noscript.css
+ // that's why they both exist: one uses JS, the other uses media queries
+ continue;
+ }
+ if noscript_css_line.starts_with(&end_theme_pat)
+ && rustdoc_css_line.starts_with(&end_theme_pat)
+ {
+ break;
+ }
+ if rustdoc_css_line != noscript_css_line {
+ tidy_error!(
+ bad,
+ "noscript.css:{noscript_css_line_number} and rustdoc.css:{rustdoc_css_line_number} contain copies of {name} theme that are not the same",
+ );
+ eprintln!("- {noscript_css_line}");
+ eprintln!("+ {rustdoc_css_line}");
+ return;
+ }
+ }
+}
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 341492400..2b828e58d 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -10,8 +10,8 @@ use std::path::{Path, PathBuf};
const ENTRY_LIMIT: usize = 900;
// FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1891;
-const ROOT_ENTRY_LIMIT: usize = 866;
+const ISSUES_ENTRY_LIMIT: usize = 1854;
+const ROOT_ENTRY_LIMIT: usize = 865;
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
"rs", // test source files